From adcdd9e6ae42feb9f8bfdb0df25c0d4e0282233e Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Thu, 3 Sep 2026 10:58:42 +0800 Subject: [PATCH 01/18] =?UTF-8?q?layout:=20struct=20=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=20+=20kindexpr=20structref=EF=BC=88#199?= =?UTF-8?q?=EF=BC=8CWIP=20=E8=90=BD=E7=9B=98=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ast: StructDecl/Field(name:kindexpr + 默认值字面量),File/PkgNode 挂 structs, sig_string 反序列化(struct X { f:T=..; … })。 - parser:struct 关键字解析进 pkg 树;kindexpr/kvkind 加 structref 形状。 - code.rs:struct 入库(/lib 下 defstruct?待定);Cargo.toml/描述对齐。 未完成 WIP 防护性提交(layout 侧),未跑全量回归。 --- layout/Cargo.toml | 2 +- layout/src/ast.rs | 53 +++++++++++ layout/src/bin/kvlanglayout.rs | 2 +- layout/src/code.rs | 69 +++++++++++++- layout/src/kindexpr.rs | 31 ++++++- layout/src/kvkind.rs | 21 +++++ layout/src/lib.rs | 2 +- layout/src/parser.rs | 165 ++++++++++++++++++++++++++++++++- 8 files changed, 336 insertions(+), 9 deletions(-) diff --git a/layout/Cargo.toml b/layout/Cargo.toml index 70018221..afe884ac 100644 --- a/layout/Cargo.toml +++ b/layout/Cargo.toml @@ -3,7 +3,7 @@ name = "kvlang-layout" version = "0.1.0" edition = "2021" license = "MIT" -description = "kvlang 编译期(parser/lower/layoutcode),只依赖 kvspace-durable 的 C ABI" +description = "kvlang 语法检查 + 布局工具(parser/lower/layoutcode),只依赖 kvspace-durable 的 C ABI" [lib] name = "kvlanglayout" diff --git a/layout/src/ast.rs b/layout/src/ast.rs index fdcaa317..e5e829a5 100644 --- a/layout/src/ast.rs +++ b/layout/src/ast.rs @@ -180,6 +180,43 @@ impl RwirDecl { } } +// ── struct ─────────────────────────────────────────────────────────── + +#[derive(Clone)] +pub struct Field { + pub name: String, + pub ty: String, // kindexpr(字段类型) + pub default: Option, // 默认值字面量(None = 未给) +} + +#[derive(Clone)] +pub struct StructDecl { + pub comments: Vec, + pub name: String, + pub pkg: String, + pub fields: Vec, +} + +impl StructDecl { + pub fn sig_string(&self) -> String { + let mut sb = format!("struct {} {{", self.name); + for (i, fld) in self.fields.iter().enumerate() { + sb.push_str(if i > 0 { "; " } else { " " }); + sb.push_str(&fld.name); + if !fld.ty.is_empty() { + sb.push(':'); + sb.push_str(&fld.ty); + } + if let Some(d) = &fld.default { + sb.push('='); + sb.push_str(&d.to_string()); + } + } + sb.push_str(" }"); + sb + } +} + // ── Expr ───────────────────────────────────────────────────────────── #[derive(Clone, Copy, PartialEq, Eq)] @@ -608,6 +645,7 @@ impl fmt::Display for ScopeStmt { pub struct File { pub package: String, pub rwir_decls: Vec, + pub structs: Vec, pub funcs: Vec, pub top_level_calls: Vec, pub init_body: Vec, @@ -617,6 +655,7 @@ pub struct File { #[derive(Default)] struct PkgNode { rwirs: Vec, + structs: Vec, funcs: Vec, body: Vec, children: std::collections::BTreeMap, @@ -635,6 +674,17 @@ fn pkg_node<'a>(root: &'a mut PkgNode, pkg: &str) -> &'a mut PkgNode { fn emit_node(sb: &mut String, node: &PkgNode, indent: &str) { let mut items: Vec = Vec::new(); + for d in &node.structs { + let mut s = String::new(); + for c in &d.comments { + s.push_str(indent); + s.push_str(c); + s.push('\n'); + } + s.push_str(indent); + s.push_str(&d.sig_string()); + items.push(s); + } for d in &node.rwirs { let mut s = String::new(); for c in &d.comments { @@ -684,6 +734,9 @@ impl File { /// 格式化为规范 kvlang 源码(重建 lib 分组,保留包名,round-trip 语义等价)。 pub fn format(&self) -> String { let mut root = PkgNode::default(); + for d in &self.structs { + pkg_node(&mut root, &d.pkg).structs.push(d.clone()); + } for d in &self.rwir_decls { pkg_node(&mut root, &d.pkg).rwirs.push(d.clone()); } diff --git a/layout/src/bin/kvlanglayout.rs b/layout/src/bin/kvlanglayout.rs index 03475079..a4134eb2 100644 --- a/layout/src/bin/kvlanglayout.rs +++ b/layout/src/bin/kvlanglayout.rs @@ -1,4 +1,4 @@ -//! 读 .kv 文件,用 Rust layout 编译进 kvspace(默认 redis),并输出入口(ENTRY=...), +//! 读 .kv 文件,用 Rust layout 检查语法并布局进 kvspace(默认 redis),并输出入口(ENTRY=...), //! 供 Go runtime 执行验证。 //! 用法: //! kvlanglayout [dsn] 仅 layout,打印 ENTRY=(默认子命令) diff --git a/layout/src/code.rs b/layout/src/code.rs index 0c2d7647..2393ff41 100644 --- a/layout/src/code.rs +++ b/layout/src/code.rs @@ -1,7 +1,7 @@ -//! layoutcode(对齐 layout/layout.go 的编译期部分):把 AST 写到 /lib/ 下的结构化 KV。 +//! layoutcode(对齐 layout/layout.go):检查 AST 并把结果布局写到 /lib/ 下的结构化 KV。 //! //! 存储约定: -//! /lib/·/[0,0] 编译后签名(kind=rwfunc) +//! /lib/·/[0,0] 布局后签名(kind=rwfunc) //! /lib/·/ 命名参数→slot 指针(kind=char, isptr=1) //! /lib/·/[i,j] 编译后指令(kind=rwir),i 从 1 开始 //! /lib/·/‥labels/ label → irseq @@ -11,7 +11,7 @@ use std::collections::HashMap; -use super::ast::{Func, Instruction, RwirDecl, Stmt}; +use super::ast::{Expr, Func, Instruction, RwirDecl, Stmt, StructDecl}; use super::ffi::Kv; use super::{builtin, ffi, keytree, kvkind, lower, parser}; @@ -39,6 +39,10 @@ pub fn compile(kv: &mut Kv, src: &str) -> Result, String> { let mut any_code = false; let mut inits: Vec = Vec::new(); + for decl in &file.structs { + write_struct_decl(kv, decl); + any_code = true; + } for func in &file.funcs { let pkg = if func.pkg.is_empty() { file.package.clone() @@ -144,7 +148,7 @@ pub fn vet(src: &str) -> Result<(), String> { let _ = lower::lower_func(func); any_code = true; } - if !file.init_body.is_empty() || !file.top_level_calls.is_empty() { + if !file.init_body.is_empty() || !file.top_level_calls.is_empty() || !file.structs.is_empty() { any_code = true; } if !any_code { @@ -431,6 +435,63 @@ pub fn write_func(kv: &mut Kv, pkg: &str, fn_: &mut Func) { } } +/// 写 struct 原型到 /lib/:基节点(kind=struct) + memindex(/lib/Name·) + 各字段默认值。 +/// 运行时 struct·new 以此为原型 cpdir 克隆,故字段默认值即实例初值。 +pub fn write_struct_decl(kv: &mut Kv, decl: &StructDecl) { + let mut name = decl.name.clone(); + if !decl.pkg.is_empty() { + name = format!("{}{}{name}", decl.pkg, keytree::MEMBER_SEP); + } + let base = keytree::rwir(&name); + let _ = kv.del_tree(&base); + let fnames: Vec = decl.fields.iter().map(|f| f.name.clone()).collect(); + let ftypes: Vec<(String, String)> = decl + .fields + .iter() + .map(|f| (f.name.clone(), f.ty.clone())) + .collect(); + let mut pairs: Vec<(String, Vec)> = Vec::new(); + pairs.push((base.clone(), kvkind::new_struct(&ftypes))); + pairs.push((keytree::member(&base, ""), kvkind::new_memindex(&fnames))); + for fld in &decl.fields { + pairs.push(( + keytree::member(&base, &fld.name), + field_default(&fld.ty, fld.default.as_ref()), + )); + } + let _ = kv.set(&pairs); +} + +/// 字段默认值 XValue:head kind = 字段类型,body = 默认字面量(未给则零值)。 +/// 标量+char 直接编码;带 dims / structref 仅记录类型(空 body),嵌套 struct 待定。 +fn field_default(ty: &str, default: Option<&Expr>) -> Vec { + let (_, dims, base) = kvkind::parse_kindexpr(ty); + let s = default.map(|e| e.val.clone()).unwrap_or_default(); + if base.starts_with("char/") { + return ffi::new_char(&base, &s); + } + if !dims.is_empty() { + return ffi::tlv_encode(&base, &[], dims.iter().product()); + } + let i = || s.parse::().unwrap_or(0); + let u = || s.parse::().unwrap_or(0); + let f = || s.parse::().unwrap_or(0.0); + match base.as_str() { + "bool" => ffi::new_bool(s == "true"), + "int8" => ffi::tlv_encode("int8", &(i() as i8).to_le_bytes(), 1), + "int16" => ffi::tlv_encode("int16", &(i() as i16).to_le_bytes(), 1), + "int32" => ffi::tlv_encode("int32", &(i() as i32).to_le_bytes(), 1), + "int64" => ffi::new_int64(i()), + "uint8" => ffi::tlv_encode("uint8", &[u() as u8], 1), + "uint16" => ffi::tlv_encode("uint16", &(u() as u16).to_le_bytes(), 1), + "uint32" => ffi::tlv_encode("uint32", &(u() as u32).to_le_bytes(), 1), + "uint64" => ffi::tlv_encode("uint64", &u().to_le_bytes(), 1), + "float32" => ffi::tlv_encode("float32", &(f() as f32).to_le_bytes(), 1), + "float64" => ffi::new_float64(f()), + _ => ffi::tlv_encode(&base, &[], 1), + } +} + /// 写用户声明的 rwir(无体)到 /lib/。 pub fn write_rwir_decl(kv: &mut Kv, decl: &RwirDecl) { let mut opcode = decl.sig.name.clone(); diff --git a/layout/src/kindexpr.rs b/layout/src/kindexpr.rs index a9e274e3..872dff9e 100644 --- a/layout/src/kindexpr.rs +++ b/layout/src/kindexpr.rs @@ -39,11 +39,25 @@ fn known_kind(k: &str) -> bool { | "rwir" | "rwfunc" | "scope" + | "struct" | "time" | "duration" ) } +/// structref = "/" path:指向 /lib 下类型定义节点的完整路径(实例 kindexpr、struct 字段类型)。 +/// 仅做语法承认(`/` + 合法路径段),不解析 /lib 是否存在该类型 —— 存在性/字段一致性留给 runtime。 +fn valid_structref(s: &str) -> bool { + let rest = match s.strip_prefix('/') { + Some(r) => r, + None => return false, + }; + !rest.is_empty() + && rest.split('/').all(|seg| { + !seg.is_empty() && seg.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'_') + }) +} + fn valid_base(s: &str) -> bool { if s.is_empty() { return false; @@ -118,8 +132,11 @@ fn valid_key(s: &str) -> bool { tail.is_empty() && inner.split(',').all(valid_scalar) } -/// atom = shape | mapexpr;mapexpr = key "·" type(value 可递归含容器,故支持嵌套 map)。 +/// atom = shape | mapexpr | structref;mapexpr = key "·" type;structref = "/" path。 fn valid_atom(s: &str) -> bool { + if s.starts_with('/') { + return valid_structref(s); + } if let Some(i) = s.find('·') { return valid_key(&s[..i]) && valid_kindexpr(&s[i + '·'.len_utf8()..]); } @@ -235,6 +252,11 @@ mod tests { "[int32,int32]·[]char/utf8", "[float32,float32]·[]char/utf8", "[float32,int8,uint32]·int64", + "struct", + "/lib/Point", + "/lib/geom/Point", + "/lib/Node", + "/lib/Point|/lib/Node", ] { assert!(valid_kindexpr(e), "{e} should be valid"); } @@ -248,9 +270,16 @@ mod tests { "[?]·int64", "[int32,]·int64", "[foo,int32]·int64", + "/", + "/lib/", + "/lib//Point", + "lib/Point", + "/lib/Po int", ] { assert!(!valid_kindexpr(e), "{e} should be invalid"); } + assert!(match_kindexpr("/lib/Point", "/lib/Point", 0, &[])); + assert!(!match_kindexpr("/lib/Point", "/lib/Node", 0, &[])); assert!(match_kindexpr("[]char/utf8·int64", "stringkeymap", 1, &[3])); assert!(!match_kindexpr("[]char/utf8·int64", "object", 0, &[])); } diff --git a/layout/src/kvkind.rs b/layout/src/kvkind.rs index 01889402..6a13395b 100644 --- a/layout/src/kvkind.rs +++ b/layout/src/kvkind.rs @@ -18,6 +18,7 @@ pub const KIND_OBJ: &str = "object"; pub const KIND_MAP: &str = "stringkeymap"; pub const KIND_INDEX: &str = "index"; pub const KIND_EXT_INDEX: &str = "extindex"; +pub const KIND_STRUCT: &str = "struct"; // kvlang 自有 kind pub const KIND_RWIR: &str = "rwir"; @@ -245,6 +246,26 @@ pub fn new_defrwir(nr: i32, nw: i32, sig: &str) -> Vec { ffi::tlv_encode(KIND_DEF_RWIR, &rwir_body(nr, nw, sig), 1) } +// ── struct 原型(对齐 runtime kvlangBuiltinMemindex)───────────────── +// +// /lib/Name kind=struct,body="name:kindexpr\n..."(字段声明类型,供实例化类型校验) +// /lib/Name· kind=index,body=[4B count LE][name\n...](字段名唯一权威) + +pub fn new_struct(fields: &[(String, String)]) -> Vec { + let body = fields + .iter() + .map(|(n, t)| format!("{n}:{t}")) + .collect::>() + .join("\n"); + ffi::tlv_encode(KIND_STRUCT, body.as_bytes(), 1) +} + +pub fn new_memindex(names: &[String]) -> Vec { + let mut raw = (names.len() as u32).to_le_bytes().to_vec(); + raw.extend_from_slice(names.join("\n").as_bytes()); + ffi::tlv_encode(KIND_INDEX, &raw, 1) +} + // ── kvlang 自有 kind:rwfunc ──────────────────────────────────────── // // body = [2B nr LE][2B nw LE][param_types 以 \n 连接],array_len=num_insts。 diff --git a/layout/src/lib.rs b/layout/src/lib.rs index e80e6513..93089b17 100644 --- a/layout/src/lib.rs +++ b/layout/src/lib.rs @@ -1,5 +1,5 @@ #![allow(non_snake_case)] -//! kvlang-layout — 编译期:parse → lower → layoutcode。 +//! kvlang-layout — 语法检查 + 布局工具:parse → lower → layoutcode(把 AST 检查后布局写入 /lib/)。 //! 只依赖 kvspace-durable 的 C ABI(见 [`ffi`]),不依赖其 Rust 类型。 //! 翻译自 kvlang 的 Go 源码:parser/ lower/ layout/ ast/ symbol/ keytree/。 diff --git a/layout/src/parser.rs b/layout/src/parser.rs index 96723b86..a566ba44 100644 --- a/layout/src/parser.rs +++ b/layout/src/parser.rs @@ -2,7 +2,9 @@ //! //! 入口:`parse_code(src) → Result<(File, Vec), String>`。 -use super::ast::{self, Expr, Func, FuncSig, Instruction, Param, RwirDecl, Stmt}; +use super::ast::{ + self, Expr, Field, Func, FuncSig, Instruction, Param, RwirDecl, Stmt, StructDecl, +}; use super::keytree; use super::scanner::{scan, Diagnostic, Kind, Pos, Token}; use super::symbol; @@ -144,6 +146,17 @@ impl Parser { continue; } + let is_struct = self.peek().kind == Kind::Ident + && self.peek().value == "struct" + && self.peek_at(1).kind == Kind::Ident + && self.peek_at(2).kind == Kind::LBrace; + if is_struct { + let mut decl = self.parse_struct_decl(); + decl.comments = comments; + f.structs.push(decl); + continue; + } + if self.peek().kind == Kind::Ident && self.peek().value == "rwir" { let decl = self.parse_rwir_decl(); f.rwir_decls.push(decl); @@ -258,6 +271,17 @@ impl Parser { self.parse_lib_body(f, &pkg); continue; } + let is_struct = self.peek().kind == Kind::Ident + && self.peek().value == "struct" + && self.peek_at(1).kind == Kind::Ident + && self.peek_at(2).kind == Kind::LBrace; + if is_struct { + let mut decl = self.parse_struct_decl(); + decl.pkg = pkg.clone(); + decl.comments = comments; + f.structs.push(decl); + continue; + } if self.peek().kind == Kind::Ident && self.peek().value == "rwir" { let mut decl = self.parse_rwir_decl(); decl.pkg = pkg.clone(); @@ -351,6 +375,60 @@ impl Parser { decl } + fn parse_struct_decl(&mut self) -> StructDecl { + self.advance(); // consume 'struct' + let name = self.advance().value; // struct 名 + self.expect(Kind::LBrace); + let mut fields = Vec::new(); + loop { + while matches!( + self.peek().kind, + Kind::Newline | Kind::Comma | Kind::Comment + ) { + self.advance(); + } + if self.peek().kind == Kind::RBrace || self.peek().kind == Kind::EOF { + break; + } + if self.peek().kind != Kind::Ident { + let t = self.peek(); + self.errors.push(Diagnostic { + pos: t.pos, + message: format!("struct {name:?}: expected field name, got {:?}", t.value), + warn: false, + info: false, + source: String::new(), + src_file: String::new(), + src_name: String::new(), + }); + break; + } + let fname = self.advance().value; + let mut ty = String::new(); + if self.peek().kind == Kind::Colon { + self.advance(); + ty = self.parse_type(); + } + let mut default = None; + if self.peek().kind == Kind::Arrow && self.peek().value == "=" { + self.advance(); + default = self.parse_pratt(0); + } + fields.push(Field { + name: fname, + ty, + default, + }); + } + self.expect(Kind::RBrace); + StructDecl { + comments: Vec::new(), + name, + pkg: String::new(), + fields, + } + } + fn parse_func_sig(&mut self) -> FuncSig { self.advance(); // consume 'rwfunc' let mut sig = FuncSig { @@ -1163,6 +1241,76 @@ impl Parser { return Some(ast::call("array", elems)); } + // struct 字面量 Name{...} 或 pkg.Name{...} → struct·new("/lib/…", "f", v, …) + let struct_lit = t.kind == Kind::Ident + && (self.peek_at(1).kind == Kind::LBrace || { + let mut j = 1isize; + while self.peek_at(j).kind == Kind::Dot && self.peek_at(j + 1).kind == Kind::Ident { + j += 2; + } + j > 1 && self.peek_at(j).kind == Kind::LBrace + }); + if struct_lit { + let mut path = format!("{}/{}", keytree::LIB_ROOT, self.advance().value); + while self.peek().kind == Kind::Dot && self.peek_at(1).kind == Kind::Ident { + self.advance(); // skip Dot + path.push_str(keytree::MEMBER_SEP); + path.push_str(&self.advance().value); + } + let mut args = vec![ast::str_lit(&path)]; + self.advance(); // consume { + loop { + while matches!( + self.peek().kind, + Kind::Newline | Kind::Comma | Kind::Comment + ) { + self.advance(); + } + if self.peek().kind == Kind::RBrace || self.peek().kind == Kind::EOF { + break; + } + if self.peek().kind != Kind::Ident { + let bt = self.peek(); + self.errors.push(Diagnostic { + pos: bt.pos, + warn: false, + info: false, + message: format!("struct literal: expected field name, got {:?}", bt.value), + source: String::new(), + src_file: String::new(), + src_name: String::new(), + }); + break; + } + let key = self.advance().value; + if !(self.peek().kind == Kind::Arrow && self.peek().value == "=") { + let bt = self.peek(); + self.errors.push(Diagnostic { + pos: bt.pos, + warn: false, + info: false, + message: format!("struct literal: expected '=' after {key:?}"), + source: String::new(), + src_file: String::new(), + src_name: String::new(), + }); + break; + } + self.advance(); // consume = + let val = match self.parse_pratt(0) { + Some(v) => v, + None => break, + }; + args.push(ast::str_lit(&key)); + args.push(val); + } + self.expect(Kind::RBrace); + return Some(ast::call( + &format!("struct{}new", keytree::MEMBER_SEP), + args, + )); + } + // dict 字面量 if t.kind == Kind::LBrace { let mut j = 1isize; @@ -1703,6 +1851,21 @@ impl Parser { if s.starts_with('/') { return; } + // struct 赋值(RHS = struct·new):深拷整棵子树,lower 为 kv·cpdir(struct·new→temp, dst)。 + // 不走 kv·set —— 后者只搬基值,struct 的成员子树会丢在临时槽。dst 传完整成员槽串, + // runtime ResolveWriteSlot 拼 +"base·key…" 即成员绝对路径。 + let is_struct_new = inst + .expr + .as_ref() + .map(|e| e.op == format!("struct{}new", keytree::MEMBER_SEP)) + .unwrap_or(false); + if is_struct_new && !s.contains('*') { + let e = inst.expr.take().unwrap(); + inst.expr = Some(ast::call("kv·cpdir", vec![e, ast::leaf(&s)])); + inst.writes = Vec::new(); + inst.write_types = Vec::new(); + return; + } // 成员链写槽 p·a·b = v → 变参 kv·set(p, "a", "b", v),与读侧 #110 一致逐段拼路径。 // 不再按首个 · 压扁成 kv·set(p, "a·b", v):扁平段把「成员链」与「含 · 的成员名」混为一谈。 let mut parts = s.split(keytree::MEMBER_SEP); From 058e25bf61a7f2c9da1aba9285246f23b142a1a2 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Thu, 3 Sep 2026 10:58:43 +0800 Subject: [PATCH 02/18] =?UTF-8?q?runtime:=20struct=C2=B7new=20=E5=86=85?= =?UTF-8?q?=E5=BB=BA=20+=20cpTree=20=E9=80=A0=E5=AE=9E=E4=BE=8B=EF=BC=88#1?= =?UTF-8?q?99=20=E4=BE=9D=E8=B5=96=20#200=EF=BC=8CWIP=20=E8=90=BD=E7=9B=98?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - builtin_collection:struct·new(type, field...) 解析 struct 原型签名、按字段类型校验实参、 经 kvspaceCpTree 深拷贝原型子树生成 structref 实例(struct 签名/字段类型/默认值语义)。 - builtin.c/kv.c/kindexpr.c/runtime_internal.h:structref kind 路由、CpTree 胶合。 - const.h/builtin_kv.c:相应常量/内建接线。 未完成 WIP 防护性提交(runtime 侧),未跑全量回归。 --- runtime/src/builtin.c | 6 +-- runtime/src/builtin_collection.c | 73 ++++++++++++++++++++++++++++++++ runtime/src/builtin_internal.h | 6 +-- runtime/src/builtin_kv.c | 46 +++++++++++++++++++- runtime/src/const.h | 1 + runtime/src/kindexpr.c | 26 +++++++++++- runtime/src/kv.c | 8 ++++ runtime/src/runtime_internal.h | 4 ++ 8 files changed, 161 insertions(+), 9 deletions(-) diff --git a/runtime/src/builtin.c b/runtime/src/builtin.c index 0a10c5a9..9f08869a 100644 --- a/runtime/src/builtin.c +++ b/runtime/src/builtin.c @@ -545,7 +545,7 @@ static const struct { const char *op; kvlangBuiltinFn fn; } myrwircaps[] = { {"array", kvlangBuiltinArray}, {"array·scatter", kvlangBuiltinScatter}, {"array·compact", kvlangBuiltinCompact}, {"array·append", kvlangBuiltinAppend}, {"array·slice", kvlangBuiltinSlice}, - {"obj", kvlangBuiltinObj}, {"map", kvlangBuiltinMap}, + {"obj", kvlangBuiltinObj}, {"map", kvlangBuiltinMap}, {"struct·new", kvlangBuiltinStructNew}, {"ndarray·numel", kvlangBuiltinNdarrayNumel}, {"ndarray·dim", kvlangBuiltinNdarrayDim}, {"ndarray·shape", kvlangBuiltinNdarrayShape}, {"xv·at", kvlangBuiltinXvAt}, {"xv·set", kvlangBuiltinXvSet}, {"xv·reshape", kvlangBuiltinXvReshape}, {"xv·reinterpret", kvlangBuiltinXvReinterpret}, @@ -567,8 +567,8 @@ static const struct { const char *op; kvlangBuiltinFn fn; } myrwircaps[] = { {"time·before", kvlangBuiltinTimeCmp}, {"time·after", kvlangBuiltinTimeCmp}, {"random·uint64", kvlangBuiltinRandUint64}, {"random·int63", kvlangBuiltinRandInt63}, {"random·intn", kvlangBuiltinRandIntn}, {"kv·get", kvlangBuiltinKvGet}, {"kv·set", kvlangBuiltinKvSet}, {"kv·del", kvlangBuiltinKvDel}, - {"kv·deltree", kvlangBuiltinKvDelTree}, {"kv·list", kvlangBuiltinKvList}, {"kv·listlen", kvlangBuiltinKvListLen}, {"kv·listn", kvlangBuiltinKvListN}, {"kv·mkindex", kvlangBuiltinKvMkindex}, - {"kv·extindex", kvlangBuiltinKvExtIndex}, {"kv·rmindexext", kvlangBuiltinKvRmIndexExt}, {"kv·watch", kvlangBuiltinKvWatch}, + {"kv·deltree", kvlangBuiltinKvDelTree}, {"kv·cp", kvlangBuiltinKvCp}, {"kv·cpdir", kvlangBuiltinKvCpTree}, {"kv·list", kvlangBuiltinKvList}, {"kv·listlen", kvlangBuiltinKvListLen}, {"kv·listn", kvlangBuiltinKvListN}, {"kv·mkindex", kvlangBuiltinKvMkindex}, + {"kv·extindex", kvlangBuiltinKvExtIndex}, {"kv·rmindexext", kvlangBuiltinKvRmIndexExt}, {"kv·watch", kvlangBuiltinKvWatch}, {"kv·abs", kvlangBuiltinKvAbs}, {"vthread·create", kvlangBuiltinVthreadCreate}, {"vthread·run", kvlangBuiltinVthreadRun}, {"vthread·call", kvlangBuiltinVthreadCall}, diff --git a/runtime/src/builtin_collection.c b/runtime/src/builtin_collection.c index 007a4f47..bdf83fb5 100644 --- a/runtime/src/builtin_collection.c +++ b/runtime/src/builtin_collection.c @@ -402,6 +402,79 @@ int kvlangBuiltinObj(kvlangFrame_t *f) { kvlangBuiltinNextPc(f); kvlangBuiltinFreeInputs(in, n); return 0; } +static char *dupn(const char *s, size_t n) { + char *r = malloc(n + 1); + memcpy(r, s, n); + r[n] = 0; + return r; +} + +/* 在 "name:kindexpr\n..." 声明串里查字段名,返回其类型(malloc)或 NULL(无此字段)。 */ +static char *struct_field_type(const char *decl, const char *fname) { + size_t fl = strlen(fname); + const char *p = decl; + while (*p) { + const char *nl = strchr(p, '\n'); + size_t linelen = nl ? (size_t)(nl - p) : strlen(p); + const char *colon = memchr(p, ':', linelen); + if (colon) { + size_t nlen = (size_t)(colon - p); + if (nlen == fl && memcmp(p, fname, fl) == 0) + return dupn(colon + 1, linelen - nlen - 1); + } + if (!nl) break; + p = nl + 1; + } + return NULL; +} + +/* struct·new:克隆 /lib/Name 原型子树到写槽,覆盖给定字段(校验字段存在性+类型)。 + * in[0]=structref("/lib/Name"),其后成对 (字段名, 值)。实例基值 kind=structref。 */ +int kvlangBuiltinStructNew(kvlangFrame_t *f) { + kvlangXvalue_t in[64]; int n = kvlangBuiltinReadInputs(f, in, 64); + if (n < 1) { kvlangBuiltinFreeInputs(in, n); return kvlangBuiltinSetErr(f, "TypeError: struct.new requires a type"); } + char *ref = kvlangXvalueValueString(&in[0]); + kvlangXvalue_t proto; kvlangXvalueZero(&proto); kvlangKvGetOne(f->kv, ref, &proto); + if (kvlangXvalueNone(&proto) || strcmp(kvlangXvalueKind(&proto), KVSPACE_KIND_STRUCT) != 0) { + int e = kvlangBuiltinSetErr(f, "TypeError: %s is not a struct type", ref); + kvlangXvalueFree(&proto); free(ref); kvlangBuiltinFreeInputs(in, n); return e; + } + kvspaceHead_t ph; kvlangXvalueHead(&proto, &ph); + int32_t dclen = 0; const uint8_t *dcl = kvlangXvalueBody(&proto, &ph, &dclen); + char *decl = dupn((const char *)dcl, (size_t)(dclen > 0 ? dclen : 0)); + kvlangXvalueFree(&proto); + + char err[256]; int rc = 0; + char *fr = kvlangKeytreeFrameRoot(f->pc); + for (int w = 0; w < f->inst->nw && rc == 0; w++) { + char *ok = kvlangBuiltinResolveWriteSlot(f->kv, fr, f->inst->writes[w].name); + kvlangKvDelTree(f->kv, ok, err, sizeof err); + if (kvlangKvCpTree(f->kv, ref, ok, err, sizeof err) != 0) { rc = kvlangBuiltinSetErr(f, "%s", err); free(ok); break; } + kvlangXvalue_t mark; kvlangXvalueNewTlv(&mark, ref, (const uint8_t *)"", 0, 1); + kvlangKvPair_t p0 = { ok, mark }; kvlangKvSet(f->kv, &p0, 1, err, sizeof err); kvlangXvalueFree(&mark); + for (int i = 1; i + 1 < n && rc == 0; i += 2) { + char *fname = kvlangXvalueValueString(&in[i]); + char *ftype = struct_field_type(decl, fname); + if (!ftype) { rc = kvlangBuiltinSetErr(f, "TypeError: struct %s has no field %s", ref, fname); free(fname); break; } + const char *vk = kvlangXvalueKind(&in[i + 1]); + kvspaceHead_t vh; kvlangXvalueHead(&in[i + 1], &vh); + kvlang_kindexpr_t vkx; kvlang_kindexpr_parse(vh.kindexpr, &vkx); + if (ftype[0] && !kvlang_rwirextKindexprMatch(ftype, vk, vkx.ndim, vkx.dims)) { + rc = kvlangBuiltinSetErr(f, "TypeError: field %s: expected %s, got %s", fname, ftype, vk[0] ? vk : "None"); + free(ftype); free(fname); break; + } + char *mk = kvlangKeytreeMember(ok, fname); + kvlangKvPair_t p = { mk, in[i + 1] }; kvlangKvSet(f->kv, &p, 1, err, sizeof err); + free(mk); free(ftype); free(fname); + } + free(ok); + } + free(fr); free(decl); free(ref); + kvlangBuiltinFreeInputs(in, n); + if (rc != 0) return rc; + kvlangBuiltinNextPc(f); return 0; +} + int kvlangBuiltinMap(kvlangFrame_t *f) { kvlangXvalue_t in[64]; int n = kvlangBuiltinReadInputs(f, in, 64); char *fr = kvlangKeytreeFrameRoot(f->pc); diff --git a/runtime/src/builtin_internal.h b/runtime/src/builtin_internal.h index cc452725..c3976278 100644 --- a/runtime/src/builtin_internal.h +++ b/runtime/src/builtin_internal.h @@ -20,7 +20,7 @@ int kvlangBuiltinArray(kvlangFrame_t *f), kvlangBuiltinNdarrayNumel(kvlangFrame_ kvlangBuiltinXvAt(kvlangFrame_t *f), kvlangBuiltinXvSet(kvlangFrame_t *f), kvlangBuiltinXvReshape(kvlangFrame_t *f), kvlangBuiltinXvReinterpret(kvlangFrame_t *f), kvlangBuiltinXvKindexpr(kvlangFrame_t *f), kvlangBuiltinXvBodylen(kvlangFrame_t *f), kvlangBuiltinScatter(kvlangFrame_t *f), kvlangBuiltinCompact(kvlangFrame_t *f), - kvlangBuiltinAppend(kvlangFrame_t *f), kvlangBuiltinSlice(kvlangFrame_t *f), kvlangBuiltinObj(kvlangFrame_t *f), kvlangBuiltinMap(kvlangFrame_t *f), kvlangBuiltinStringSet(kvlangFrame_t *f), + kvlangBuiltinAppend(kvlangFrame_t *f), kvlangBuiltinSlice(kvlangFrame_t *f), kvlangBuiltinObj(kvlangFrame_t *f), kvlangBuiltinMap(kvlangFrame_t *f), kvlangBuiltinStructNew(kvlangFrame_t *f), kvlangBuiltinStringSet(kvlangFrame_t *f), kvlangBuiltinStringChar(kvlangFrame_t *f), kvlangBuiltinStringOrd(kvlangFrame_t *f), kvlangBuiltinStringCmp(kvlangFrame_t *f), kvlangBuiltinStringFind(kvlangFrame_t *f), kvlangBuiltinStringLen(kvlangFrame_t *f), kvlangBuiltinStringSlice(kvlangFrame_t *f), kvlangBuiltinStringConcat(kvlangFrame_t *f), @@ -31,8 +31,8 @@ int kvlangBuiltinArray(kvlangFrame_t *f), kvlangBuiltinNdarrayNumel(kvlangFrame_ kvlangBuiltinDurArith(kvlangFrame_t *f), kvlangBuiltinDurCmp(kvlangFrame_t *f), kvlangBuiltinTimeCmp(kvlangFrame_t *f), kvlangBuiltinRandUint64(kvlangFrame_t *f), kvlangBuiltinRandInt63(kvlangFrame_t *f), kvlangBuiltinRandIntn(kvlangFrame_t *f), kvlangBuiltinKvGet(kvlangFrame_t *f), kvlangBuiltinKvSet(kvlangFrame_t *f), kvlangBuiltinKvDel(kvlangFrame_t *f), - kvlangBuiltinKvDelTree(kvlangFrame_t *f), kvlangBuiltinKvList(kvlangFrame_t *f), kvlangBuiltinKvListLen(kvlangFrame_t *f), kvlangBuiltinKvListN(kvlangFrame_t *f), kvlangBuiltinKvMkindex(kvlangFrame_t *f), - kvlangBuiltinKvExtIndex(kvlangFrame_t *f), kvlangBuiltinKvRmIndexExt(kvlangFrame_t *f), kvlangBuiltinKvWatch(kvlangFrame_t *f), + kvlangBuiltinKvDelTree(kvlangFrame_t *f), kvlangBuiltinKvCp(kvlangFrame_t *f), kvlangBuiltinKvCpTree(kvlangFrame_t *f), kvlangBuiltinKvList(kvlangFrame_t *f), kvlangBuiltinKvListLen(kvlangFrame_t *f), kvlangBuiltinKvListN(kvlangFrame_t *f), kvlangBuiltinKvMkindex(kvlangFrame_t *f), + kvlangBuiltinKvExtIndex(kvlangFrame_t *f), kvlangBuiltinKvRmIndexExt(kvlangFrame_t *f), kvlangBuiltinKvWatch(kvlangFrame_t *f), kvlangBuiltinKvAbs(kvlangFrame_t *f), kvlangBuiltinDebugger(kvlangFrame_t *f), kvlangBuiltinVthreadCreate(kvlangFrame_t *f), kvlangBuiltinVthreadRun(kvlangFrame_t *f), kvlangBuiltinVthreadCall(kvlangFrame_t *f), kvlangBuiltinVthreadSleep(kvlangFrame_t *f), diff --git a/runtime/src/builtin_kv.c b/runtime/src/builtin_kv.c index 0072ef23..1a7d5f33 100644 --- a/runtime/src/builtin_kv.c +++ b/runtime/src/builtin_kv.c @@ -21,10 +21,19 @@ static char *path_arg(kvlangFrame_t *f, int idx, const kvlangXvalue_t *in) { return NULL; } +/* 容器 base:object/map/index/extindex 或 struct 实例(kind=structref,以 / 起头)。 + * 容器取其写槽路径拼成员 key;非容器把 base 值当 key 串。 */ +static bool base_is_container(const kvlangXvalue_t *base) { + if (kvlangXvalueNone(base)) return true; + const char *k = kvlangXvalueKind(base); + return k[0] == '/' || strcmp(k, KVSPACE_KIND_OBJ) == 0 || strcmp(k, KVSPACE_KIND_MAP) == 0 || + strcmp(k, KVSPACE_KIND_INDEX) == 0 || strcmp(k, KVSPACE_KIND_EXT_INDEX) == 0; +} + static char *member_path(kvlangFrame_t *f, const kvlangXvalue_t *in, int n) { const kvlangXvalue_t *base = &in[0]; char *fr = kvlangKeytreeFrameRoot(f->pc); - char *bp = kvlangXvalueNone(base) || (strcmp(kvlangXvalueKind(base), KVSPACE_KIND_OBJ) == 0 || strcmp(kvlangXvalueKind(base), KVSPACE_KIND_MAP) == 0 || strcmp(kvlangXvalueKind(base), KVSPACE_KIND_INDEX) == 0 || strcmp(kvlangXvalueKind(base), KVSPACE_KIND_EXT_INDEX) == 0) ? kvlangBuiltinResolveWriteSlot(f->kv, fr, f->inst->reads[0].name) : kvlangXvalueValueString(base); + char *bp = base_is_container(base) ? kvlangBuiltinResolveWriteSlot(f->kv, fr, f->inst->reads[0].name) : kvlangXvalueValueString(base); free(fr); /* 成员链:base 之后逐段拼 key(变参),每段可为静态字面量或动态键(运行时值)。 */ for (int i = 1; i < n; i++) { @@ -74,6 +83,41 @@ int kvlangBuiltinKvDel(kvlangFrame_t *f) { return kv_path_void(f, "kv.del", kvla int kvlangBuiltinKvDelTree(kvlangFrame_t *f) { return kv_path_void(f, "kv.deltree", kvlangKvDelTree); } +/* 绝对路径 / 路径字符串直取,否则裸标识符解析为本帧槽位 key(对齐 kv.list 的裸变量处理)。 */ +static char *resolve_path_arg(kvlangFrame_t *f, int idx, const kvlangXvalue_t *in) { + char *p = path_arg(f, idx, in); + if (p) return p; + char *fr = kvlangKeytreeFrameRoot(f->pc); + char *base = kvlangBuiltinResolveWriteSlot(f->kv, fr, f->inst->reads[idx].name); + free(fr); + return base; +} + +static int kv_two_path_void(kvlangFrame_t *f, const char *name, + int (*op)(kvlangKv_t *, const char *, const char *, char *, uint32_t)) { + kvlangXvalue_t in[2]; int n = kvlangBuiltinReadInputs(f, in, 2); + char *src = n >= 1 ? resolve_path_arg(f, 0, in) : NULL; + char *dst = n >= 2 ? resolve_path_arg(f, 1, in) : NULL; + if (!src || !dst) { free(src); free(dst); kvlangBuiltinFreeInputs(in, n); return kvlangBuiltinSetErr(f, "TypeError: %s requires src,dst path args", name); } + char err[256]; int rc = op(f->kv, src, dst, err, sizeof err); + free(src); free(dst); kvlangBuiltinFreeInputs(in, n); + if (rc != 0) return kvlangBuiltinSetErr(f, "%s", err); + kvlangBuiltinNextPc(f); return 0; +} + +int kvlangBuiltinKvCp(kvlangFrame_t *f) { return kv_two_path_void(f, "kv.cp", kvlangKvCp); } + +int kvlangBuiltinKvCpTree(kvlangFrame_t *f) { return kv_two_path_void(f, "kv.cpdir", kvlangKvCpTree); } + +int kvlangBuiltinKvAbs(kvlangFrame_t *f) { + kvlangXvalue_t in[1]; int n = kvlangBuiltinReadInputs(f, in, 1); + char *p = n >= 1 ? resolve_path_arg(f, 0, in) : NULL; + if (!p) { kvlangBuiltinFreeInputs(in, n); return kvlangBuiltinSetErr(f, "TypeError: kv.abs requires a key"); } + kvlangXvalue_t r; kvlangXvalueNewCharUtf32(&r, p); + int rc = kvlangBuiltinWriteResult(f, &r); kvlangXvalueFree(&r); + free(p); kvlangBuiltinFreeInputs(in, n); return rc; +} + int kvlangBuiltinKvList(kvlangFrame_t *f) { if (f->inst->nw == 0) return kvlangBuiltinSetErr(f, "TypeError: kv.list requires a write param"); kvlangXvalue_t in[1]; int n = kvlangBuiltinReadInputs(f, in, 1); diff --git a/runtime/src/const.h b/runtime/src/const.h index 7ecbdc03..593e0d1f 100644 --- a/runtime/src/const.h +++ b/runtime/src/const.h @@ -30,6 +30,7 @@ #define KVSPACE_KIND_DEF_RWFUNC "defrwfunc" #define KVSPACE_KIND_RWIR_OR_RWFUNC "rwir|rwfunc" #define KVSPACE_KIND_SCOPE "scope" +#define KVSPACE_KIND_STRUCT "struct" #define KVSPACE_KIND_TIME "time" #define KVSPACE_KIND_DURATION "duration" diff --git a/runtime/src/kindexpr.c b/runtime/src/kindexpr.c index 7509a724..57e9e3ce 100644 --- a/runtime/src/kindexpr.c +++ b/runtime/src/kindexpr.c @@ -31,10 +31,31 @@ static bool known_kind(const char *s, size_t len) { kind_eq(s, len, KVSPACE_KIND_OBJ) || kind_eq(s, len, KVSPACE_KIND_MAP) || kind_eq(s, len, KVSPACE_KIND_INDEX) || kind_eq(s, len, KVSPACE_KIND_EXT_INDEX) || kind_eq(s, len, KVSPACE_KIND_RWIR) || kind_eq(s, len, KVSPACE_KIND_RWFUNC) || - kind_eq(s, len, KVSPACE_KIND_SCOPE) || kind_eq(s, len, KVSPACE_KIND_TIME) || + kind_eq(s, len, KVSPACE_KIND_SCOPE) || kind_eq(s, len, KVSPACE_KIND_STRUCT) || + kind_eq(s, len, KVSPACE_KIND_TIME) || kind_eq(s, len, KVSPACE_KIND_DURATION); } +/* structref = "/" path:指向 /lib 下 struct 定义节点的完整路径(实例 kind / 字段类型)。 + * 仅语法承认(`/` + 合法路径段),存在性/字段一致性留给 runtime 判定。 */ +static bool valid_structref(const char *s, size_t len) { + if (len < 2 || s[0] != '/') return false; + size_t seg = 0; + for (size_t i = 1; i < len; i++) { + if (s[i] == '/') { + if (seg == 0) return false; + seg = 0; + continue; + } + char c = s[i]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '_')) + return false; + seg++; + } + return seg > 0; +} + /* base = any | kind(kind 为精确合法 kind 串) */ static bool valid_base(const char *s, size_t len) { if (len == 0) return false; @@ -63,9 +84,10 @@ static bool valid_dims(const char *s, size_t len) { return true; } -/* atom = [dims] base */ +/* atom = [dims] base | structref */ static bool valid_atom(const char *s, size_t len) { if (len == 0) return false; + if (s[0] == '/') return valid_structref(s, len); const char *p = s; if (*p == '[') { const char *end = memchr(p, ']', len); diff --git a/runtime/src/kv.c b/runtime/src/kv.c index 91122dd1..fe3b5435 100644 --- a/runtime/src/kv.c +++ b/runtime/src/kv.c @@ -81,6 +81,14 @@ int kvlangKvDelTree(kvlangKv_t *k, const char *prefix, char *err, uint32_t err_c return kvspaceDelTree(k->h, prefix, err, err_cap); } +int kvlangKvCp(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap) { + return kvspaceCp(k->h, src, dst, err, err_cap); +} + +int kvlangKvCpTree(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap) { + return kvspaceCpTree(k->h, src, dst, err, err_cap); +} + int kvlangKvMkindex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap) { return kvspaceMkindex(k->h, path, err, err_cap); } diff --git a/runtime/src/runtime_internal.h b/runtime/src/runtime_internal.h index 6ad89548..ee9a4395 100644 --- a/runtime/src/runtime_internal.h +++ b/runtime/src/runtime_internal.h @@ -34,6 +34,8 @@ extern int kvspaceListAt(void *h, const char *prefix, int expand_ext, int reso uint8_t **out, uint32_t *out_len); extern int kvspaceDel(void *h, const char *const *keys, uint32_t nkeys, char *err, uint32_t err_cap); extern int kvspaceDelTree(void *h, const char *prefix, char *err, uint32_t err_cap); +extern int kvspaceCp(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); +extern int kvspaceCpTree(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); extern int kvspaceMkindex(void *h, const char *path, char *err, uint32_t err_cap); extern int kvspaceMkindexExt(void *h, const char *path, const char *ext_path, char *err, uint32_t err_cap); extern int kvspaceRmindexExt(void *h, const char *path, char *err, uint32_t err_cap); @@ -140,6 +142,8 @@ int kvlangKvGetMember(kvlangKv_t *k, const char *dir, const char *name, kvlangXv int kvlangKvSet(kvlangKv_t *k, const kvlangKvPair_t *pairs, int n, char *err, uint32_t err_cap); int kvlangKvDel(kvlangKv_t *k, const char *key, char *err, uint32_t err_cap); int kvlangKvDelTree(kvlangKv_t *k, const char *prefix, char *err, uint32_t err_cap); +int kvlangKvCp(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); +int kvlangKvCpTree(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); int kvlangKvMkindex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap); int kvlangKvExtIndex(kvlangKv_t *k, const char *path, const char *ext, char *err, uint32_t err_cap); int kvlangKvDelExtIndex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap); From 4709a9f0b33c4170c478b7718aa74448855af948 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Thu, 3 Sep 2026 10:58:43 +0800 Subject: [PATCH 03/18] =?UTF-8?q?tutorial:=2012-struct=20=E9=87=8D?= =?UTF-8?q?=E5=86=99=E4=B8=BA=20struct=20=E6=95=99=E7=A8=8B=2000-07=20+=20?= =?UTF-8?q?README=20=E6=8E=AA=E8=BE=9E=EF=BC=88#199=EF=BC=8CWIP=20?= =?UTF-8?q?=E8=90=BD=E7=9B=98=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除旧 extern/wip 的 01-linked-list/02-tree/03-graph(占位),重写: 00-point/01-fields/02-mutate/03-linked-list/04-tree/05-graph/06-list-reverse/07-list-local。 - README_CN:编译期→布局、描述措辞对齐。 未完成 WIP 防护性提交(示例侧),未跑全量回归。 --- README_CN.md | 4 +-- tutorial/12-struct/00-point.kv | 21 ++++++++++++++ tutorial/12-struct/01-fields.kv | 24 ++++++++++++++++ tutorial/12-struct/01-linked-list.kv | 29 ------------------- tutorial/12-struct/02-mutate.kv | 20 +++++++++++++ tutorial/12-struct/02-tree.kv | 21 -------------- tutorial/12-struct/03-graph.kv | 21 -------------- tutorial/12-struct/03-linked-list.kv | 24 ++++++++++++++++ tutorial/12-struct/04-tree.kv | 33 +++++++++++++++++++++ tutorial/12-struct/05-graph.kv | 41 +++++++++++++++++++++++++++ tutorial/12-struct/06-list-reverse.kv | 33 +++++++++++++++++++++ tutorial/12-struct/07-list-local.kv | 29 +++++++++++++++++++ 12 files changed, 227 insertions(+), 73 deletions(-) create mode 100644 tutorial/12-struct/00-point.kv create mode 100644 tutorial/12-struct/01-fields.kv delete mode 100644 tutorial/12-struct/01-linked-list.kv create mode 100644 tutorial/12-struct/02-mutate.kv delete mode 100644 tutorial/12-struct/02-tree.kv delete mode 100644 tutorial/12-struct/03-graph.kv create mode 100644 tutorial/12-struct/03-linked-list.kv create mode 100644 tutorial/12-struct/04-tree.kv create mode 100644 tutorial/12-struct/05-graph.kv create mode 100644 tutorial/12-struct/06-list-reverse.kv create mode 100644 tutorial/12-struct/07-list-local.kv diff --git a/README_CN.md b/README_CN.md index 6a9898c6..7234c8ac 100644 --- a/README_CN.md +++ b/README_CN.md @@ -55,7 +55,7 @@ kvspace 是核心的寻址空间与内存空间;语言本体是小核心 runti ![kvlang 生态架构](docs/kvlang-ecosystem-architecture.png) - **kvspace** — 一套 C ABI(`kvspace_*`,24 符号),由 DSN 选择两种实现:`kvspace-c`(C,`shm://`,链接 `blockmalloc` + `slotsboxmalloc`)与 `kvspace-durable`(Rust,`redis://` / `fs://`,s3/tikv 规划中)。 -- **kvlang** — `layout`(Rust,编译)与 `runtime`(C,执行),二者都只依赖 `kvspace_*` C ABI。 +- **kvlang** — `layout`(Rust,语法检查+布局)与 `runtime`(C,执行),二者都只依赖 `kvspace_*` C ABI。 - **rwirext** — 构建在 runtime 之上的扩展。嵌入式(Rust `term`,经 `kvlang_rwirext.h` 链接 `libkvlang_runtime`)或独立进程 handoff(Go `json`、Python `numpy`)。`term` / `json` 只是基础示例扩展,不是招牌能力。 --- @@ -191,7 +191,7 @@ if (sum > 50) { println("big") } else { println("small") } for (x in [7, 2, 9, 4]) { println(x) } ``` -条件支持复合表达式:`if (7 % 2 != 0)`、`while (i < string.len(s))` 均可(编译期自动展平为临时槽)。 +条件支持复合表达式:`if (7 % 2 != 0)`、`while (i < string.len(s))` 均可(布局期自动展平为临时槽)。 ### 操作符 diff --git a/tutorial/12-struct/00-point.kv b/tutorial/12-struct/00-point.kv new file mode 100644 index 00000000..c84ad699 --- /dev/null +++ b/tutorial/12-struct/00-point.kv @@ -0,0 +1,21 @@ +# point: struct 声明 + 实例化 + 成员访问 +# 语义: struct Name { field:kindexpr=default } 注册 /lib/Name 原型; +# Name{f=v} 克隆原型子树、覆盖字段并做类型校验;p·f 成员访问。 +# 期望输出: +# x= 3.0 y= 4.0 +# default x= 0.0 y= 0.0 +struct Point { + x:float64=0.0 + y:float64=0.0 +} + +rwfunc test() -> () { + p = Point{x=3.0 y=4.0} + p·x -> a + p·y -> b + println("x=", a, " y=", b) + q = Point{} + q·x -> c + q·y -> d + println("default x=", c, " y=", d) +} diff --git a/tutorial/12-struct/01-fields.kv b/tutorial/12-struct/01-fields.kv new file mode 100644 index 00000000..e08f2b92 --- /dev/null +++ b/tutorial/12-struct/01-fields.kv @@ -0,0 +1,24 @@ +# fields: 多类型字段 + 默认值 + 部分覆盖 +# 语义: 字段声明 name:kindexpr=default;实例化只写给定字段,其余取默认; +# 类型不符或字段不存在均在 runtime 报 TypeError。 +# 期望输出: +# alice 30 true +# anon 0 false +struct User { + name:[]char/utf32="anon" + age:int64=0 + active:bool=false +} + +rwfunc test() -> () { + u = User{name="alice" age=30 active=true} + u·name -> n + u·age -> a + u·active -> ac + println(n, a, ac) + d = User{} + d·name -> dn + d·age -> da + d·active -> dac + println(dn, da, dac) +} diff --git a/tutorial/12-struct/01-linked-list.kv b/tutorial/12-struct/01-linked-list.kv deleted file mode 100644 index c1acb84c..00000000 --- a/tutorial/12-struct/01-linked-list.kv +++ /dev/null @@ -1,29 +0,0 @@ -// 链表:非表意指针(隐式 ·hex 子 key)+ dict -// 待实现:需隐式 ·hex 子 key + ‥incr 计数(见 非表意指针key生成规则·md) -// wip: 需要 ·hex 隐式创建实现 -// 语义: l 是容器 dict;l·head = {} 隐式建节点 ·1;指针 p 走链,p·next = {} 隐式建下一节点 -// 期望输出: -// 10 -// 20 -// 30 - -l = {} -l·head = {} -l·head·val = 10 - -p = l·head -p·next = {} -p = p·next -p·val = 20 - -p·next = {} -p = p·next -p·val = 30 - -// 遍历链表 -p = l·head -while (p != null) { - p·val -> v - println(v) - p·next -> p -} diff --git a/tutorial/12-struct/02-mutate.kv b/tutorial/12-struct/02-mutate.kv new file mode 100644 index 00000000..ac796568 --- /dev/null +++ b/tutorial/12-struct/02-mutate.kv @@ -0,0 +1,20 @@ +# mutate: 实例成员可读可写 +# 语义: p·field 是普通 KV 成员,创建后可用 val -> p·field 改写。 +# 期望输出: +# before x= 1 y= 2 +# after x= 5 y= 2 +struct P { + x:int64=0 + y:int64=0 +} + +rwfunc test() -> () { + p = P{x=1 y=2} + p·x -> a + p·y -> b + println("before x=", a, " y=", b) + 5 -> p·x + p·x -> c + p·y -> d + println("after x=", c, " y=", d) +} diff --git a/tutorial/12-struct/02-tree.kv b/tutorial/12-struct/02-tree.kv deleted file mode 100644 index 4f6c6dc5..00000000 --- a/tutorial/12-struct/02-tree.kv +++ /dev/null @@ -1,21 +0,0 @@ -// 二叉树:非表意指针 + dict -// 待实现:需隐式 ·hex 子 key -// wip: 需要 ·hex 隐式创建实现 -// 语义: t 是容器;t·root = {} 隐式建根节点 ·1,left/right 各隐式建子节点 -// 期望输出: -// root=5 left=3 right=8 - -t = {} -t·root = {} -t·root·val = 5 - -t·root·left = {} -t·root·left·val = 3 - -t·root·right = {} -t·root·right·val = 8 - -t·root·val -> a -t·root·left·val -> b -t·root·right·val -> c -println("root=", a, " left=", b, " right=", c) diff --git a/tutorial/12-struct/03-graph.kv b/tutorial/12-struct/03-graph.kv deleted file mode 100644 index 158dbabe..00000000 --- a/tutorial/12-struct/03-graph.kv +++ /dev/null @@ -1,21 +0,0 @@ -// 有向图(邻接表):非表意指针 + dict -// 待实现:需隐式 ·hex 子 key -// wip: 需要 ·hex 隐式创建实现 -// 语义: g 是容器;g·a/g·b/g·c 隐式建节点,邻居存为成员引用。边 a→b, a→c -// 期望输出: -// g·a -> 2 , 3 - -g = {} -g·a = {} -g·a·val = 1 -g·b = {} -g·b·val = 2 -g·c = {} -g·c·val = 3 - -g·a·n0 = g·b -g·a·n1 = g·c - -g·a·n0·val -> x -g·a·n1·val -> y -println("g·a ->", x, ",", y) diff --git a/tutorial/12-struct/03-linked-list.kv b/tutorial/12-struct/03-linked-list.kv new file mode 100644 index 00000000..c4411c40 --- /dev/null +++ b/tutorial/12-struct/03-linked-list.kv @@ -0,0 +1,24 @@ +# linked-list: struct 节点存进 map(int 键、struct 值),指针用绝对路径 +# 语义: /list 是 [int64]·/lib/Node 的 map;节点存在自增整数键 ·1 ·2 ·3; +# next 字段存下一节点的绝对路径串(""=尾);"路径"·field 解引用。 +# 期望输出: +# 10 +# 20 +# 30 +struct Node { + val:int64=0 + next:[]char/utf32="" +} + +rwfunc test() -> () { + /list:[int64]·/lib/Node = {} + Node{val=10 next="/list·2"} -> /list·1 + Node{val=20 next="/list·3"} -> /list·2 + Node{val=30} -> /list·3 + cur = "/list·1" + while (cur != "") { + cur·val -> v + println(v) + cur·next -> cur + } +} diff --git a/tutorial/12-struct/04-tree.kv b/tutorial/12-struct/04-tree.kv new file mode 100644 index 00000000..a629d13a --- /dev/null +++ b/tutorial/12-struct/04-tree.kv @@ -0,0 +1,33 @@ +# tree: 二叉树存进 map(int 键、struct 值),左右孩子用绝对路径指针 +# 语义: /tree 是 [int64]·/lib/TNode 的 map;left/right 存孩子绝对路径(""=空); +# inorder 递归中序遍历,node 是路径串,node·field 解引用。 +# 期望输出: +# 3 +# 5 +# 8 +struct TNode { + val:int64=0 + left:[]char/utf32="" + right:[]char/utf32="" +} + +rwfunc inorder(node:[]char/utf32) -> () { + if (node != "") { + node·left -> l + inorder(l) + node·val -> v + println(v) + node·right -> r + inorder(r) + } +} + +rwfunc test() -> () { + /tree:[int64]·/lib/TNode = {} + TNode{val=5} -> /tree·1 + TNode{val=3} -> /tree·2 + TNode{val=8} -> /tree·3 + "/tree·2" -> /tree·1·left + "/tree·3" -> /tree·1·right + inorder("/tree·1") +} diff --git a/tutorial/12-struct/05-graph.kv b/tutorial/12-struct/05-graph.kv new file mode 100644 index 00000000..dc052bcd --- /dev/null +++ b/tutorial/12-struct/05-graph.kv @@ -0,0 +1,41 @@ +# graph: 有向图存进 map(int 键、struct 值),邻居用绝对路径指针 +# 语义: /graph 是 [int64]·/lib/GNode 的 map;e0/e1 是两条出边的绝对路径(""=无); +# seen 标记去重;dfs 深度优先,node 是路径串,本地拷贝 n 后经 n·seen 回写。 +# 边: 1→2 1→3 2→3 +# 期望输出: +# 1 +# 2 +# 3 +struct GNode { + val:int64=0 + e0:[]char/utf32="" + e1:[]char/utf32="" + seen:bool=false +} + +rwfunc dfs(node:[]char/utf32) -> () { + if (node != "") { + node·seen -> s + if (!s) { + n = node + true -> n·seen + node·val -> v + println(v) + node·e0 -> a + dfs(a) + node·e1 -> b + dfs(b) + } + } +} + +rwfunc test() -> () { + /graph:[int64]·/lib/GNode = {} + GNode{val=1} -> /graph·1 + GNode{val=2} -> /graph·2 + GNode{val=3} -> /graph·3 + "/graph·2" -> /graph·1·e0 + "/graph·3" -> /graph·1·e1 + "/graph·3" -> /graph·2·e0 + dfs("/graph·1") +} diff --git a/tutorial/12-struct/06-list-reverse.kv b/tutorial/12-struct/06-list-reverse.kv new file mode 100644 index 00000000..e8d02a95 --- /dev/null +++ b/tutorial/12-struct/06-list-reverse.kv @@ -0,0 +1,33 @@ +# list-reverse: C 风格 struct 指针变量,切换链表指向(原地反转) +# 语义: cur/prev/nxt 都是指针变量(绝对路径串),等价 C 的 Node*; +# cur·next 即 C 的 cur->next。反转 = 逐节点把 next 指回前驱。 +# 链表: 10→20→30 反转后从新头 prev 遍历得 30→20→10 +# 期望输出: +# 30 +# 20 +# 10 +struct Node { + val:int64=0 + next:[]char/utf32="" +} + +rwfunc test() -> () { + /list:[int64]·/lib/Node = {} + Node{val=10 next="/list·2"} -> /list·1 + Node{val=20 next="/list·3"} -> /list·2 + Node{val=30} -> /list·3 + prev = "" + cur = "/list·1" + while (cur != "") { + cur·next -> nxt + prev -> cur·next + cur -> prev + nxt -> cur + } + cur = prev + while (cur != "") { + cur·val -> v + println(v) + cur·next -> cur + } +} diff --git a/tutorial/12-struct/07-list-local.kv b/tutorial/12-struct/07-list-local.kv new file mode 100644 index 00000000..7b544b1e --- /dev/null +++ b/tutorial/12-struct/07-list-local.kv @@ -0,0 +1,29 @@ +# list-local: 用局部变量容器实现链表(不放全局绝对路径) +# 语义: list 是局部 map(帧内,路径含动态 vthread id,源码写不死); +# kv·abs(list) 取容器运行期绝对路径,拼 ·n 造节点指针串; +# struct 赋值 X{…} -> list·n 由 layout 下沉为 kv·cpdir 深拷子树(成员随之落位)。 +# 链表: 10→20→30 +# 期望输出: +# 10 +# 20 +# 30 +struct Node { + val:int64=0 + next:[]char/utf32="" +} + +rwfunc test() -> () { + list:[int64]·/lib/Node = {} + kv·abs(list) -> base + base + "·2" -> p2 + base + "·3" -> p3 + Node{val=10 next=p2} -> list·1 + Node{val=20 next=p3} -> list·2 + Node{val=30} -> list·3 + base + "·1" -> cur + while (cur != "") { + cur·val -> v + println(v) + cur·next -> cur + } +} From ae4ebe8aa3f1f8483308a45403621668f5032081 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Sat, 5 Sep 2026 16:16:37 +0800 Subject: [PATCH 04/18] =?UTF-8?q?fix:=2012-struct=20=E6=95=99=E7=A8=8B?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=E8=BF=81=E7=A7=BB=20#=E2=86=92//=EF=BC=88reb?= =?UTF-8?q?ase=20=E5=90=8E=E5=AF=B9=E9=BD=90=20master=20#219=20=E8=AF=AD?= =?UTF-8?q?=E6=B3=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct WIP 基于 #219 前 master,教程注释仍用 #;rebase 后按现行 // 语法转换。 --- tutorial/12-struct/00-point.kv | 12 ++++++------ tutorial/12-struct/01-fields.kv | 12 ++++++------ tutorial/12-struct/02-mutate.kv | 10 +++++----- tutorial/12-struct/03-linked-list.kv | 14 +++++++------- tutorial/12-struct/04-tree.kv | 14 +++++++------- tutorial/12-struct/05-graph.kv | 16 ++++++++-------- tutorial/12-struct/06-list-reverse.kv | 16 ++++++++-------- tutorial/12-struct/07-list-local.kv | 18 +++++++++--------- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/tutorial/12-struct/00-point.kv b/tutorial/12-struct/00-point.kv index c84ad699..c64f7574 100644 --- a/tutorial/12-struct/00-point.kv +++ b/tutorial/12-struct/00-point.kv @@ -1,9 +1,9 @@ -# point: struct 声明 + 实例化 + 成员访问 -# 语义: struct Name { field:kindexpr=default } 注册 /lib/Name 原型; -# Name{f=v} 克隆原型子树、覆盖字段并做类型校验;p·f 成员访问。 -# 期望输出: -# x= 3.0 y= 4.0 -# default x= 0.0 y= 0.0 +// point: struct 声明 + 实例化 + 成员访问 +// 语义: struct Name { field:kindexpr=default } 注册 /lib/Name 原型; +// Name{f=v} 克隆原型子树、覆盖字段并做类型校验;p·f 成员访问。 +// 期望输出: +// x= 3.0 y= 4.0 +// default x= 0.0 y= 0.0 struct Point { x:float64=0.0 y:float64=0.0 diff --git a/tutorial/12-struct/01-fields.kv b/tutorial/12-struct/01-fields.kv index e08f2b92..16edbb8c 100644 --- a/tutorial/12-struct/01-fields.kv +++ b/tutorial/12-struct/01-fields.kv @@ -1,9 +1,9 @@ -# fields: 多类型字段 + 默认值 + 部分覆盖 -# 语义: 字段声明 name:kindexpr=default;实例化只写给定字段,其余取默认; -# 类型不符或字段不存在均在 runtime 报 TypeError。 -# 期望输出: -# alice 30 true -# anon 0 false +// fields: 多类型字段 + 默认值 + 部分覆盖 +// 语义: 字段声明 name:kindexpr=default;实例化只写给定字段,其余取默认; +// 类型不符或字段不存在均在 runtime 报 TypeError。 +// 期望输出: +// alice 30 true +// anon 0 false struct User { name:[]char/utf32="anon" age:int64=0 diff --git a/tutorial/12-struct/02-mutate.kv b/tutorial/12-struct/02-mutate.kv index ac796568..17ecd441 100644 --- a/tutorial/12-struct/02-mutate.kv +++ b/tutorial/12-struct/02-mutate.kv @@ -1,8 +1,8 @@ -# mutate: 实例成员可读可写 -# 语义: p·field 是普通 KV 成员,创建后可用 val -> p·field 改写。 -# 期望输出: -# before x= 1 y= 2 -# after x= 5 y= 2 +// mutate: 实例成员可读可写 +// 语义: p·field 是普通 KV 成员,创建后可用 val -> p·field 改写。 +// 期望输出: +// before x= 1 y= 2 +// after x= 5 y= 2 struct P { x:int64=0 y:int64=0 diff --git a/tutorial/12-struct/03-linked-list.kv b/tutorial/12-struct/03-linked-list.kv index c4411c40..378bb7f0 100644 --- a/tutorial/12-struct/03-linked-list.kv +++ b/tutorial/12-struct/03-linked-list.kv @@ -1,10 +1,10 @@ -# linked-list: struct 节点存进 map(int 键、struct 值),指针用绝对路径 -# 语义: /list 是 [int64]·/lib/Node 的 map;节点存在自增整数键 ·1 ·2 ·3; -# next 字段存下一节点的绝对路径串(""=尾);"路径"·field 解引用。 -# 期望输出: -# 10 -# 20 -# 30 +// linked-list: struct 节点存进 map(int 键、struct 值),指针用绝对路径 +// 语义: /list 是 [int64]·/lib/Node 的 map;节点存在自增整数键 ·1 ·2 ·3; +// next 字段存下一节点的绝对路径串(""=尾);"路径"·field 解引用。 +// 期望输出: +// 10 +// 20 +// 30 struct Node { val:int64=0 next:[]char/utf32="" diff --git a/tutorial/12-struct/04-tree.kv b/tutorial/12-struct/04-tree.kv index a629d13a..929ddd7a 100644 --- a/tutorial/12-struct/04-tree.kv +++ b/tutorial/12-struct/04-tree.kv @@ -1,10 +1,10 @@ -# tree: 二叉树存进 map(int 键、struct 值),左右孩子用绝对路径指针 -# 语义: /tree 是 [int64]·/lib/TNode 的 map;left/right 存孩子绝对路径(""=空); -# inorder 递归中序遍历,node 是路径串,node·field 解引用。 -# 期望输出: -# 3 -# 5 -# 8 +// tree: 二叉树存进 map(int 键、struct 值),左右孩子用绝对路径指针 +// 语义: /tree 是 [int64]·/lib/TNode 的 map;left/right 存孩子绝对路径(""=空); +// inorder 递归中序遍历,node 是路径串,node·field 解引用。 +// 期望输出: +// 3 +// 5 +// 8 struct TNode { val:int64=0 left:[]char/utf32="" diff --git a/tutorial/12-struct/05-graph.kv b/tutorial/12-struct/05-graph.kv index dc052bcd..3ba5a880 100644 --- a/tutorial/12-struct/05-graph.kv +++ b/tutorial/12-struct/05-graph.kv @@ -1,11 +1,11 @@ -# graph: 有向图存进 map(int 键、struct 值),邻居用绝对路径指针 -# 语义: /graph 是 [int64]·/lib/GNode 的 map;e0/e1 是两条出边的绝对路径(""=无); -# seen 标记去重;dfs 深度优先,node 是路径串,本地拷贝 n 后经 n·seen 回写。 -# 边: 1→2 1→3 2→3 -# 期望输出: -# 1 -# 2 -# 3 +// graph: 有向图存进 map(int 键、struct 值),邻居用绝对路径指针 +// 语义: /graph 是 [int64]·/lib/GNode 的 map;e0/e1 是两条出边的绝对路径(""=无); +// seen 标记去重;dfs 深度优先,node 是路径串,本地拷贝 n 后经 n·seen 回写。 +// 边: 1→2 1→3 2→3 +// 期望输出: +// 1 +// 2 +// 3 struct GNode { val:int64=0 e0:[]char/utf32="" diff --git a/tutorial/12-struct/06-list-reverse.kv b/tutorial/12-struct/06-list-reverse.kv index e8d02a95..fa29acdd 100644 --- a/tutorial/12-struct/06-list-reverse.kv +++ b/tutorial/12-struct/06-list-reverse.kv @@ -1,11 +1,11 @@ -# list-reverse: C 风格 struct 指针变量,切换链表指向(原地反转) -# 语义: cur/prev/nxt 都是指针变量(绝对路径串),等价 C 的 Node*; -# cur·next 即 C 的 cur->next。反转 = 逐节点把 next 指回前驱。 -# 链表: 10→20→30 反转后从新头 prev 遍历得 30→20→10 -# 期望输出: -# 30 -# 20 -# 10 +// list-reverse: C 风格 struct 指针变量,切换链表指向(原地反转) +// 语义: cur/prev/nxt 都是指针变量(绝对路径串),等价 C 的 Node*; +// cur·next 即 C 的 cur->next。反转 = 逐节点把 next 指回前驱。 +// 链表: 10→20→30 反转后从新头 prev 遍历得 30→20→10 +// 期望输出: +// 30 +// 20 +// 10 struct Node { val:int64=0 next:[]char/utf32="" diff --git a/tutorial/12-struct/07-list-local.kv b/tutorial/12-struct/07-list-local.kv index 7b544b1e..4e88fa4e 100644 --- a/tutorial/12-struct/07-list-local.kv +++ b/tutorial/12-struct/07-list-local.kv @@ -1,12 +1,12 @@ -# list-local: 用局部变量容器实现链表(不放全局绝对路径) -# 语义: list 是局部 map(帧内,路径含动态 vthread id,源码写不死); -# kv·abs(list) 取容器运行期绝对路径,拼 ·n 造节点指针串; -# struct 赋值 X{…} -> list·n 由 layout 下沉为 kv·cpdir 深拷子树(成员随之落位)。 -# 链表: 10→20→30 -# 期望输出: -# 10 -# 20 -# 30 +// list-local: 用局部变量容器实现链表(不放全局绝对路径) +// 语义: list 是局部 map(帧内,路径含动态 vthread id,源码写不死); +// kv·abs(list) 取容器运行期绝对路径,拼 ·n 造节点指针串; +// struct 赋值 X{…} -> list·n 由 layout 下沉为 kv·cpdir 深拷子树(成员随之落位)。 +// 链表: 10→20→30 +// 期望输出: +// 10 +// 20 +// 30 struct Node { val:int64=0 next:[]char/utf32="" From cfb44ed12c1dd7dd8492881450863b07adba2410 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Sat, 5 Sep 2026 18:08:49 +0800 Subject: [PATCH 05/18] =?UTF-8?q?struct:=20=E5=AE=9E=E4=BE=8B=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=20cpdir/cpTree=20=E6=B7=B1=E6=8B=B7=20=E2=86=92=20cpl?= =?UTF-8?q?ist/CpList=20=E6=B5=85=E6=8B=B7=EF=BC=88#199=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct 赋值改浅拷:base + 一层成员(kv·cplist),不走 cpTree 整棵子树深拷—— 成员子树不必整体克隆,一层足够且更快。parser/layout/runtime/runtime-rs 同步。 --- layout/src/code.rs | 2 +- layout/src/ffi.rs | 18 +++++++++++------- layout/src/parser.rs | 6 +++--- runtime-rs/src/engine.rs | 20 +++++++++++++------- runtime-rs/src/ffi.rs | 3 ++- runtime/src/builtin.c | 2 +- runtime/src/builtin_collection.c | 3 +-- runtime/src/builtin_internal.h | 2 +- runtime/src/builtin_kv.c | 2 ++ runtime/src/kv.c | 10 +++++++--- runtime/src/runtime_internal.h | 4 +++- 11 files changed, 45 insertions(+), 27 deletions(-) diff --git a/layout/src/code.rs b/layout/src/code.rs index 2393ff41..de206b46 100644 --- a/layout/src/code.rs +++ b/layout/src/code.rs @@ -436,7 +436,7 @@ pub fn write_func(kv: &mut Kv, pkg: &str, fn_: &mut Func) { } /// 写 struct 原型到 /lib/:基节点(kind=struct) + memindex(/lib/Name·) + 各字段默认值。 -/// 运行时 struct·new 以此为原型 cpdir 克隆,故字段默认值即实例初值。 +/// 运行时 struct·new 以此为原型 cplist 克隆,故字段默认值即实例初值。 pub fn write_struct_decl(kv: &mut Kv, decl: &StructDecl) { let mut name = decl.name.clone(); if !decl.pkg.is_empty() { diff --git a/layout/src/ffi.rs b/layout/src/ffi.rs index 10236a17..3c1c452c 100644 --- a/layout/src/ffi.rs +++ b/layout/src/ffi.rs @@ -62,7 +62,8 @@ extern "C" { expand_ext: c_int, resolve: c_int, idx: i32, - out: *mut *mut u8, + buf: *mut u8, + buf_cap: u32, out_len: *mut u32, ) -> c_int; fn kvspaceDel( @@ -237,19 +238,22 @@ impl Kv { } let mut v = Vec::with_capacity(count as usize); for i in 0..count { - let bytes = call_borrow(|out, out_len| unsafe { + let mut buf = [0u8; 1024]; + let mut out_len: u32 = 0; + let ok = unsafe { kvspaceListAt( self.h, c.as_ptr(), expand_ext as c_int, resolve as c_int, i, - out, - out_len, + buf.as_mut_ptr(), + buf.len() as u32, + &mut out_len, ) - }); - if !bytes.is_empty() { - v.push(String::from_utf8_lossy(&bytes).into_owned()); + } == 0; + if ok && out_len > 0 { + v.push(String::from_utf8_lossy(&buf[..out_len as usize]).into_owned()); } } v diff --git a/layout/src/parser.rs b/layout/src/parser.rs index a566ba44..5028cc94 100644 --- a/layout/src/parser.rs +++ b/layout/src/parser.rs @@ -1851,8 +1851,8 @@ impl Parser { if s.starts_with('/') { return; } - // struct 赋值(RHS = struct·new):深拷整棵子树,lower 为 kv·cpdir(struct·new→temp, dst)。 - // 不走 kv·set —— 后者只搬基值,struct 的成员子树会丢在临时槽。dst 传完整成员槽串, + // struct 赋值(RHS = struct·new):浅拷 base+一层成员,lower 为 kv·cplist(struct·new→temp, dst)。 + // 不走 kv·set —— 后者只搬基值,struct 的成员会丢在临时槽。dst 传完整成员槽串, // runtime ResolveWriteSlot 拼 +"base·key…" 即成员绝对路径。 let is_struct_new = inst .expr @@ -1861,7 +1861,7 @@ impl Parser { .unwrap_or(false); if is_struct_new && !s.contains('*') { let e = inst.expr.take().unwrap(); - inst.expr = Some(ast::call("kv·cpdir", vec![e, ast::leaf(&s)])); + inst.expr = Some(ast::call("kv·cplist", vec![e, ast::leaf(&s)])); inst.writes = Vec::new(); inst.write_types = Vec::new(); return; diff --git a/runtime-rs/src/engine.rs b/runtime-rs/src/engine.rs index 2b1aba2a..deeade7b 100644 --- a/runtime-rs/src/engine.rs +++ b/runtime-rs/src/engine.rs @@ -221,15 +221,21 @@ impl Engine { } let mut v = Vec::with_capacity(count as usize); for i in 0..count { - let (mut out, mut olen) = (null_mut(), 0u32); - if kvspaceListAt(self.kv, cp.as_ptr(), 0, 0, i, &mut out, &mut olen) == 0 - && !out.is_null() + let mut buf = [0u8; 1024]; + let mut olen = 0u32; + if kvspaceListAt( + self.kv, + cp.as_ptr(), + 0, + 0, + i, + buf.as_mut_ptr(), + buf.len() as u32, + &mut olen, + ) == 0 && olen > 0 { - v.push( - String::from_utf8_lossy(std::slice::from_raw_parts(out, olen as usize)) - .into_owned(), - ); + v.push(String::from_utf8_lossy(&buf[..olen as usize]).into_owned()); } } v diff --git a/runtime-rs/src/ffi.rs b/runtime-rs/src/ffi.rs index e6b1f77e..bf7d3789 100644 --- a/runtime-rs/src/ffi.rs +++ b/runtime-rs/src/ffi.rs @@ -116,7 +116,8 @@ unsafe extern "C" { expand_ext: c_int, resolve: c_int, idx: i32, - out: *mut *mut u8, + buf: *mut u8, + buf_cap: u32, out_len: *mut u32, ) -> c_int; pub fn kvspaceTlvEncode( diff --git a/runtime/src/builtin.c b/runtime/src/builtin.c index 9f08869a..f6f0bfe3 100644 --- a/runtime/src/builtin.c +++ b/runtime/src/builtin.c @@ -567,7 +567,7 @@ static const struct { const char *op; kvlangBuiltinFn fn; } myrwircaps[] = { {"time·before", kvlangBuiltinTimeCmp}, {"time·after", kvlangBuiltinTimeCmp}, {"random·uint64", kvlangBuiltinRandUint64}, {"random·int63", kvlangBuiltinRandInt63}, {"random·intn", kvlangBuiltinRandIntn}, {"kv·get", kvlangBuiltinKvGet}, {"kv·set", kvlangBuiltinKvSet}, {"kv·del", kvlangBuiltinKvDel}, - {"kv·deltree", kvlangBuiltinKvDelTree}, {"kv·cp", kvlangBuiltinKvCp}, {"kv·cpdir", kvlangBuiltinKvCpTree}, {"kv·list", kvlangBuiltinKvList}, {"kv·listlen", kvlangBuiltinKvListLen}, {"kv·listn", kvlangBuiltinKvListN}, {"kv·mkindex", kvlangBuiltinKvMkindex}, + {"kv·deltree", kvlangBuiltinKvDelTree}, {"kv·cp", kvlangBuiltinKvCp}, {"kv·cpdir", kvlangBuiltinKvCpTree}, {"kv·cplist", kvlangBuiltinKvCpList}, {"kv·list", kvlangBuiltinKvList}, {"kv·listlen", kvlangBuiltinKvListLen}, {"kv·listn", kvlangBuiltinKvListN}, {"kv·mkindex", kvlangBuiltinKvMkindex}, {"kv·extindex", kvlangBuiltinKvExtIndex}, {"kv·rmindexext", kvlangBuiltinKvRmIndexExt}, {"kv·watch", kvlangBuiltinKvWatch}, {"kv·abs", kvlangBuiltinKvAbs}, {"vthread·create", kvlangBuiltinVthreadCreate}, {"vthread·run", kvlangBuiltinVthreadRun}, diff --git a/runtime/src/builtin_collection.c b/runtime/src/builtin_collection.c index bdf83fb5..1e5816ad 100644 --- a/runtime/src/builtin_collection.c +++ b/runtime/src/builtin_collection.c @@ -448,8 +448,7 @@ int kvlangBuiltinStructNew(kvlangFrame_t *f) { char *fr = kvlangKeytreeFrameRoot(f->pc); for (int w = 0; w < f->inst->nw && rc == 0; w++) { char *ok = kvlangBuiltinResolveWriteSlot(f->kv, fr, f->inst->writes[w].name); - kvlangKvDelTree(f->kv, ok, err, sizeof err); - if (kvlangKvCpTree(f->kv, ref, ok, err, sizeof err) != 0) { rc = kvlangBuiltinSetErr(f, "%s", err); free(ok); break; } + if (kvlangKvCpList(f->kv, ref, ok, err, sizeof err) != 0) { rc = kvlangBuiltinSetErr(f, "%s", err); free(ok); break; } kvlangXvalue_t mark; kvlangXvalueNewTlv(&mark, ref, (const uint8_t *)"", 0, 1); kvlangKvPair_t p0 = { ok, mark }; kvlangKvSet(f->kv, &p0, 1, err, sizeof err); kvlangXvalueFree(&mark); for (int i = 1; i + 1 < n && rc == 0; i += 2) { diff --git a/runtime/src/builtin_internal.h b/runtime/src/builtin_internal.h index c3976278..a6ed9996 100644 --- a/runtime/src/builtin_internal.h +++ b/runtime/src/builtin_internal.h @@ -31,7 +31,7 @@ int kvlangBuiltinArray(kvlangFrame_t *f), kvlangBuiltinNdarrayNumel(kvlangFrame_ kvlangBuiltinDurArith(kvlangFrame_t *f), kvlangBuiltinDurCmp(kvlangFrame_t *f), kvlangBuiltinTimeCmp(kvlangFrame_t *f), kvlangBuiltinRandUint64(kvlangFrame_t *f), kvlangBuiltinRandInt63(kvlangFrame_t *f), kvlangBuiltinRandIntn(kvlangFrame_t *f), kvlangBuiltinKvGet(kvlangFrame_t *f), kvlangBuiltinKvSet(kvlangFrame_t *f), kvlangBuiltinKvDel(kvlangFrame_t *f), - kvlangBuiltinKvDelTree(kvlangFrame_t *f), kvlangBuiltinKvCp(kvlangFrame_t *f), kvlangBuiltinKvCpTree(kvlangFrame_t *f), kvlangBuiltinKvList(kvlangFrame_t *f), kvlangBuiltinKvListLen(kvlangFrame_t *f), kvlangBuiltinKvListN(kvlangFrame_t *f), kvlangBuiltinKvMkindex(kvlangFrame_t *f), + kvlangBuiltinKvDelTree(kvlangFrame_t *f), kvlangBuiltinKvCp(kvlangFrame_t *f), kvlangBuiltinKvCpTree(kvlangFrame_t *f), kvlangBuiltinKvCpList(kvlangFrame_t *f), kvlangBuiltinKvList(kvlangFrame_t *f), kvlangBuiltinKvListLen(kvlangFrame_t *f), kvlangBuiltinKvListN(kvlangFrame_t *f), kvlangBuiltinKvMkindex(kvlangFrame_t *f), kvlangBuiltinKvExtIndex(kvlangFrame_t *f), kvlangBuiltinKvRmIndexExt(kvlangFrame_t *f), kvlangBuiltinKvWatch(kvlangFrame_t *f), kvlangBuiltinKvAbs(kvlangFrame_t *f), kvlangBuiltinDebugger(kvlangFrame_t *f), kvlangBuiltinVthreadCreate(kvlangFrame_t *f), kvlangBuiltinVthreadRun(kvlangFrame_t *f), diff --git a/runtime/src/builtin_kv.c b/runtime/src/builtin_kv.c index 1a7d5f33..49042493 100644 --- a/runtime/src/builtin_kv.c +++ b/runtime/src/builtin_kv.c @@ -109,6 +109,8 @@ int kvlangBuiltinKvCp(kvlangFrame_t *f) { return kv_two_path_void(f, "kv.cp", kv int kvlangBuiltinKvCpTree(kvlangFrame_t *f) { return kv_two_path_void(f, "kv.cpdir", kvlangKvCpTree); } +int kvlangBuiltinKvCpList(kvlangFrame_t *f) { return kv_two_path_void(f, "kv.cplist", kvlangKvCpList); } + int kvlangBuiltinKvAbs(kvlangFrame_t *f) { kvlangXvalue_t in[1]; int n = kvlangBuiltinReadInputs(f, in, 1); char *p = n >= 1 ? resolve_path_arg(f, 0, in) : NULL; diff --git a/runtime/src/kv.c b/runtime/src/kv.c index fe3b5435..aefceb40 100644 --- a/runtime/src/kv.c +++ b/runtime/src/kv.c @@ -89,6 +89,10 @@ int kvlangKvCpTree(kvlangKv_t *k, const char *src, const char *dst, char *err, u return kvspaceCpTree(k->h, src, dst, err, err_cap); } +int kvlangKvCpList(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap) { + return kvspaceCpList(k->h, src, dst, err, err_cap); +} + int kvlangKvMkindex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap) { return kvspaceMkindex(k->h, path, err, err_cap); } @@ -110,9 +114,9 @@ int kvlangKvList(kvlangKv_t *k, const char *prefix, bool expand_ext, bool resolv if (count <= 0) return 0; char **names = malloc(sizeof(char *) * (size_t)count); for (int32_t i = 0; i < count; i++) { - uint8_t *d = NULL; uint32_t len = 0; - if (kvspaceListAt(k->h, prefix, ex, rs, i, &d, &len) == 0 && d) - names[i] = strndup((const char *)d, len); + uint8_t buf[1024]; uint32_t len = 0; + if (kvspaceListAt(k->h, prefix, ex, rs, i, buf, sizeof buf, &len) == 0) + names[i] = strndup((const char *)buf, len); else names[i] = strdup(""); } diff --git a/runtime/src/runtime_internal.h b/runtime/src/runtime_internal.h index ee9a4395..941ba990 100644 --- a/runtime/src/runtime_internal.h +++ b/runtime/src/runtime_internal.h @@ -31,11 +31,12 @@ extern int kvspaceWriteNewPlace(void *h, const char *key, const char *kindexpr /* 前缀遍历:listlen 定计数,逐 idx 取名(借用回收缓冲,不得 free),不一次性返回整段名单。 */ extern int kvspaceListLen(void *h, const char *prefix, int expand_ext, int resolve, int32_t *out_count); extern int kvspaceListAt(void *h, const char *prefix, int expand_ext, int resolve, int32_t idx, - uint8_t **out, uint32_t *out_len); + uint8_t *buf, uint32_t buf_cap, uint32_t *out_len); extern int kvspaceDel(void *h, const char *const *keys, uint32_t nkeys, char *err, uint32_t err_cap); extern int kvspaceDelTree(void *h, const char *prefix, char *err, uint32_t err_cap); extern int kvspaceCp(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); extern int kvspaceCpTree(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); +extern int kvspaceCpList(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); extern int kvspaceMkindex(void *h, const char *path, char *err, uint32_t err_cap); extern int kvspaceMkindexExt(void *h, const char *path, const char *ext_path, char *err, uint32_t err_cap); extern int kvspaceRmindexExt(void *h, const char *path, char *err, uint32_t err_cap); @@ -144,6 +145,7 @@ int kvlangKvDel(kvlangKv_t *k, const char *key, char *err, uint32_t err_cap); int kvlangKvDelTree(kvlangKv_t *k, const char *prefix, char *err, uint32_t err_cap); int kvlangKvCp(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); int kvlangKvCpTree(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); +int kvlangKvCpList(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); int kvlangKvMkindex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap); int kvlangKvExtIndex(kvlangKv_t *k, const char *path, const char *ext, char *err, uint32_t err_cap); int kvlangKvDelExtIndex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap); From 94dea4d76a17de9f7cf35b3deb49d669e53af79d Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Sun, 6 Sep 2026 12:03:44 +0800 Subject: [PATCH 06/18] =?UTF-8?q?mkindex:=20=E5=8A=A0=20capacity=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0=EF=BC=88kv=C2=B7mkindex(path,cap)=EF=BC=89+?= =?UTF-8?q?=20=E6=96=B0=E6=95=99=E7=A8=8B=20kv=5Fmkindex=5Fcap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kvlangKvMkindex 传 cap=0(默认);教程演示预分配容量目录。 --- layout/src/ffi.rs | 11 +++++++++-- runtime/src/builtin_kv.c | 11 ++++++++++- runtime/src/kv.c | 4 ++-- runtime/src/kvcpu.c | 4 ++-- runtime/src/runtime.c | 2 +- runtime/src/runtime_internal.h | 4 ++-- runtime/src/vthread.c | 2 +- tutorial/01-basics/kv_mkindex_cap.kv | 11 +++++++++++ 8 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 tutorial/01-basics/kv_mkindex_cap.kv diff --git a/layout/src/ffi.rs b/layout/src/ffi.rs index 3c1c452c..372834fa 100644 --- a/layout/src/ffi.rs +++ b/layout/src/ffi.rs @@ -74,7 +74,13 @@ extern "C" { err_cap: u32, ) -> c_int; fn kvspaceDelTree(h: Handle, prefix: *const c_char, err: *mut c_char, err_cap: u32) -> c_int; - fn kvspaceMkindex(h: Handle, path: *const c_char, err: *mut c_char, err_cap: u32) -> c_int; + fn kvspaceMkindex( + h: Handle, + path: *const c_char, + capacity: u32, + err: *mut c_char, + err_cap: u32, + ) -> c_int; fn kvspaceMkindexExt( h: Handle, path: *const c_char, @@ -269,7 +275,8 @@ impl Kv { pub fn mkindex(&mut self, path: &str) -> Result<(), String> { let c = CString::new(path).expect("no NUL"); let mut err: [c_char; 256] = [0; 256]; - let ret = unsafe { kvspaceMkindex(self.h, c.as_ptr(), err.as_mut_ptr(), err.len() as u32) }; + let ret = + unsafe { kvspaceMkindex(self.h, c.as_ptr(), 0, err.as_mut_ptr(), err.len() as u32) }; err_ret(&mut err, ret) } diff --git a/runtime/src/builtin_kv.c b/runtime/src/builtin_kv.c index 49042493..d3d06dff 100644 --- a/runtime/src/builtin_kv.c +++ b/runtime/src/builtin_kv.c @@ -230,7 +230,16 @@ int kvlangBuiltinKvListN(kvlangFrame_t *f) { return rc; } -int kvlangBuiltinKvMkindex(kvlangFrame_t *f) { return kv_path_void(f, "kv.mkindex", kvlangKvMkindex); } +int kvlangBuiltinKvMkindex(kvlangFrame_t *f) { + kvlangXvalue_t in[2]; int n = kvlangBuiltinReadInputs(f, in, 2); + char *key = n >= 1 ? path_arg(f, 0, in) : NULL; + if (!key) { kvlangBuiltinFreeInputs(in, n); return kvlangBuiltinSetErr(f, "TypeError: kv.mkindex requires a path"); } + uint32_t capacity = n >= 2 ? (uint32_t)kvlangXvalueAsInt64(&in[1]) : 0; + char err[256]; int rc = kvlangKvMkindex(f->kv, key, capacity, err, sizeof err); + free(key); kvlangBuiltinFreeInputs(in, n); + if (rc != 0) return kvlangBuiltinSetErr(f, "%s", err); + kvlangBuiltinNextPc(f); return 0; +} int kvlangBuiltinKvExtIndex(kvlangFrame_t *f) { kvlangXvalue_t in[2]; int n = kvlangBuiltinReadInputs(f, in, 2); diff --git a/runtime/src/kv.c b/runtime/src/kv.c index aefceb40..d12ec09c 100644 --- a/runtime/src/kv.c +++ b/runtime/src/kv.c @@ -93,8 +93,8 @@ int kvlangKvCpList(kvlangKv_t *k, const char *src, const char *dst, char *err, u return kvspaceCpList(k->h, src, dst, err, err_cap); } -int kvlangKvMkindex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap) { - return kvspaceMkindex(k->h, path, err, err_cap); +int kvlangKvMkindex(kvlangKv_t *k, const char *path, uint32_t capacity, char *err, uint32_t err_cap) { + return kvspaceMkindex(k->h, path, capacity, err, err_cap); } int kvlangKvExtIndex(kvlangKv_t *k, const char *path, const char *ext, char *err, uint32_t err_cap) { diff --git a/runtime/src/kvcpu.c b/runtime/src/kvcpu.c index 4d9cf415..0de4f9a3 100644 --- a/runtime/src/kvcpu.c +++ b/runtime/src/kvcpu.c @@ -298,7 +298,7 @@ static char *handle_call(kvlangKv_t *kv, const char *pc, kvlangRwirInst_t *inst) char err[256]; kvlangKvDelTree(kv, frame_root, err, sizeof err); char *stack_fr = kvlangKeytreeStack(frame_root); - kvlangKvMkindex(kv, stack_fr, err, sizeof err); + kvlangKvMkindex(kv, stack_fr, 0, err, sizeof err); kvlangKvExtIndex(kv, stack_fr, func_dir.p, err, sizeof err); /* 系统变量 */ @@ -502,7 +502,7 @@ char *kvlangKvcpuBootstrap(kvlangKv_t *kv, const char *vtid, const char *funcnam char *frame_root = kvlangKeytreeFrameAt(vtid, 1); char *stack_fr = kvlangKeytreeStack(frame_root); char err[256]; - kvlangKvMkindex(kv, stack_fr, err, sizeof err); + kvlangKvMkindex(kv, stack_fr, 0, err, sizeof err); kvlangKvExtIndex(kv, stack_fr, func_dir.p, err, sizeof err); char *ep = kvlangKeytreeEntryPc(frame_root); diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index ba2a2192..7c958b03 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -85,7 +85,7 @@ char *kvlangVthreadSpawn(kvlangKv_t *kv, const char *funcname, kvlangKeytreeVthread(vtid, &vtroot); char *stack_vt = kvlangKeytreeStack(vtroot.p); char e[256]; - kvlangKvMkindex(kv, stack_vt, e, sizeof e); + kvlangKvMkindex(kv, stack_vt, 0, e, sizeof e); char *first_pc = kvlangKvcpuBootstrap(kv, vtid, funcname, args, nargs); if (!first_pc) { free(stack_vt); diff --git a/runtime/src/runtime_internal.h b/runtime/src/runtime_internal.h index 941ba990..ade9aea1 100644 --- a/runtime/src/runtime_internal.h +++ b/runtime/src/runtime_internal.h @@ -37,7 +37,7 @@ extern int kvspaceDelTree(void *h, const char *prefix, char *err, uint32_t err extern int kvspaceCp(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); extern int kvspaceCpTree(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); extern int kvspaceCpList(void *h, const char *src, const char *dst, char *err, uint32_t err_cap); -extern int kvspaceMkindex(void *h, const char *path, char *err, uint32_t err_cap); +extern int kvspaceMkindex(void *h, const char *path, uint32_t capacity, char *err, uint32_t err_cap); extern int kvspaceMkindexExt(void *h, const char *path, const char *ext_path, char *err, uint32_t err_cap); extern int kvspaceRmindexExt(void *h, const char *path, char *err, uint32_t err_cap); extern int kvspaceWatch(void *h, const char *key, const uint8_t *target, uint32_t target_len, @@ -146,7 +146,7 @@ int kvlangKvDelTree(kvlangKv_t *k, const char *prefix, char *err, uint32_t err_c int kvlangKvCp(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); int kvlangKvCpTree(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); int kvlangKvCpList(kvlangKv_t *k, const char *src, const char *dst, char *err, uint32_t err_cap); -int kvlangKvMkindex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap); +int kvlangKvMkindex(kvlangKv_t *k, const char *path, uint32_t capacity, char *err, uint32_t err_cap); int kvlangKvExtIndex(kvlangKv_t *k, const char *path, const char *ext, char *err, uint32_t err_cap); int kvlangKvDelExtIndex(kvlangKv_t *k, const char *path, char *err, uint32_t err_cap); int kvlangKvList(kvlangKv_t *k, const char *prefix, bool expand_ext, bool resolve, diff --git a/runtime/src/vthread.c b/runtime/src/vthread.c index 52c708f8..c24bf976 100644 --- a/runtime/src/vthread.c +++ b/runtime/src/vthread.c @@ -53,7 +53,7 @@ void kvlangVthreadSetError(kvlangKv_t *kv, const char *vtid, const char *pc, con kvlangStrbuf_t dir; kvlangStrbufInit(&dir); kvlangStrbufPutn(&dir, msg_path.p, (size_t)(sep - msg_path.p) + 1); char err[256]; - kvlangKvMkindex(kv, dir.p, err, sizeof err); + kvlangKvMkindex(kv, dir.p, 0, err, sizeof err); kvlangStrbufFree(&dir); } diff --git a/tutorial/01-basics/kv_mkindex_cap.kv b/tutorial/01-basics/kv_mkindex_cap.kv new file mode 100644 index 00000000..3c23e8e2 --- /dev/null +++ b/tutorial/01-basics/kv_mkindex_cap.kv @@ -0,0 +1,11 @@ +// 期望输出: +// n= 3 +rwfunc test() -> () { + kv·mkindex("/tmp/kvtc/", 8) + kv·set("/tmp/kvtc/a", 1) + kv·set("/tmp/kvtc/bb", 2) + kv·set("/tmp/kvtc/ccc", 3) + kv·list("/tmp/kvtc/") -> names + ndarray·numel(names) -> n + println("n=", n) +} From e142dbea15984ea2715e2150c2f8f749e9ba4d54 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Sun, 6 Sep 2026 17:07:03 +0800 Subject: [PATCH 07/18] =?UTF-8?q?docs:=20=E7=94=9F=E6=80=81=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E5=9B=BE=E8=BF=81=E5=85=A5=20+=20stdlib/kvlang=20?= =?UTF-8?q?=E5=A2=9E=20reference=EF=BC=88=E4=BA=94=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=EF=BC=89=E4=B8=8E=20spec=EF=BC=88kvlang=20=E8=A7=84=E8=8C=83?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/kvlang-ecosystem-architecture.{drawio,png}:从 deepx-design 迁入。 - stdlib/kvlang/reference/:五语言对齐参考材料(c99/go/typescript/rust/python, 含 CPython 源码树、C99 标准 PDF 等),供 layout/runtime 行为对齐查阅。 - stdlib/kvlang/spec/:kvlang 形式化规范(词法/类型/求值,.kv 形态,站点可渲染)。 --- docs/kvlang-ecosystem-architecture.drawio | 169 + stdlib/kvlang/reference/README.md | 15 + stdlib/kvlang/reference/c99/n1256.pdf | Bin 0 -> 3788603 bytes stdlib/kvlang/reference/go/go-spec.html | 9652 ++++ .../reference/python/cpython/.coveragerc | 24 + .../reference/python/cpython/.editorconfig | 15 + .../reference/python/cpython/.gitattributes | 119 + .../reference/python/cpython/.gitignore | 191 + .../kvlang/reference/python/cpython/.mailmap | 4 + .../python/cpython/.pre-commit-config.yaml | 149 + .../reference/python/cpython/.readthedocs.yml | 60 + .../reference/python/cpython/.ruff.toml | 12 + .../kvlang/reference/python/cpython/AGENTS.md | 16 + .../reference/python/cpython/Doc/.ruff.toml | 44 + .../reference/python/cpython/Doc/Makefile | 363 + .../reference/python/cpython/Doc/README.rst | 137 + .../reference/python/cpython/Doc/about.rst | 40 + .../reference/python/cpython/Doc/bugs.rst | 116 + .../reference/python/cpython/Doc/conf.py | 608 + .../python/cpython/Doc/constraints.txt | 24 + .../reference/python/cpython/Doc/contents.rst | 23 + .../python/cpython/Doc/copyright.rst | 19 + .../reference/python/cpython/Doc/glossary.rst | 1732 + .../python/cpython/Doc/improve-page-nojs.rst | 29 + .../python/cpython/Doc/improve-page.rst | 65 + .../reference/python/cpython/Doc/license.rst | 1267 + .../reference/python/cpython/Doc/make.bat | 192 + .../reference/python/cpython/Doc/pylock.toml | 245 + .../cpython/Doc/reference/compound_stmts.rst | 2077 + .../cpython/Doc/reference/datamodel.rst | 4021 ++ .../cpython/Doc/reference/executionmodel.rst | 590 + .../cpython/Doc/reference/expressions.rst | 2658 + .../python/cpython/Doc/reference/grammar.rst | 28 + .../python/cpython/Doc/reference/import.rst | 992 + .../python/cpython/Doc/reference/index.rst | 29 + .../cpython/Doc/reference/introduction.rst | 219 + .../Doc/reference/lexical_analysis.rst | 1590 + .../cpython/Doc/reference/simple_stmts.rst | 1176 + .../Doc/reference/toplevel_components.rst | 113 + .../python/cpython/Doc/requirements.txt | 24 + .../kvlang/reference/python/cpython/LICENSE | 277 + .../reference/python/cpython/Makefile.pre.in | 3482 ++ .../reference/python/cpython/README.rst | 235 + .../reference/python/cpython/aclocal.m4 | 794 + .../reference/python/cpython/config.guess | 1807 + .../reference/python/cpython/config.sub | 1974 + .../kvlang/reference/python/cpython/configure | 40255 ++++++++++++++++ .../reference/python/cpython/configure.ac | 8904 ++++ .../reference/python/cpython/install-sh | 541 + .../reference/python/cpython/pyconfig.h.in | 2291 + .../rust/reference-repo/.cargo/config.toml | 2 + .../rust/reference-repo/.gitattributes | 2 + .../.github/workflows/daily-grammar-check.yml | 72 + .../.github/workflows/dev-guide.yml | 49 + .../reference-repo/.github/workflows/main.yml | 191 + .../reference/rust/reference-repo/.gitignore | 4 + .../rust/reference-repo/CONTRIBUTING.md | 3 + .../reference/rust/reference-repo/Cargo.lock | 1017 + .../reference/rust/reference-repo/Cargo.toml | 8 + .../rust/reference-repo/LICENSE-APACHE | 201 + .../reference/rust/reference-repo/LICENSE-MIT | 25 + .../reference/rust/reference-repo/README.md | 7 + .../reference/rust/reference-repo/book.toml | 104 + .../rust/reference-repo/dev-guide/README.md | 7 + .../rust/reference-repo/dev-guide/book.toml | 11 + .../reference-repo/dev-guide/src/SUMMARY.md | 22 + .../dev-guide/src/attributes.md | 190 + .../reference-repo/dev-guide/src/examples.md | 37 + .../dev-guide/src/formatting/admonitions.md | 23 + .../dev-guide/src/formatting/index.md | 3 + .../dev-guide/src/formatting/markdown.md | 45 + .../reference-repo/dev-guide/src/grammar.md | 172 + .../dev-guide/src/introduction.md | 37 + .../reference-repo/dev-guide/src/links.md | 101 + .../dev-guide/src/process/index.md | 80 + .../dev-guide/src/process/stabilization.md | 26 + .../dev-guide/src/publishing.md | 11 + .../reference-repo/dev-guide/src/resources.md | 6 + .../dev-guide/src/review-policy.md | 60 + .../dev-guide/src/rules/index.md | 44 + .../dev-guide/src/rules/test-annotations.md | 15 + .../reference-repo/dev-guide/src/style.md | 15 + .../reference-repo/dev-guide/src/tests.md | 64 + .../dev-guide/src/tooling/building.md | 63 + .../dev-guide/src/tooling/index.md | 10 + .../dev-guide/src/tooling/mdbook-spec.md | 39 + .../rust/reference-repo/docs/authoring.md | 27 + .../rust/reference-repo/reference.md | 4 + .../rust/reference-repo/rust-toolchain.toml | 2 + .../rust/reference-repo/rustfmt.toml | 1 + .../rust/reference-repo/src/SUMMARY.md | 143 + .../reference/rust/reference-repo/src/abi.md | 192 + .../rust/reference-repo/src/appendices.md | 1 + .../rust/reference-repo/src/attributes.md | 368 + .../reference-repo/src/attributes/codegen.md | 940 + .../reference-repo/src/attributes/debugger.md | 228 + .../reference-repo/src/attributes/derive.md | 116 + .../src/attributes/diagnostics.md | 781 + .../reference-repo/src/attributes/limits.md | 88 + .../reference-repo/src/attributes/testing.md | 191 + .../src/attributes/type_system.md | 210 + .../src/behavior-considered-undefined.md | 220 + .../src/behavior-not-considered-unsafe.md | 30 + .../rust/reference-repo/src/comments.md | 149 + .../src/conditional-compilation.md | 530 + .../rust/reference-repo/src/const_eval.md | 343 + .../src/crates-and-source-files.md | 142 + .../rust/reference-repo/src/destructors.md | 711 + .../rust/reference-repo/src/divergence.md | 91 + .../src/dynamically-sized-types.md | 44 + .../rust/reference-repo/src/expressions.md | 430 + .../src/expressions/array-expr.md | 146 + .../src/expressions/await-expr.md | 68 + .../src/expressions/block-expr.md | 365 + .../src/expressions/call-expr.md | 107 + .../src/expressions/closure-expr.md | 110 + .../src/expressions/field-expr.md | 79 + .../src/expressions/grouped-expr.md | 47 + .../reference-repo/src/expressions/if-expr.md | 211 + .../src/expressions/literal-expr.md | 521 + .../src/expressions/loop-expr.md | 461 + .../src/expressions/match-expr.md | 270 + .../src/expressions/method-call-expr.md | 94 + .../src/expressions/operator-expr.md | 1266 + .../src/expressions/path-expr.md | 42 + .../src/expressions/range-expr.md | 67 + .../src/expressions/return-expr.md | 30 + .../src/expressions/struct-expr.md | 151 + .../src/expressions/tuple-expr.md | 98 + .../src/expressions/underscore-expr.md | 39 + .../rust/reference-repo/src/glossary.md | 368 + .../rust/reference-repo/src/grammar.md | 5 + .../rust/reference-repo/src/identifiers.md | 89 + .../rust/reference-repo/src/influences.md | 16 + .../reference-repo/src/inline-assembly.md | 1728 + .../rust/reference-repo/src/input-format.md | 64 + .../reference-repo/src/interior-mutability.md | 29 + .../rust/reference-repo/src/introduction.md | 144 + .../rust/reference-repo/src/items.md | 93 + .../src/items/associated-items.md | 514 + .../src/items/constant-items.md | 120 + .../reference-repo/src/items/enumerations.md | 398 + .../reference-repo/src/items/extern-crates.md | 102 + .../src/items/external-blocks.md | 476 + .../reference-repo/src/items/functions.md | 779 + .../rust/reference-repo/src/items/generics.md | 310 + .../src/items/implementations.md | 291 + .../rust/reference-repo/src/items/modules.md | 141 + .../reference-repo/src/items/static-items.md | 146 + .../rust/reference-repo/src/items/structs.md | 72 + .../rust/reference-repo/src/items/traits.md | 390 + .../reference-repo/src/items/type-aliases.md | 51 + .../rust/reference-repo/src/items/unions.md | 191 + .../src/items/use-declarations.md | 493 + .../rust/reference-repo/src/keywords.md | 167 + .../reference-repo/src/lexical-structure.md | 3 + .../reference-repo/src/lifetime-elision.md | 226 + .../rust/reference-repo/src/linkage.md | 183 + .../reference-repo/src/macro-ambiguity.md | 299 + .../reference-repo/src/macros-by-example.md | 738 + .../rust/reference-repo/src/macros.md | 122 + .../src/memory-allocation-and-lifetime.md | 8 + .../rust/reference-repo/src/memory-model.md | 27 + .../rust/reference-repo/src/names.md | 168 + .../src/names/name-resolution.md | 587 + .../reference-repo/src/names/namespaces.md | 169 + .../rust/reference-repo/src/names/preludes.md | 248 + .../rust/reference-repo/src/names/scopes.md | 384 + .../rust/reference-repo/src/notation.md | 78 + .../rust/reference-repo/src/panic.md | 150 + .../rust/reference-repo/src/paths.md | 521 + .../rust/reference-repo/src/patterns.md | 1071 + .../reference-repo/src/procedural-macros.md | 416 + .../rust/reference-repo/src/runtime.md | 88 + .../rust/reference-repo/src/shebang.md | 47 + .../src/special-types-and-traits.md | 227 + .../src/statements-and-expressions.md | 6 + .../rust/reference-repo/src/statements.md | 157 + .../rust/reference-repo/src/subtyping.md | 113 + .../rust/reference-repo/src/syntax-index.md | 456 + .../rust/reference-repo/src/test-summary.md | 5 + .../rust/reference-repo/src/tokens.md | 868 + .../rust/reference-repo/src/trait-bounds.md | 254 + .../rust/reference-repo/src/type-coercions.md | 303 + .../rust/reference-repo/src/type-layout.md | 726 + .../rust/reference-repo/src/type-system.md | 1 + .../rust/reference-repo/src/types.md | 176 + .../rust/reference-repo/src/types/array.md | 32 + .../rust/reference-repo/src/types/boolean.md | 143 + .../rust/reference-repo/src/types/char.md | 27 + .../rust/reference-repo/src/types/closure.md | 840 + .../rust/reference-repo/src/types/enum.md | 22 + .../reference-repo/src/types/function-item.md | 54 + .../src/types/function-pointer.md | 66 + .../reference-repo/src/types/impl-trait.md | 176 + .../rust/reference-repo/src/types/inferred.md | 26 + .../rust/reference-repo/src/types/never.md | 58 + .../rust/reference-repo/src/types/numeric.md | 57 + .../reference-repo/src/types/parameters.md | 18 + .../rust/reference-repo/src/types/pointer.md | 79 + .../rust/reference-repo/src/types/slice.md | 32 + .../rust/reference-repo/src/types/str.md | 25 + .../rust/reference-repo/src/types/struct.md | 26 + .../reference-repo/src/types/trait-object.md | 88 + .../rust/reference-repo/src/types/tuple.md | 49 + .../rust/reference-repo/src/types/union.md | 20 + .../rust/reference-repo/src/unsafe-keyword.md | 90 + .../rust/reference-repo/src/unsafety.md | 42 + .../rust/reference-repo/src/variables.md | 39 + .../src/visibility-and-privacy.md | 214 + .../rust/reference-repo/src/whitespace.md | 37 + .../rust/reference-repo/theme/reference.css | 693 + .../rust/reference-repo/theme/reference.js | 78 + .../tools/diagnostics/Cargo.toml | 6 + .../tools/diagnostics/README.md | 3 + .../tools/diagnostics/src/lib.rs | 51 + .../tools/grammar-check/Cargo.toml | 24 + .../tools/grammar-check/README.md | 57 + .../grammar-check/src/commands/lex_compare.rs | 378 + .../src/commands/print_grammar.rs | 29 + .../grammar-check/src/commands/split_check.rs | 441 + .../grammar-check/src/commands/tokenize.rs | 73 + .../tools/grammar-check/src/commands/tree.rs | 73 + .../tools/grammar-check/src/main.rs | 428 + .../tools/grammar-check/src/permute.rs | 831 + .../tools/grammar-check/src/test_cases.rs | 111 + .../tools/grammar-check/src/tools/pm2.rs | 455 + .../tools/grammar-check/src/tools/rustc.rs | 267 + .../grammar-check/src/tools/rustc_lexer.rs | 30 + .../reference-repo/tools/grammar/Cargo.toml | 10 + .../reference-repo/tools/grammar/README.md | 3 + .../tools/grammar/src/display.rs | 67 + .../tools/grammar/src/frontmatter.rs | 55 + .../reference-repo/tools/grammar/src/lib.rs | 355 + .../tools/grammar/src/parser.rs | 1333 + .../tools/mdbook-spec/Cargo.toml | 24 + .../tools/mdbook-spec/LICENSE-APACHE | 176 + .../tools/mdbook-spec/LICENSE-MIT | 25 + .../tools/mdbook-spec/README.md | 3 + .../tools/mdbook-spec/src/admonitions.rs | 106 + .../tools/mdbook-spec/src/grammar.rs | 254 + .../src/grammar/render_markdown.rs | 458 + .../src/grammar/render_railroad.rs | 809 + .../tools/mdbook-spec/src/lib.rs | 211 + .../tools/mdbook-spec/src/main.rs | 19 + .../tools/mdbook-spec/src/rules.rs | 118 + .../tools/mdbook-spec/src/std_links.rs | 358 + .../tools/mdbook-spec/src/test_links.rs | 203 + .../reference-repo/tools/parser/Cargo.toml | 12 + .../reference-repo/tools/parser/README.md | 25 + .../tools/parser/src/coverage.rs | 601 + .../reference-repo/tools/parser/src/lexer.rs | 281 + .../reference-repo/tools/parser/src/lib.rs | 119 + .../reference-repo/tools/parser/src/main.rs | 41 + .../reference-repo/tools/parser/src/parser.rs | 630 + .../reference-repo/tools/parser/src/tree.rs | 89 + .../tools/style-check/Cargo.toml | 8 + .../tools/style-check/README.md | 3 + .../tools/style-check/src/main.rs | 130 + .../reference-repo/tools/xtask/Cargo.toml | 6 + .../rust/reference-repo/tools/xtask/README.md | 3 + .../reference-repo/tools/xtask/src/main.rs | 115 + .../rust/reference-repo/triagebot.toml | 30 + .../typescript/typescript-1.8-spec.md | 6738 +++ ...16\344\270\200\350\207\264\346\200\247.kv" | 53 + ...15\346\263\225\345\215\225\345\205\203.kv" | 59 + .../02-\346\263\250\351\207\212.kv" | 42 + ...46\344\270\216\350\267\257\345\276\204.kv" | 59 + ...4-\345\255\227\351\235\242\351\207\217.kv" | 69 + ...5-\350\277\220\347\256\227\347\254\246.kv" | 96 + ...60\345\235\200\347\251\272\351\227\264.kv" | 61 + ...00\344\270\216\345\221\275\345\220\215.kv" | 78 + ...60\347\273\204\350\256\277\351\227\256.kv" | 113 + ...03\345\261\200\346\240\274\345\274\217.kv" | 69 + ...73\347\273\237\345\217\230\351\207\217.kv" | 53 + ...32\345\256\275\347\261\273\345\236\213.kv" | 122 + ...13\350\241\250\350\276\276\345\274\217.kv" | 104 + ...60\347\273\204\345\275\242\346\200\201.kv" | 109 + .../04-\345\256\271\345\231\250.kv" | 109 + ...07\344\273\244\346\236\266\346\236\204.kv" | 80 + .../02-\345\207\275\346\225\260.kv" | 91 + ...3-\346\216\247\345\210\266\346\265\201.kv" | 64 + ...ut\346\265\201\346\260\264\347\272\277.kv" | 58 + .../05-\350\257\212\346\226\255.kv" | 67 + ...44\270\216rwir\346\225\260\346\215\256.kv" | 83 + ...47\350\241\214\346\250\241\345\236\213.kv" | 92 + ...20\345\221\230\350\256\277\351\227\256.kv" | 59 + ...50\344\270\216\345\206\205\345\273\272.kv" | 75 + .../04-rwirext\346\211\251\345\261\225.kv" | 113 + ...344\270\216\345\220\216\347\253\257abi.kv" | 76 + ...30\347\256\227\345\210\206\347\246\273.kv" | 34 + ...07\347\232\206\346\230\216\346\226\207.kv" | 34 + ...60\346\215\256\347\273\223\346\236\204.kv" | 39 + ...43\347\240\201\345\261\202\347\272\247.kv" | 35 + ...00\351\227\250\350\257\255\350\250\200.kv" | 48 + .../01-\346\226\207\346\263\225.kv" | 213 + 296 files changed, 140492 insertions(+) create mode 100644 docs/kvlang-ecosystem-architecture.drawio create mode 100644 stdlib/kvlang/reference/README.md create mode 100644 stdlib/kvlang/reference/c99/n1256.pdf create mode 100644 stdlib/kvlang/reference/go/go-spec.html create mode 100644 stdlib/kvlang/reference/python/cpython/.coveragerc create mode 100644 stdlib/kvlang/reference/python/cpython/.editorconfig create mode 100644 stdlib/kvlang/reference/python/cpython/.gitattributes create mode 100644 stdlib/kvlang/reference/python/cpython/.gitignore create mode 100644 stdlib/kvlang/reference/python/cpython/.mailmap create mode 100644 stdlib/kvlang/reference/python/cpython/.pre-commit-config.yaml create mode 100644 stdlib/kvlang/reference/python/cpython/.readthedocs.yml create mode 100644 stdlib/kvlang/reference/python/cpython/.ruff.toml create mode 100644 stdlib/kvlang/reference/python/cpython/AGENTS.md create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/.ruff.toml create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/Makefile create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/README.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/about.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/bugs.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/conf.py create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/constraints.txt create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/contents.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/copyright.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/glossary.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/improve-page-nojs.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/improve-page.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/license.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/make.bat create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/pylock.toml create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/compound_stmts.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/datamodel.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/executionmodel.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/expressions.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/grammar.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/import.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/index.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/introduction.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/lexical_analysis.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/simple_stmts.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/reference/toplevel_components.rst create mode 100644 stdlib/kvlang/reference/python/cpython/Doc/requirements.txt create mode 100644 stdlib/kvlang/reference/python/cpython/LICENSE create mode 100644 stdlib/kvlang/reference/python/cpython/Makefile.pre.in create mode 100644 stdlib/kvlang/reference/python/cpython/README.rst create mode 100644 stdlib/kvlang/reference/python/cpython/aclocal.m4 create mode 100755 stdlib/kvlang/reference/python/cpython/config.guess create mode 100755 stdlib/kvlang/reference/python/cpython/config.sub create mode 100755 stdlib/kvlang/reference/python/cpython/configure create mode 100644 stdlib/kvlang/reference/python/cpython/configure.ac create mode 100755 stdlib/kvlang/reference/python/cpython/install-sh create mode 100644 stdlib/kvlang/reference/python/cpython/pyconfig.h.in create mode 100644 stdlib/kvlang/reference/rust/reference-repo/.cargo/config.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/.gitattributes create mode 100644 stdlib/kvlang/reference/rust/reference-repo/.github/workflows/daily-grammar-check.yml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/.github/workflows/dev-guide.yml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/.github/workflows/main.yml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/.gitignore create mode 100644 stdlib/kvlang/reference/rust/reference-repo/CONTRIBUTING.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/Cargo.lock create mode 100644 stdlib/kvlang/reference/rust/reference-repo/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/LICENSE-APACHE create mode 100644 stdlib/kvlang/reference/rust/reference-repo/LICENSE-MIT create mode 100644 stdlib/kvlang/reference/rust/reference-repo/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/book.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/book.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/SUMMARY.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/attributes.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/examples.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/admonitions.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/index.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/markdown.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/grammar.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/introduction.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/links.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/index.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/stabilization.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/publishing.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/resources.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/review-policy.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/index.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/test-annotations.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/style.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tests.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/building.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/index.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/mdbook-spec.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/docs/authoring.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/reference.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/rust-toolchain.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/rustfmt.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/SUMMARY.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/abi.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/appendices.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes/codegen.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes/debugger.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes/derive.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes/diagnostics.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes/limits.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes/testing.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/attributes/type_system.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/behavior-considered-undefined.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/behavior-not-considered-unsafe.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/comments.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/conditional-compilation.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/const_eval.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/crates-and-source-files.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/destructors.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/divergence.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/dynamically-sized-types.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/array-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/await-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/block-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/call-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/closure-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/field-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/grouped-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/if-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/literal-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/loop-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/match-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/method-call-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/operator-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/path-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/range-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/return-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/struct-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/tuple-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/expressions/underscore-expr.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/glossary.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/grammar.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/identifiers.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/influences.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/inline-assembly.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/input-format.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/interior-mutability.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/introduction.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/associated-items.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/constant-items.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/enumerations.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/extern-crates.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/external-blocks.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/functions.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/generics.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/implementations.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/modules.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/static-items.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/structs.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/traits.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/type-aliases.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/unions.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/items/use-declarations.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/keywords.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/lexical-structure.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/lifetime-elision.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/linkage.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/macro-ambiguity.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/macros-by-example.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/macros.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/memory-allocation-and-lifetime.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/memory-model.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/names.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/names/name-resolution.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/names/namespaces.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/names/preludes.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/names/scopes.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/notation.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/panic.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/paths.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/patterns.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/procedural-macros.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/runtime.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/shebang.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/special-types-and-traits.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/statements-and-expressions.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/statements.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/subtyping.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/syntax-index.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/test-summary.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/tokens.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/trait-bounds.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/type-coercions.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/type-layout.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/type-system.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/array.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/boolean.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/char.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/closure.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/enum.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/function-item.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/function-pointer.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/impl-trait.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/inferred.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/never.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/numeric.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/parameters.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/pointer.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/slice.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/str.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/struct.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/trait-object.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/tuple.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/types/union.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/unsafe-keyword.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/unsafety.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/variables.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/visibility-and-privacy.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/src/whitespace.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/theme/reference.css create mode 100644 stdlib/kvlang/reference/rust/reference-repo/theme/reference.js create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/src/lib.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/lex_compare.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/print_grammar.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/split_check.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tokenize.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tree.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/main.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/permute.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/test_cases.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/pm2.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc_lexer.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/display.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/frontmatter.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/lib.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/parser.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-APACHE create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-MIT create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/admonitions.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_markdown.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_railroad.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/lib.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/main.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/rules.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/std_links.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/test_links.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/coverage.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lexer.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lib.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/main.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/parser.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/tree.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/style-check/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/style-check/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/style-check/src/main.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/xtask/Cargo.toml create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/xtask/README.md create mode 100644 stdlib/kvlang/reference/rust/reference-repo/tools/xtask/src/main.rs create mode 100644 stdlib/kvlang/reference/rust/reference-repo/triagebot.toml create mode 100644 stdlib/kvlang/reference/typescript/typescript-1.8-spec.md create mode 100644 "stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" create mode 100644 "stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\344\270\216\350\257\215\346\263\225\345\215\225\345\205\203.kv" create mode 100644 "stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\346\263\250\351\207\212.kv" create mode 100644 "stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\240\207\350\257\206\347\254\246\344\270\216\350\267\257\345\276\204.kv" create mode 100644 "stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\345\255\227\351\235\242\351\207\217.kv" create mode 100644 "stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\350\277\220\347\256\227\347\254\246.kv" create mode 100644 "stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" create mode 100644 "stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" create mode 100644 "stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" create mode 100644 "stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" create mode 100644 "stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\347\263\273\347\273\237\345\217\230\351\207\217.kv" create mode 100644 "stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" create mode 100644 "stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-kindexpr\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" create mode 100644 "stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\346\225\260\347\273\204\345\275\242\346\200\201.kv" create mode 100644 "stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\345\256\271\345\231\250.kv" create mode 100644 "stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" create mode 100644 "stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\345\207\275\346\225\260.kv" create mode 100644 "stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\346\216\247\345\210\266\346\265\201.kv" create mode 100644 "stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/04-layout\346\265\201\346\260\264\347\272\277.kv" create mode 100644 "stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/05-\350\257\212\346\226\255.kv" create mode 100644 "stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/06-lib\344\270\216rwir\346\225\260\346\215\256.kv" create mode 100644 "stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/01-\346\211\247\350\241\214\346\250\241\345\236\213.kv" create mode 100644 "stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/02-\346\210\220\345\221\230\350\256\277\351\227\256.kv" create mode 100644 "stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/03-\345\207\275\346\225\260\350\260\203\347\224\250\344\270\216\345\206\205\345\273\272.kv" create mode 100644 "stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/04-rwirext\346\211\251\345\261\225.kv" create mode 100644 "stdlib/kvlang/spec/05-runtime\350\257\255\344\271\211/05-c-runtime\344\270\216\345\220\216\347\253\257abi.kv" create mode 100644 "stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/01-\345\255\230\347\256\227\345\210\206\347\246\273.kv" create mode 100644 "stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/02-\344\270\200\345\210\207\347\232\206\346\230\216\346\226\207.kv" create mode 100644 "stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/03-\347\250\213\345\272\217\345\215\263\346\225\260\346\215\256\347\273\223\346\236\204.kv" create mode 100644 "stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/04-\344\273\243\347\240\201\345\261\202\347\272\247.kv" create mode 100644 "stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/05-\345\246\202\344\275\225\350\256\276\350\256\241\344\270\200\351\227\250\350\257\255\350\250\200.kv" create mode 100644 "stdlib/kvlang/spec/\351\231\204\345\275\225/01-\346\226\207\346\263\225.kv" diff --git a/docs/kvlang-ecosystem-architecture.drawio b/docs/kvlang-ecosystem-architecture.drawio new file mode 100644 index 00000000..8a905729 --- /dev/null +++ b/docs/kvlang-ecosystem-architecture.drawio @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stdlib/kvlang/reference/README.md b/stdlib/kvlang/reference/README.md new file mode 100644 index 00000000..14aad752 --- /dev/null +++ b/stdlib/kvlang/reference/README.md @@ -0,0 +1,15 @@ +# 五语言规范原始文档(对齐参考) + +kvlang 行为与命名对齐 C/Python/Rust/Go/TypeScript。此目录存放各语言**规范原始文档**,作为 kvlang 语言规范设计与"分裂时选阵营"裁决的一手依据。仅供参考,不参与构建。 + +| 语言 | 文档 | 版本/来源 | 形态 | +|------|------|-----------|------| +| C99 | `c99/n1256.pdf` | WG14 N1256(C99 + TC1/2/3,ISO 9899:1999 事实等价终稿) | PDF ~552 页 | +| Rust | `rust/reference-repo/` | github.com/rust-lang/reference @ main(shallow) | mdBook markdown(`src/`) | +| Python | `python/cpython/Doc/reference/` | github.com/python/cpython @ main(blobless + sparse) | reStructuredText | +| Go | `go/go-spec.html` | go.dev/ref/spec(The Go Programming Language Specification) | 单页 HTML | +| TypeScript | `typescript/typescript-1.8-spec.md` | microsoft/TypeScript @ v1.8.10 `doc/spec.md`(官方规范终版,此后停更并归档) | Markdown | + +下载日期:2026-09-06。来源均为各语言权威/官方发布点。 + +> 冻结快照 commit:rust reference @ e24eecf97b0c9a6dbac67191098204dc8a190aaa;cpython @ 7cd63cddade4c3e1de17c3443695afe1f41d8495(已移除 .git,纯文件形态) diff --git a/stdlib/kvlang/reference/c99/n1256.pdf b/stdlib/kvlang/reference/c99/n1256.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f2a372f19783679a122f8db4569859ea1842bd78 GIT binary patch literal 3788603 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 pZVbkuGaaAzR~2jbu{b6Rfto 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

dvITsf4YRxSoQ0rUL;1*v{yu2s^$OICT+uG|Ic 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�$Dg88lN&pG)!SnTG}ybpP=aVM2_!(YRPL~)C{y- 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⎞v;gr_F7YW^Yzsv~QebkH zLH=bXb@d|N*HrJ#7TH0<+;@uS0@}EFP)00TC~QASZs3BaPYS%4sqSd0t6Jp5-#M$7J4UI|V^Q>;SI~+w zum+fh#pVgP#?75P%GG|By}Nj7L0{Jnq{)6=O}pDIEW%%8tO(20q7PK(7b6ze-^P#3 zYM(5A$Sb)VIW6PoGq1J`o#VUJ)s(Ba6cBoGVa@rocIGDP8cIk_AgN|Uco4vW7 zv2hGKNN#KttBf15Ia}#(GNw`O7(U7xNxtlG+NsGMj(kbhw&KIl_Fy=M{(=@PPuw%D z>P>KJg@7D0x8$#-nqjGxv7@f68r!BTK(7Qgjf@IqqdR!@WKIr9;Mo-m88{y6O)wLN zi-EG61U3+^U3qTOOpnTm5Wg3x9R`Xn@HLwFD{^gyr8BM#p0vqO5&zBMILqv3-YR#_ zZ$l8m;Cq{M4uHV-%NPs@hZZU-nV0BZ6}+(?O3X4V8JuGdGQlcV!&rSLD6^kHOYWL1 zo1m1376|&0PYeIj#hiP0K$Qi z(kCFB=Wo3!wI1+E+3-lwAI?ZPbHxdGsp}^oQaNzaG#E1tj)>L~(fsyeZf*#7Rp__B zuVWbyc0`J;m$G1uB5Pp33|c*I#h&9uU+rd_vxFfIz!AEljw&2#v@@k_}qb&)uCj#d()e)_*LunW+u7od(kS+%h1hkgSI_jWso~9%oJEB zq%D=Fjv)KS)ylORC>Hg0&39=Qh`Hr1@fT@K1)!%Y?#Lh@gn+H+^xJJQ5PkoH$gXk# z^0eDkhI!ZF>!u%`K(|va^Duda9-fFAV{x8Er{m^0okhOtO5&D8c%wp4>FnQA0)mCE z9@XcO56t5_AxOU4?Du5W;Lt28Ug2fWx!l?WiX_~H2KTHdTii}RfyWjT#;sC|R0Org zIpa%Hq1Hn^f(I|FexEl?M&m8W$$>!8xyDA0tw=y(aa$9(yTay?cEL^RDc`Y(X8Gv0 z1Vey%wev_O^D6#|{29PttMK%XN%v1pZr14EH$^Mmef79__N%!9++5ghk zX8+rBsN1TV!S7ktZLXYsJYJ^2c#k)U1Y~hV4u~{YOF$b&q!@Pzs&2cVapZPxFGXEq z_OXfq1WAxyEj!WnVf5tcUcWPOJq3FG8nZN5nW(v|r)$b-KsQm%GyEb6EqI$pDbRS; zWheX6G1QNJ7#Wb1q|JE1knDAbfW&}lc?>G1|Fw&*pVeda;(^bCg#bfugLQF#uFzNz z+M*q@uR�uuhV8b@kcq;dTV|e)h6r*TG3%wszq@Y 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%0Ad1;rAr8|yt7j2 zEb4StIdlu^HS@1cK@4Cm|i@`b5m#1SMh2kTtk9s@gPAcwcV(?1f9Q zfiTv_x7H236$4fk3<0ZriK(d}RdGxxUd+|k!@3o=K~L#*{$Pat*-|@-nU0+0oN&ff zT!3qjD1mq)LA%o?=1`&JTOa$l`CXdjcsy_ojL<~^rbK^_;l z>WxYNxVD&`U##D?&xROs;DkNV7HU$phn=S>OK#+Wx2B541K_Q&7L}0RtRGmZ;4yUJ zadQrn0hONt+D$4s>$RYb+c~OWXMt>rT|cUQlc9Oz^vt1FR!^~EQDS8Lutmw0?_TUqp; zTUJ(0;+5Vp!6gWe%%7$#0Qs6 zH|JRMy)n!q_&vt`Eb~PotBk3qbN|MTO`OL85+t)0ueK%MZmFX{S#e z35YYXDe?4ghF-44C$1wFzM$wsgusFA&h$JLxN_>E-)I$6)Zfrg2ur39sSq9eG96Qh z`EgmxHc4*$YkS1IhB3CBA+QL$Ji`Rb`&L0|b=5=jG%;|xI!z5IFid}Yc7RURCqOXe zm2bc7U;`wtBVp6yigSw|gTH~C>b>X@YpGBx@jx z+yd$FBLJ5H!{!LV%OsGi(*~os9B1DrE6Xpxs5A4Eh4cHyR%0wbql}_IP_N~b&0K=F zTrx(X04G9FcuIal1!bxVIp09df{uwBYxSUvB=HAKVz@kBU$p-2iUaO^U}zve1z}Jk zr9O=yV6*~><7RLj`FQ%fUdcGaA?ry%MiHzDXjT-kk9&enmgA2 zs^*S`;h!JJpz{ahGyE$I?hnXk_>%_t_iL3upZr(IXJz>Jfp42%Qha#tM;!rOIx{_{ zHxh-lV4env2KJyBV~4{jlb(ahBp3F}j;BNIrFkou3I7w(^( z9nhd0b}OO|9yw_zi!7SG6TX{HE)!7_je|ZJ*{0OjN04ed9VPowExNBB7j?|S#D7J< z#u=wvCq87)i0`D5y)TrXJ|3#2RL4mszVLcYkS(mKJB$-L?D;zctLP8Y2pcv_j)NSa zf2g18VVyQhL>ow0y+s|H>rgks(WLfXz&NXHpg8SwwdXSTg<}+eIutF&sB~IIIMd@; z>-G|k_k?RuabBCY~Z!%&$z|wfE9Oi{dx~N zs$^#PO=>FpcAxFxXjSxXRPsuJl)^EplSR}?(X>j+vfBM9ul?C{6PUYuSR3X#&x^IK zq#ZRm#@9N*Q;nS+KJCO;a+`?C)99?^Iw2CHlhe+N!w^?$4b(3z%uzfUUMzVh5ZW*T zbv=NO9~s;T$)cpL#9 z+!P!FQ}gd{%5=3PBd$6^Ue}<^etEvPh+RBRgju$7yO2zGEvc_JotiBy z?}5HCVrvKSK!K;O78y+3n#^&}!M;k`@DPh5ueKu&RCScuMEa;iFy84pQ%=)(^N+J~ z;iy7Wsycvh&JK}Iv1U9s2vjgh!3EMdhYRF=B_hNQC%D%TWWf!s($Hq~LXY{BU_KXCXWc-x z(>8jK-Pl;UQ-OhThXbHNDg|4A{yteFa^ALKm0W^}E^j8?vq;>lz&LOtz(sNTn;MC7 z4}4*5c{Z|ltIe4pvSzFQ=O`brG6ybE8DET@egD%n!YWu>l0>!F?@9#=_v|0{GOV(} zxmAuEjd|hn`oRsZil>{Z61ks|f1?o zda4OtjWvHt2`D$TXW;169n#r7wo#b%-P&wC~WQPBDbmNE@-T2H@hJ;Bp6}g zb>@SD2vLn%e1G8VIn3*2vG6)#Z?h8$jQ4l=jcuP{Q4T0U0@zqj;eH(|WBVLKo&n?a ztX#dashgBy-#wSc|9N+WCj49M>67VYSI$2f9P!%)x_>D+10RWWl;w*qQ~LuR1{TK3 z6Fc>Q9xp7EU206f5cb9H6@17mJK+EVZ#1}FU<^_ad)z-u2zzY|(jSFL2>W<<7+&m! zT_QB$=^ur1K!G1&B3rdkRP0h0&VoEl zE;V&{tl2K}CDYb@Ul zNcgAqe79;(+Q)3_yT3Bk)e??X{}x&QP6NmKf7ZbL<2V1m2CK3#{DrV!_=|{u;m;5J z50Lebzxyk)GO_$SWF1%2{KMqty;zN3lhROw{zJqJ3(V4t6NG%h3L!QHAc%UlmQ~9B z%US;M@+BfLloE`u)Z_#SHHza-xy-!1zV(RtN5E6}&qL-%(}JzMS7ihu(@Rif-sqf( z{>gTMAhd1ra92Y(JiY(|{|oML#=UoBk3$A8F?b{LjlNg*Ae?KSHzB*I9xhLB)@n*& zh5F(~99g*z+HUY!9Sb-sp2Au|v#d}0H) z-7M`yw``WEg(H}0eU zIp2Uf0t1P3zOLRURn1azF@OIqEp(GM0R0@f5;fk&Xv0Z&E!z%U!Pi3$>+k(6%l3Fo zTUsOv>>tqOYrNV-qqvJ@#4>ZaI&S$0aRBB-LO;M|`5v1pq6r77TVLbTy(kipZjT9l zn0lLFT9juSa__ZpCSU)R�z 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

$Bh~rUS{b3AAu^HUqFW%C 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 literal 0 HcmV?d00001 diff --git a/stdlib/kvlang/reference/go/go-spec.html b/stdlib/kvlang/reference/go/go-spec.html new file mode 100644 index 00000000..25dcf863 --- /dev/null +++ b/stdlib/kvlang/reference/go/go-spec.html @@ -0,0 +1,9652 @@ + + + + + + + + + + + + + + + + + + + + + + + + +The Go Programming Language Specification - The Go Programming Language + + + + + + + + + + + + +

+ + +
+ + + +
+ + + + + +

The Go Programming Language Specification

+ + + +

Language version go1.27 (May 26, 2026)

+ + + + + + + + + + + + + + +

Introduction

+ +

+This is the reference manual for the Go programming language. +For more information and other documents, see go.dev. +

+ +

+Go is a general-purpose language designed with systems programming +in mind. It is strongly typed and garbage-collected and has explicit +support for concurrent programming. Programs are constructed from +packages, whose properties allow efficient management of +dependencies. +

+ +

+The syntax is compact and simple to parse, allowing for easy analysis +by automatic tools such as integrated development environments. +

+ +

Notation

+

+The syntax is specified using a +variant +of Extended Backus-Naur Form (EBNF): +

+ +
+Syntax      = { Production } .
+Production  = production_name "=" [ Expression ] "." .
+Expression  = Term { "|" Term } .
+Term        = Factor { Factor } .
+Factor      = production_name | token [ "…" token ] | Group | Option | Repetition .
+Group       = "(" Expression ")" .
+Option      = "[" Expression "]" .
+Repetition  = "{" Expression "}" .
+
+ +

+Productions are expressions constructed from terms and the following +operators, in increasing precedence: +

+
+|   alternation
+()  grouping
+[]  option (0 or 1 times)
+{}  repetition (0 to n times)
+
+ +

+Lowercase production names are used to identify lexical (terminal) tokens. +Non-terminals are in CamelCase. Lexical tokens are enclosed in +double quotes "" or back quotes ``. +

+ +

+The form a … b represents the set of characters from +a through b as alternatives. The horizontal +ellipsis is also used elsewhere in the spec to informally denote various +enumerations or code snippets that are not further specified. The character +(as opposed to the three characters ...) is not a token of the Go +language. +

+ +

+A link of the form [Go 1.xx] indicates that a described +language feature (or some aspect of it) was changed or added with language version 1.xx and +thus requires at minimum that language version to build. +For details, see the linked section +in the appendix. +

+ +

Source code representation

+ +

+Source code is Unicode text encoded in +UTF-8. The text is not +canonicalized, so a single accented code point is distinct from the +same character constructed from combining an accent and a letter; +those are treated as two code points. For simplicity, this document +will use the unqualified term character to refer to a Unicode code point +in the source text. +

+

+Each code point is distinct; for instance, uppercase and lowercase letters +are different characters. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may disallow the NUL character (U+0000) in the source text. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may ignore a UTF-8-encoded byte order mark +(U+FEFF) if it is the first Unicode code point in the source text. +A byte order mark may be disallowed anywhere else in the source. +

+ +

Characters

+ +

+The following terms are used to denote specific Unicode character categories: +

+
+newline        = /* the Unicode code point U+000A */ .
+unicode_char   = /* an arbitrary Unicode code point except newline */ .
+unicode_letter = /* a Unicode code point categorized as "Letter" */ .
+unicode_digit  = /* a Unicode code point categorized as "Number, decimal digit" */ .
+
+ +

+In The Unicode Standard 8.0, +Section 4.5 "General Category" defines a set of character categories. +Go treats all characters in any of the Letter categories Lu, Ll, Lt, Lm, or Lo +as Unicode letters, and those in the Number category Nd as Unicode digits. +

+ +

Letters and digits

+ +

+The underscore character _ (U+005F) is considered a lowercase letter. +

+
+letter        = unicode_letter | "_" .
+decimal_digit = "0" … "9" .
+binary_digit  = "0" | "1" .
+octal_digit   = "0" … "7" .
+hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" .
+
+ +

Lexical elements

+ +

Comments

+ +

+Comments serve as program documentation. There are two forms: +

+ +
    +
  1. +Line comments start with the character sequence // +and stop at the end of the line. +
  2. +
  3. +General comments start with the character sequence /* +and stop with the first subsequent character sequence */. +
  4. +
+ +

+A comment cannot start inside a rune or +string literal, or inside a comment. +A general comment containing no newlines acts like a space. +Any other comment acts like a newline. +

+ +

Tokens

+ +

+Tokens form the vocabulary of the Go language. +There are four classes: identifiers, keywords, operators +and punctuation, and literals. White space, formed from +spaces (U+0020), horizontal tabs (U+0009), +carriage returns (U+000D), and newlines (U+000A), +is ignored except as it separates tokens +that would otherwise combine into a single token. Also, a newline or end of file +may trigger the insertion of a semicolon. +While breaking the input into tokens, +the next token is the longest sequence of characters that form a +valid token. +

+ +

Semicolons

+ +

+The formal syntax uses semicolons ";" as terminators in +a number of productions. Go programs may omit most of these semicolons +using the following two rules: +

+ +
    +
  1. +When the input is broken into tokens, a semicolon is automatically inserted +into the token stream immediately after a line's final token if that token is + +
  2. + +
  3. +To allow complex statements to occupy a single line, a semicolon +may be omitted before a closing ")" or "}". +
  4. +
+ +

+To reflect idiomatic use, code examples in this document elide semicolons +using these rules. +

+ + +

Identifiers

+ +

+Identifiers name program entities such as variables and types. +An identifier is a sequence of one or more letters and digits. +The first character in an identifier must be a letter. +

+
+identifier = letter { letter | unicode_digit } .
+
+
+a
+_x9
+ThisVariableIsExported
+αβ
+
+ +

+Some identifiers are predeclared. +

+ + +

Keywords

+ +

+The following keywords are reserved and may not be used as identifiers. +

+
+break        default      func         interface    select
+case         defer        go           map          struct
+chan         else         goto         package      switch
+const        fallthrough  if           range        type
+continue     for          import       return       var
+
+ +

Operators and punctuation

+ +

+The following character sequences represent operators +(including assignment operators) and punctuation +[Go 1.18]: +

+
++    &     +=    &=     &&    ==    !=    (    )
+-    |     -=    |=     ||    <     <=    [    ]
+*    ^     *=    ^=     <-    >     >=    {    }
+/    <<    /=    <<=    ++    =     :=    ,    ;
+%    >>    %=    >>=    --    !     ...   .    :
+     &^          &^=          ~
+
+ +

Integer literals

+ +

+An integer literal is a sequence of digits representing an +integer constant. +An optional prefix sets a non-decimal base: 0b or 0B +for binary, 0, 0o, or 0O for octal, +and 0x or 0X for hexadecimal +[Go 1.13]. +A single 0 is considered a decimal zero. +In hexadecimal literals, letters a through f +and A through F represent values 10 through 15. +

+ +

+For readability, an underscore character _ may appear after +a base prefix or between successive digits; such underscores do not change +the literal's value. +

+
+int_lit        = decimal_lit | binary_lit | octal_lit | hex_lit .
+decimal_lit    = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] .
+binary_lit     = "0" ( "b" | "B" ) [ "_" ] binary_digits .
+octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .
+hex_lit        = "0" ( "x" | "X" ) [ "_" ] hex_digits .
+
+decimal_digits = decimal_digit { [ "_" ] decimal_digit } .
+binary_digits  = binary_digit { [ "_" ] binary_digit } .
+octal_digits   = octal_digit { [ "_" ] octal_digit } .
+hex_digits     = hex_digit { [ "_" ] hex_digit } .
+
+ +
+42
+4_2
+0600
+0_600
+0o600
+0O600       // second character is capital letter 'O'
+0xBadFace
+0xBad_Face
+0x_67_7a_2f_cc_40_c6
+170141183460469231731687303715884105727
+170_141183_460469_231731_687303_715884_105727
+
+_42         // an identifier, not an integer literal
+42_         // invalid: _ must separate successive digits
+4__2        // invalid: only one _ at a time
+0_xBadFace  // invalid: _ must separate successive digits
+
+ + +

Floating-point literals

+ +

+A floating-point literal is a decimal or hexadecimal representation of a +floating-point constant. +

+ +

+A decimal floating-point literal consists of an integer part (decimal digits), +a decimal point, a fractional part (decimal digits), and an exponent part +(e or E followed by an optional sign and decimal digits). +One of the integer part or the fractional part may be elided; one of the decimal point +or the exponent part may be elided. +An exponent value exp scales the mantissa (integer and fractional part) by 10exp. +

+ +

+A hexadecimal floating-point literal consists of a 0x or 0X +prefix, an integer part (hexadecimal digits), a radix point, a fractional part (hexadecimal digits), +and an exponent part (p or P followed by an optional sign and decimal digits). +One of the integer part or the fractional part may be elided; the radix point may be elided as well, +but the exponent part is required. (This syntax matches the one given in IEEE 754-2008 §5.12.3.) +An exponent value exp scales the mantissa (integer and fractional part) by 2exp +[Go 1.13]. +

+ +

+For readability, an underscore character _ may appear after +a base prefix or between successive digits; such underscores do not change +the literal value. +

+ +
+float_lit         = decimal_float_lit | hex_float_lit .
+
+decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
+                    decimal_digits decimal_exponent |
+                    "." decimal_digits [ decimal_exponent ] .
+decimal_exponent  = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
+
+hex_float_lit     = "0" ( "x" | "X" ) hex_mantissa hex_exponent .
+hex_mantissa      = [ "_" ] hex_digits "." [ hex_digits ] |
+                    [ "_" ] hex_digits |
+                    "." hex_digits .
+hex_exponent      = ( "p" | "P" ) [ "+" | "-" ] decimal_digits .
+
+ +
+0.
+72.40
+072.40       // == 72.40
+2.71828
+1.e+0
+6.67428e-11
+1E6
+.25
+.12345E+5
+1_5.         // == 15.0
+0.15e+0_2    // == 15.0
+
+0x1p-2       // == 0.25
+0x2.p10      // == 2048.0
+0x1.Fp+0     // == 1.9375
+0X.8p-0      // == 0.5
+0X_1FFFP-16  // == 0.1249847412109375
+0x15e-2      // == 0x15e - 2 (integer subtraction)
+
+0x.p1        // invalid: mantissa has no digits
+1p-2         // invalid: p exponent requires hexadecimal mantissa
+0x1.5e-2     // invalid: hexadecimal mantissa requires p exponent
+1_.5         // invalid: _ must separate successive digits
+1._5         // invalid: _ must separate successive digits
+1.5_e1       // invalid: _ must separate successive digits
+1.5e_1       // invalid: _ must separate successive digits
+1.5e1_       // invalid: _ must separate successive digits
+
+ + +

Imaginary literals

+ +

+An imaginary literal represents the imaginary part of a +complex constant. +It consists of an integer or +floating-point literal +followed by the lowercase letter i. +The value of an imaginary literal is the value of the respective +integer or floating-point literal multiplied by the imaginary unit i +[Go 1.13] +

+ +
+imaginary_lit = (decimal_digits | int_lit | float_lit) "i" .
+
+ +

+For backward compatibility, an imaginary literal's integer part consisting +entirely of decimal digits (and possibly underscores) is considered a decimal +integer, even if it starts with a leading 0. +

+ +
+0i
+0123i         // == 123i for backward-compatibility
+0o123i        // == 0o123 * 1i == 83i
+0xabci        // == 0xabc * 1i == 2748i
+0.i
+2.71828i
+1.e+0i
+6.67428e-11i
+1E6i
+.25i
+.12345E+5i
+0x1p-2i       // == 0x1p-2 * 1i == 0.25i
+
+ + +

Rune literals

+ +

+A rune literal represents a rune constant, +an integer value identifying a Unicode code point. +A rune literal is expressed as one or more characters enclosed in single quotes, +as in 'x' or '\n'. +Within the quotes, any character may appear except newline and unescaped single +quote. A single quoted character represents the Unicode value +of the character itself, +while multi-character sequences beginning with a backslash encode +values in various formats. +

+ +

+The simplest form represents the single character within the quotes; +since Go source text is Unicode characters encoded in UTF-8, multiple +UTF-8-encoded bytes may represent a single integer value. For +instance, the literal 'a' holds a single byte representing +a literal a, Unicode U+0061, value 0x61, while +'ä' holds two bytes (0xc3 0xa4) representing +a literal a-dieresis, U+00E4, value 0xe4. +

+ +

+Several backslash escapes allow arbitrary values to be encoded as +ASCII text. There are four ways to represent the integer value +as a numeric constant: \x followed by exactly two hexadecimal +digits; \u followed by exactly four hexadecimal digits; +\U followed by exactly eight hexadecimal digits, and a +plain backslash \ followed by exactly three octal digits. +In each case the value of the literal is the value represented by +the digits in the corresponding base. +

+ +

+Although these representations all result in an integer, they have +different valid ranges. Octal escapes must represent a value between +0 and 255 inclusive. Hexadecimal escapes satisfy this condition +by construction. The escapes \u and \U +represent Unicode code points so within them some values are illegal, +in particular those above 0x10FFFF and surrogate halves. +

+ +

+After a backslash, certain single-character escapes represent special values: +

+ +
+\a   U+0007 alert or bell
+\b   U+0008 backspace
+\f   U+000C form feed
+\n   U+000A line feed or newline
+\r   U+000D carriage return
+\t   U+0009 horizontal tab
+\v   U+000B vertical tab
+\\   U+005C backslash
+\'   U+0027 single quote  (valid escape only within rune literals)
+\"   U+0022 double quote  (valid escape only within string literals)
+
+ +

+An unrecognized character following a backslash in a rune literal is illegal. +

+ +
+rune_lit         = "'" ( unicode_value | byte_value ) "'" .
+unicode_value    = unicode_char | little_u_value | big_u_value | escaped_char .
+byte_value       = octal_byte_value | hex_byte_value .
+octal_byte_value = `\` octal_digit octal_digit octal_digit .
+hex_byte_value   = `\` "x" hex_digit hex_digit .
+little_u_value   = `\` "u" hex_digit hex_digit hex_digit hex_digit .
+big_u_value      = `\` "U" hex_digit hex_digit hex_digit hex_digit
+                           hex_digit hex_digit hex_digit hex_digit .
+escaped_char     = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
+
+ +
+'a'
+'ä'
+'本'
+'\t'
+'\000'
+'\007'
+'\377'
+'\x07'
+'\xff'
+'\u12e4'
+'\U00101234'
+'\''         // rune literal containing single quote character
+'aa'         // illegal: too many characters
+'\k'         // illegal: k is not recognized after a backslash
+'\xa'        // illegal: too few hexadecimal digits
+'\0'         // illegal: too few octal digits
+'\400'       // illegal: octal value over 255
+'\uDFFF'     // illegal: surrogate half
+'\U00110000' // illegal: invalid Unicode code point
+
+ + +

String literals

+ +

+A string literal represents a string constant +obtained from concatenating a sequence of characters. There are two forms: +raw string literals and interpreted string literals. +

+ +

+Raw string literals are character sequences between back quotes, as in +`foo`. Within the quotes, any character may appear except +back quote. The value of a raw string literal is the +string composed of the uninterpreted (implicitly UTF-8-encoded) characters +between the quotes; +in particular, backslashes have no special meaning and the string may +contain newlines. +Carriage return characters ('\r') inside raw string literals +are discarded from the raw string value. +

+ +

+Interpreted string literals are character sequences between double +quotes, as in "bar". +Within the quotes, any character may appear except newline and unescaped double quote. +The text between the quotes forms the +value of the literal, with backslash escapes interpreted as they +are in rune literals (except that \' is illegal and +\" is legal), with the same restrictions. +The three-digit octal (\nnn) +and two-digit hexadecimal (\xnn) escapes represent individual +bytes of the resulting string; all other escapes represent +the (possibly multi-byte) UTF-8 encoding of individual characters. +Thus inside a string literal \377 and \xFF represent +a single byte of value 0xFF=255, while ÿ, +\u00FF, \U000000FF and \xc3\xbf represent +the two bytes 0xc3 0xbf of the UTF-8 encoding of character +U+00FF. +

+ +
+string_lit             = raw_string_lit | interpreted_string_lit .
+raw_string_lit         = "`" { unicode_char | newline } "`" .
+interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
+
+ +
+`abc`                // same as "abc"
+`\n
+\n`                  // same as "\\n\n\\n"
+"\n"
+"\""                 // same as `"`
+"Hello, world!\n"
+"日本語"
+"\u65e5本\U00008a9e"
+"\xff\u00FF"
+"\uD800"             // illegal: surrogate half
+"\U00110000"         // illegal: invalid Unicode code point
+
+ +

+These examples all represent the same string: +

+ +
+"日本語"                                 // UTF-8 input text
+`日本語`                                 // UTF-8 input text as a raw literal
+"\u65e5\u672c\u8a9e"                    // the explicit Unicode code points
+"\U000065e5\U0000672c\U00008a9e"        // the explicit Unicode code points
+"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"  // the explicit UTF-8 bytes
+
+ +

+If the source code represents a character as two code points, such as +a combining form involving an accent and a letter, the result will be +an error if placed in a rune literal (it is not a single code +point), and will appear as two code points if placed in a string +literal. +

+ + +

Constants

+ +

There are boolean constants, +rune constants, +integer constants, +floating-point constants, complex constants, +and string constants. Rune, integer, floating-point, +and complex constants are +collectively called numeric constants. +

+ +

+A constant value is represented by a +rune, +integer, +floating-point, +imaginary, +or +string literal, +an identifier denoting a constant, +a constant expression, +a conversion with a result that is a constant, or +the result value of some built-in functions such as +min or max applied to constant arguments, +unsafe.Sizeof applied to certain values, +cap or len applied to +some expressions, +real and imag applied to a complex constant +and complex applied to numeric constants. +The boolean truth values are represented by the predeclared constants +true and false. The predeclared identifier +iota denotes an integer constant. +

+ +

+In general, complex constants are a form of +constant expression +and are discussed in that section. +

+ +

+Numeric constants represent exact values of arbitrary precision and do not overflow. +Consequently, there are no constants denoting the IEEE 754 negative zero, infinity, +and not-a-number values. +

+ +

+Constants may be typed or untyped. +Literal constants, true, false, iota, +and certain constant expressions +containing only untyped constant operands are untyped. +

+ +

+A constant may be given a type explicitly by a constant declaration +or conversion, or implicitly when used in a +variable declaration or an +assignment statement or as an +operand in an expression. +It is an error if the constant value +cannot be represented as a value of the respective type. +If the type is a type parameter, the constant is converted into a non-constant +value of the type parameter. +

+ +

+An untyped constant has a default type which is the type to which the +constant is implicitly converted in contexts where a typed value is required, +for instance, in a short variable declaration +such as i := 0 where there is no explicit type. +The default type of an untyped constant is bool, rune, +int, float64, complex128, or string +respectively, depending on whether it is a boolean, rune, integer, floating-point, +complex, or string constant. +

+ +

+Implementation restriction: Although numeric constants have arbitrary +precision in the language, a compiler may implement them using an +internal representation with limited precision. That said, every +implementation must: +

+ +
    +
  • Represent integer constants with at least 256 bits.
  • + +
  • Represent floating-point constants, including the parts of + a complex constant, with a mantissa of at least 256 bits + and a signed binary exponent of at least 16 bits.
  • + +
  • Give an error if unable to represent an integer constant + precisely.
  • + +
  • Give an error if unable to represent a floating-point or + complex constant due to overflow.
  • + +
  • Round to the nearest representable constant if unable to + represent a floating-point or complex constant due to limits + on precision.
  • +
+ +

+These requirements apply both to literal constants and to the result +of evaluating constant +expressions. +

+ + +

Variables

+ +

+A variable is a storage location for holding a value. +The set of permissible values is determined by the +variable's type. +

+ +

+A variable declaration +or, for function parameters and results, the signature +of a function declaration +or function literal reserves +storage for a named variable. + +Calling the built-in function new +or taking the address of a composite literal +allocates storage for a variable at run time. +Such an anonymous variable is referred to via a (possibly implicit) +pointer indirection. +

+ +

+Structured variables of array, slice, +and struct types have elements and fields that may +be addressed individually. Each such element +acts like a variable. +

+ +

+The static type (or just type) of a variable is the +type given in its declaration, the type provided in the +new call or composite literal, or the type of +an element of a structured variable. +Variables of interface type also have a distinct dynamic type, +which is the (non-interface) type of the value assigned to the variable at run time +(unless the value is the predeclared identifier nil, +which has no type). +The dynamic type may vary during execution but values stored in interface +variables are always assignable +to the static type of the variable. +

+ +
+var x interface{}  // x is nil and has static type interface{}
+var v *T           // v has value nil, static type *T
+x = 42             // x has value 42 and dynamic type int
+x = v              // x has value (*T)(nil) and dynamic type *T
+
+ +

+A variable's value is retrieved by referring to the variable in an +expression; it is the most recent value +assigned to the variable. +If a variable has not yet been assigned a value, its value is the +zero value for its type. +

+ +

Types

+ +

+A type determines a set of values together with operations and methods specific +to those values. A type may be denoted by a type name, if it has one, which must be +followed by type arguments if the type is generic. +A type may also be specified using a type literal, which composes a type +from existing types. +

+ +
+Type     = TypeName [ TypeArgs ] | TypeLit | "(" Type ")" .
+TypeName = identifier | QualifiedIdent .
+TypeArgs = "[" TypeList [ "," ] "]" .
+TypeList = Type { "," Type } .
+TypeLit  = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
+           SliceType | MapType | ChannelType .
+
+ +

+The language predeclares certain type names. +Others are introduced with type declarations +or type parameter lists. +Composite types—array, struct, pointer, function, +interface, slice, map, and channel types—may be constructed using +type literals. +

+ +

+Predeclared types (excluding any), +defined types, and +type parameters are called named types. +An alias denotes a named type if the type given in the alias declaration is a named type. +All named types are distinct. +

+ +

Boolean types

+ +

+A boolean type represents the set of Boolean truth values +denoted by the predeclared constants true +and false. The predeclared boolean type is bool; +it is a named type. +

+ +

Numeric types

+ +

+An integer, floating-point, or complex type +represents the set of integer, floating-point, or complex values, respectively. +They are collectively called numeric types. +The predeclared architecture-independent numeric types are: +

+ +
+uint8       the set of all unsigned  8-bit integers (0 to 255)
+uint16      the set of all unsigned 16-bit integers (0 to 65535)
+uint32      the set of all unsigned 32-bit integers (0 to 4294967295)
+uint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)
+
+int8        the set of all signed  8-bit integers (-128 to 127)
+int16       the set of all signed 16-bit integers (-32768 to 32767)
+int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
+int64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
+
+float32     the set of all IEEE 754 32-bit floating-point numbers
+float64     the set of all IEEE 754 64-bit floating-point numbers
+
+complex64   the set of all complex numbers with float32 real and imaginary parts
+complex128  the set of all complex numbers with float64 real and imaginary parts
+
+byte        alias for uint8
+rune        alias for int32
+
+ +

+The value of an n-bit integer is n bits wide and represented using +two's complement arithmetic. +

+ +

+There is also a set of predeclared integer types with implementation-specific sizes: +

+ +
+uint     either 32 or 64 bits
+int      same size as uint
+uintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value
+
+ +

+To avoid portability issues all numeric types are named types and thus distinct except +byte, which is an alias for uint8, and +rune, which is an alias for int32. +Explicit conversions +are required when different numeric types are mixed in an expression +or assignment. For instance, int32 and int +are not the same type even though they may have the same size on a +particular architecture. +

+ +

String types

+ +

+A string type represents the set of string values. +A string value is a (possibly empty) sequence of bytes. +The number of bytes is called the length of the string and is never negative. +Strings are immutable: once created, +it is impossible to change the contents of a string. +The predeclared string type is string; +it is a named type. +

+ +

+The length of a string s can be discovered using +the built-in function len. +The length is a compile-time constant if the string is a constant. +A string's bytes can be accessed by integer indices +0 through len(s)-1. +It is illegal to take the address of such an element; if +s[i] is the i'th byte of a +string, &s[i] is invalid. +

+ + +

Array types

+ +

+An array is a numbered sequence of elements of a single +type, called the element type. +The number of elements is called the length of the array and is never negative. +

+ +
+ArrayType   = "[" ArrayLength "]" ElementType .
+ArrayLength = Expression .
+ElementType = Type .
+
+ +

+The length is part of the array's type; it must evaluate to a +non-negative constant +representable by a value +of type int. +The length of array a can be discovered +using the built-in function len. +The elements can be addressed by integer indices +0 through len(a)-1. +Array types are always one-dimensional but may be composed to form +multi-dimensional types. +

+ +
+[32]byte
+[2*N] struct { x, y int32 }
+[1000]*float64
+[3][5]int
+[2][2][2]float64  // same as [2]([2]([2]float64))
+
+ +

+An array type T may not have an element of type T, +or of a type containing T as a component, directly or indirectly, +if those containing types are only array or struct types. +

+ +
+// invalid array types
+type (
+	T1 [10]T1                 // element type of T1 is T1
+	T2 [10]struct{ f T2 }     // T2 contains T2 as component of a struct
+	T3 [10]T4                 // T3 contains T3 as component of a struct in T4
+	T4 struct{ f T3 }         // T4 contains T4 as component of array T3 in a struct
+)
+
+// valid array types
+type (
+	T5 [10]*T5                // T5 contains T5 as component of a pointer
+	T6 [10]func() T6          // T6 contains T6 as component of a function type
+	T7 [10]struct{ f []T7 }   // T7 contains T7 as component of a slice in a struct
+)
+
+ +

Slice types

+ +

+A slice is a descriptor for a contiguous segment of an underlying array and +provides access to a numbered sequence of elements from that array. +A slice type denotes the set of all slices of arrays of its element type. +The number of elements is called the length of the slice and is never negative. +The value of an uninitialized slice is nil. +

+ +
+SliceType = "[" "]" ElementType .
+
+ +

+The length of a slice s can be discovered by the built-in function +len; unlike with arrays it may change during +execution. The elements can be addressed by integer indices +0 through len(s)-1. The slice index of a +given element may be less than the index of the same element in the +underlying array. +

+

+A slice, once initialized, is always associated with an underlying +array that holds its elements. A slice therefore shares storage +with its array and with other slices of the same array; by contrast, +distinct arrays always represent distinct storage. +

+

+The array underlying a slice may extend past the end of the slice. +The capacity is a measure of that extent: it is the sum of +the length of the slice and the length of the array beyond the slice; +a slice of length up to that capacity can be created by +slicing a new one from the original slice. +The capacity of a slice a can be discovered using the +built-in function cap(a). +

+ +

+A new, initialized slice value for a given element type T may be +made using the built-in function +make, +which takes a slice type +and parameters specifying the length and optionally the capacity. +A slice created with make always allocates a new, hidden array +to which the returned slice value refers. That is, executing +

+ +
+make([]T, length, capacity)
+
+ +

+produces the same slice as allocating an array and slicing +it, so these two expressions are equivalent: +

+ +
+make([]int, 50, 100)
+new([100]int)[0:50]
+
+ +

+Like arrays, slices are always one-dimensional but may be composed to construct +higher-dimensional objects. +With arrays of arrays, the inner arrays are, by construction, always the same length; +however with slices of slices (or arrays of slices), the inner lengths may vary dynamically. +Moreover, the inner slices must be initialized individually. +

+ +

Struct types

+ +

+A struct is a sequence of named elements, called fields, each of which has a +name and a type. Field names may be specified explicitly (IdentifierList) or +implicitly (EmbeddedField). +Within a struct, non-blank field names must +be unique. +

+ +
+StructType    = "struct" "{" { FieldDecl ";" } "}" .
+FieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .
+EmbeddedField = [ "*" ] TypeName [ TypeArgs ] .
+Tag           = string_lit .
+
+ +
+// An empty struct.
+struct {}
+
+// A struct with 6 fields.
+struct {
+	x, y int
+	u float32
+	_ float32  // padding
+	A *[]int
+	F func()
+}
+
+ +

+A field declared with a type but no explicit field name is called an embedded field. +An embedded field must be specified as +a type name T or as a pointer to a non-interface type name *T, +and T itself may not be +a pointer type or type parameter. The unqualified type name acts as the field name. +

+ +
+// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4
+struct {
+	T1        // field name is T1
+	*T2       // field name is T2
+	P.T3      // field name is T3
+	*P.T4     // field name is T4
+	x, y int  // field names are x and y
+}
+
+ +

+The following declaration is illegal because field names must be unique +in a struct type: +

+ +
+struct {
+	T     // conflicts with embedded field *T and *P.T
+	*T    // conflicts with embedded field T and *P.T
+	*P.T  // conflicts with embedded field T and *T
+}
+
+ +

+A field or method f of an +embedded field in a struct x is called promoted if +x.f is a legal selector that denotes +that field or method f. +

+ +

+Promoted fields act like ordinary fields of a struct. +

+ +

+Given a struct type S and a type name +T, promoted methods are included in the method set of the struct as follows: +

+
    +
  • + If S contains an embedded field T, + the method sets of S + and *S both include promoted methods with receiver + T. The method set of *S also + includes promoted methods with receiver *T. +
  • + +
  • + If S contains an embedded field *T, + the method sets of S and *S both + include promoted methods with receiver T or + *T. +
  • +
+ +

+A field declaration may be followed by an optional string literal tag, +which becomes an attribute for all the fields in the corresponding +field declaration. An empty tag string is equivalent to an absent tag. +The tags are made visible through a reflection interface +and take part in type identity for structs +but are otherwise ignored. +

+ +
+struct {
+	x, y float64 ""  // an empty tag string is like an absent tag
+	name string  "any string is permitted as a tag"
+	_    [4]byte "ceci n'est pas un champ de structure"
+}
+
+// A struct corresponding to a TimeStamp protocol buffer.
+// The tag strings define the protocol buffer field numbers;
+// they follow the convention outlined by the reflect package.
+struct {
+	microsec  uint64 `protobuf:"1"`
+	serverIP6 uint64 `protobuf:"2"`
+}
+
+ +

+A struct type T may not contain a field of type T, +or of a type containing T as a component, directly or indirectly, +if those containing types are only array or struct types. +

+ +
+// invalid struct types
+type (
+	T1 struct{ T1 }            // T1 contains a field of T1
+	T2 struct{ f [10]T2 }      // T2 contains T2 as component of an array
+	T3 struct{ T4 }            // T3 contains T3 as component of an array in struct T4
+	T4 struct{ f [10]T3 }      // T4 contains T4 as component of struct T3 in an array
+)
+
+// valid struct types
+type (
+	T5 struct{ f *T5 }         // T5 contains T5 as component of a pointer
+	T6 struct{ f func() T6 }   // T6 contains T6 as component of a function type
+	T7 struct{ f [10][]T7 }    // T7 contains T7 as component of a slice in an array
+)
+
+ +

Pointer types

+ +

+A pointer type denotes the set of all pointers to variables of a given +type, called the base type of the pointer. +The value of an uninitialized pointer is nil. +

+ +
+PointerType = "*" BaseType .
+BaseType    = Type .
+
+ +
+*Point
+*[4]int
+
+ +

Function types

+ +

+A function type denotes the set of all functions with the same parameter and result types. +The value of an uninitialized variable of function +type is nil. +

+ +
+FunctionType  = "func" Signature .
+Signature     = Parameters [ Result ] .
+Result        = Parameters | Type .
+Parameters    = "(" [ ParameterList [ "," ] ] ")" .
+ParameterList = ParameterDecl { "," ParameterDecl } .
+ParameterDecl = [ IdentifierList ] [ "..." ] Type .
+
+ +

+Within a list of parameters or results, the names (IdentifierList) +must either all be present or all be absent. If present, each name +stands for one item (parameter or result) of the specified type and +all non-blank names in the signature +must be unique. +If absent, each type stands for one item of that type. +Parameter and result +lists are always parenthesized except that if there is exactly +one unnamed result it may be written as an unparenthesized type. +

+ +

+The final incoming parameter in a function signature may have +a type prefixed with .... +A function with such a parameter is called variadic and +may be invoked with zero or more arguments for that parameter. +

+ +
+func()
+func(x int) int
+func(a, _ int, z float32) bool
+func(a, b int, z float32) (bool)
+func(prefix string, values ...int)
+func(a, b int, z float64, opt ...interface{}) (success bool)
+func(int, int, float64) (float64, *[]int)
+func(n int) func(p *T)
+
+ +

Interface types

+ +

+An interface type defines a type set. +A variable of interface type can store a value of any type that is in the type +set of the interface. Such a type is said to +implement the interface. +The value of an uninitialized variable of +interface type is nil. +

+ +
+InterfaceType  = "interface" "{" { InterfaceElem ";" } "}" .
+InterfaceElem  = MethodElem | TypeElem .
+MethodElem     = MethodName Signature .
+MethodName     = identifier .
+TypeElem       = TypeTerm { "|" TypeTerm } .
+TypeTerm       = Type | UnderlyingType .
+UnderlyingType = "~" Type .
+
+ +

+An interface type is specified by a list of interface elements. +An interface element is either a method or a type element, +where a type element is a union of one or more type terms. +A type term is either a single type or a single underlying type. +

+ +

Basic interfaces

+ +

+In its most basic form an interface specifies a (possibly empty) list of methods. +The type set defined by such an interface is the set of types which implement all of +those methods, and the corresponding method set consists +exactly of the methods specified by the interface. +Interfaces whose type sets can be defined entirely by a list of methods are called +basic interfaces. +Interface methods cannot declare type parameters, +but they may use type parameters from the interface declaration. +

+ +
+// A simple File interface.
+interface {
+	Read([]byte) (int, error)
+	Write([]byte) (int, error)
+	Close() error
+}
+
+ +

+The name of each explicitly specified method must be unique +and not blank. +

+ +
+interface {
+	String() string
+	String() string  // illegal: String not unique
+	_(x int)         // illegal: method must have non-blank name
+}
+
+ +

+More than one type may implement an interface. +For instance, if two types S1 and S2 +have the method set +

+ +
+func (p T) Read(p []byte) (n int, err error)
+func (p T) Write(p []byte) (n int, err error)
+func (p T) Close() error
+
+ +

+(where T stands for either S1 or S2) +then the File interface is implemented by both S1 and +S2, regardless of what other methods +S1 and S2 may have or share. +

+ +

+Every type that is a member of the type set of an interface implements that interface. +Any given type may implement several distinct interfaces. +For instance, all types implement the empty interface which stands for the set +of all (non-interface) types: +

+ +
+interface{}
+
+ +

+For convenience, the predeclared type any is an alias for the empty interface; +it is not a named type. +[Go 1.18] +

+ +

+Similarly, consider this interface specification, +which appears within a type declaration +to define an interface called Locker: +

+ +
+type Locker interface {
+	Lock()
+	Unlock()
+}
+
+ +

+If S1 and S2 also implement +

+ +
+func (p T) Lock() { … }
+func (p T) Unlock() { … }
+
+ +

+they implement the Locker interface as well +as the File interface. +

+ +

Embedded interfaces

+ +

+In a slightly more general form +an interface T may use a (possibly qualified) interface type +name E as an interface element. This is called +embedding interface E in T +[Go 1.14]. +The type set of T is the intersection of the type sets +defined by T's explicitly declared methods and the type sets +of T’s embedded interfaces. +In other words, the type set of T is the set of all types that implement all the +explicitly declared methods of T and also all the methods of +E +[Go 1.18]. +

+ +
+type Reader interface {
+	Read(p []byte) (n int, err error)
+	Close() error
+}
+
+type Writer interface {
+	Write(p []byte) (n int, err error)
+	Close() error
+}
+
+// ReadWriter's methods are Read, Write, and Close.
+type ReadWriter interface {
+	Reader  // includes methods of Reader in ReadWriter's method set
+	Writer  // includes methods of Writer in ReadWriter's method set
+}
+
+ +

+When embedding interfaces, methods with the +same names must +have identical signatures. +

+ +
+type ReadCloser interface {
+	Reader   // includes methods of Reader in ReadCloser's method set
+	Close()  // illegal: signatures of Reader.Close and Close are different
+}
+
+ +

General interfaces

+ +

+In their most general form, an interface element may also be an arbitrary type term +T, or a term of the form ~T specifying the underlying type T, +or a union of terms t1|t2|…|tn +[Go 1.18]. +Together with method specifications, these elements enable the precise +definition of an interface's type set as follows: +

+ +
    +
  • The type set of the empty interface is the set of all non-interface types. +
  • + +
  • The type set of a non-empty interface is the intersection of the type sets + of its interface elements. +
  • + +
  • The type set of a method specification is the set of all non-interface types + whose method sets include that method. +
  • + +
  • The type set of a non-interface type term is the set consisting + of just that type. +
  • + +
  • The type set of a term of the form ~T + is the set of all types whose underlying type is T. +
  • + +
  • The type set of a union of terms + t1|t2|…|tn + is the union of the type sets of the terms. +
  • +
+ +

+The quantification "the set of all non-interface types" refers not just to all (non-interface) +types declared in the program at hand, but all possible types in all possible programs, and +hence is infinite. +Similarly, given the set of all non-interface types that implement a particular method, the +intersection of the method sets of those types will contain exactly that method, even if all +types in the program at hand always pair that method with another method. +

+ +

+By construction, an interface's type set never contains an interface type. +

+ +
+// An interface representing only the type int.
+interface {
+	int
+}
+
+// An interface representing all types with underlying type int.
+interface {
+	~int
+}
+
+// An interface representing all types with underlying type int that implement the String method.
+interface {
+	~int
+	String() string
+}
+
+// An interface representing an empty type set: there is no type that is both an int and a string.
+interface {
+	int
+	string
+}
+
+ +

+In a term of the form ~T, the underlying type of T +must be itself, and T cannot be an interface. +

+ +
+type MyInt int
+
+interface {
+	~[]byte  // the underlying type of []byte is itself
+	~MyInt   // illegal: the underlying type of MyInt is not MyInt
+	~error   // illegal: error is an interface
+}
+
+ +

+Union elements denote unions of type sets: +

+ +
+// The Float interface represents all floating-point types
+// (including any named types whose underlying types are
+// either float32 or float64).
+type Float interface {
+	~float32 | ~float64
+}
+
+ +

+The type T in a term of the form T or ~T cannot +be a type parameter, and the type sets of all +non-interface terms must be pairwise disjoint (the pairwise intersection of the type sets must be empty). +Given a type parameter P: +

+ +
+interface {
+	P                // illegal: P is a type parameter
+	int | ~P         // illegal: P is a type parameter
+	~int | MyInt     // illegal: the type sets for ~int and MyInt are not disjoint (~int includes MyInt)
+	float32 | Float  // overlapping type sets but Float is an interface
+}
+
+ +

+Implementation restriction: +A union (with more than one term) cannot contain the +predeclared identifier comparable +or interfaces that specify methods, or embed comparable or interfaces +that specify methods. +

+ +

+Interfaces that are not basic may only be used as type +constraints, or as elements of other interfaces used as constraints. +They cannot be the types of values or variables, or components of other, +non-interface types. +

+ +
+var x Float                     // illegal: Float is not a basic interface
+
+var x interface{} = Float(nil)  // illegal
+
+type Floatish struct {
+	f Float                 // illegal
+}
+
+ +

+An interface type T may not embed a type element +that is, contains, or embeds T, directly or indirectly. +

+ +
+// illegal: Bad may not embed itself
+type Bad interface {
+	Bad
+}
+
+// illegal: Bad1 may not embed itself using Bad2
+type Bad1 interface {
+	Bad2
+}
+type Bad2 interface {
+	Bad1
+}
+
+// illegal: Bad3 may not embed a union containing Bad3
+type Bad3 interface {
+	~int | ~string | Bad3
+}
+
+// illegal: Bad4 may not embed an array containing Bad4 as element type
+type Bad4 interface {
+	[10]Bad4
+}
+
+ +

Implementing an interface

+ +

+A type T implements an interface I if +

+ +
    +
  • + T is not an interface and is an element of the type set of I; or +
  • +
  • + T is an interface and the type set of T is a subset of the + type set of I. +
  • +
+ +

+A value of type T implements an interface if T +implements the interface. +

+ +

Map types

+ +

+A map is an unordered group of elements of one type, called the +element type, indexed by a set of unique keys of another type, +called the key type. +The value of an uninitialized map is nil. +

+ +
+MapType = "map" "[" KeyType "]" ElementType .
+KeyType = Type .
+
+ +

+The comparison operators +== and != must be fully defined +for operands of the key type; thus the key type must not be a function, map, or +slice. +If the key type is an interface type, these +comparison operators must be defined for the dynamic key values; +failure will cause a run-time panic. +

+ +
+map[string]int
+map[*T]struct{ x, y float64 }
+map[string]interface{}
+
+ +

+The number of map elements is called its length. +For a map m, it can be discovered using the +built-in function len +and may change during execution. Elements may be added during execution +using assignments and retrieved with +index expressions; they may be removed with the +delete and +clear built-in function. +

+ +

+A new, empty map value is made using the built-in +function make, +which takes the map type and an optional capacity hint as arguments: +

+ +
+make(map[string]int)
+make(map[string]int, 100)
+
+ +

+The initial capacity does not bound its size: +maps grow to accommodate the number of items +stored in them, with the exception of nil maps. +A nil map is equivalent to an empty map except that no elements +may be added. +

+ +

Channel types

+ +

+A channel provides a mechanism for +concurrently executing functions +to communicate by +sending and +receiving +values of a specified element type. +The value of an uninitialized channel is nil. +

+ +
+ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
+
+ +

+The optional <- operator specifies the channel direction, +send or receive. If a direction is given, the channel is directional, +otherwise it is bidirectional. +A channel may be constrained only to send or only to receive by +assignment or +explicit conversion. +

+ +
+chan T          // can be used to send and receive values of type T
+chan<- float64  // can only be used to send float64s
+<-chan int      // can only be used to receive ints
+
+ +

+The <- operator associates with the leftmost chan +possible: +

+ +
+chan<- chan int    // same as chan<- (chan int)
+chan<- <-chan int  // same as chan<- (<-chan int)
+<-chan <-chan int  // same as <-chan (<-chan int)
+chan (<-chan int)
+
+ +

+A new, initialized channel +value can be made using the built-in function +make, +which takes the channel type and an optional capacity as arguments: +

+ +
+make(chan int, 100)
+
+ +

+The capacity, in number of elements, sets the size of the buffer in the channel. +If the capacity is zero or absent, the channel is unbuffered and communication +succeeds only when both a sender and receiver are ready. Otherwise, the channel +is buffered and communication succeeds without blocking if the buffer +is not full (sends) or not empty (receives). +A nil channel is never ready for communication. +

+ +

+A channel may be closed with the built-in function +close. +The multi-valued assignment form of the +receive operator +reports whether a received value was sent before +the channel was closed. +

+ +

+A single channel may be used in +send statements, +receive operations, +and calls to the built-in functions +cap and +len +by any number of goroutines without further synchronization. +Channels act as first-in-first-out queues. +For example, if one goroutine sends values on a channel +and a second goroutine receives them, the values are +received in the order sent. +

+ +

Properties of types and values

+ +

Representation of values

+ +

+Values of predeclared types (see below for the interfaces any +and error), arrays, and structs are self-contained: +Each such value contains a complete copy of all its data, +and variables of such types store the entire value. +For instance, an array variable provides the storage (the variables) +for all elements of the array. +The respective zero values are specific to the +value's types; they are never nil. +

+ +

+Non-nil pointer, function, slice, map, and channel values contain references +to underlying data which may be shared by multiple values: +

+ +
    +
  • + A pointer value is a reference to the variable holding + the pointer base type value. +
  • +
  • + A function value contains references to the (possibly + anonymous) function + and enclosed variables. +
  • +
  • + A slice value contains the slice length, capacity, and + a reference to its underlying array. +
  • +
  • + A map or channel value is a reference to the implementation-specific + data structure of the map or channel. +
  • +
+ +

+An interface value may be self-contained or contain references to underlying data +depending on the interface's dynamic type. +The predeclared identifier nil is the zero value for types whose values +can contain references. +

+ +

+When multiple values share underlying data, changing one value may change another. +For instance, changing an element of a slice will change +that element in the underlying array for all slices that share the array. +

+ +

Underlying types

+ +

+Each type T has an underlying type: If T +is one of the predeclared boolean, numeric, or string types, or a type literal, +the corresponding underlying type is T itself. +Otherwise, T's underlying type is the underlying type of the +type to which T refers in its declaration. +For a type parameter that is the underlying type of its +type constraint, which is always an interface. +

+ +
+type (
+	A1 = string
+	A2 = A1
+)
+
+type (
+	B1 string
+	B2 B1
+	B3 []B1
+	B4 B3
+)
+
+func f[P any](x P) { … }
+
+ +

+The underlying type of string, A1, A2, B1, +and B2 is string. +The underlying type of []B1, B3, and B4 is []B1. +The underlying type of P is interface{}. +

+ +

Type identity

+ +

+Two types are either identical ("the same") or different. +

+ +

+A named type is always different from any other type. +Otherwise, two types are identical if their underlying type literals are +structurally equivalent; that is, they have the same literal structure and corresponding +components have identical types. In detail: +

+ +
    +
  • Two array types are identical if they have identical element types and + the same array length.
  • + +
  • Two slice types are identical if they have identical element types.
  • + +
  • Two struct types are identical if they have the same sequence of fields, + and if corresponding pairs of fields have the same names, identical types, + and identical tags, and are either both embedded or both not embedded. + Non-exported field names from different + packages are always different.
  • + +
  • Two pointer types are identical if they have identical base types.
  • + +
  • Two function types are identical if they have the same number of parameters + and result values, corresponding parameter and result types are + identical, and either both functions are variadic or neither is. + Parameter and result names are not required to match.
  • + +
  • Two interface types are identical if they define the same type set. +
  • + +
  • Two map types are identical if they have identical key and element types.
  • + +
  • Two channel types are identical if they have identical element types and + the same direction.
  • + +
  • Two instantiated types are identical if + their defined types and all type arguments are identical. +
  • +
+ +

+Given the declarations +

+ +
+type (
+	A0 = []string
+	A1 = A0
+	A2 = struct{ a, b int }
+	A3 = int
+	A4 = func(A3, float64) *A0
+	A5 = func(x int, _ float64) *[]string
+
+	B0 A0
+	B1 []string
+	B2 struct{ a, b int }
+	B3 struct{ a, c int }
+	B4 func(int, float64) *B0
+	B5 func(x int, y float64) *A1
+
+	C0 = B0
+	D0[P1, P2 any] struct{ x P1; y P2 }
+	E0 = D0[int, string]
+)
+
+ +

+these types are identical: +

+ +
+A0, A1, and []string
+A2 and struct{ a, b int }
+A3 and int
+A4, func(int, float64) *[]string, and A5
+
+B0 and C0
+D0[int, string] and E0
+[]int and []int
+struct{ a, b *B5 } and struct{ a, b *B5 }
+func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
+
+ +

+B0 and B1 are different because they are new types +created by distinct type definitions; +func(int, float64) *B0 and func(x int, y float64) *[]string +are different because B0 is different from []string; +and P1 and P2 are different because they are different +type parameters. +D0[int, string] and struct{ x int; y string } are +different because the former is an instantiated +defined type while the latter is a type literal +(but they are still assignable). +

+ +

Assignability

+ +

+A value x of type V is assignable to a variable of type T +("x is assignable to T") if one of the following conditions applies: +

+ +
    +
  • +V and T are identical. +
  • +
  • +V and T have identical +underlying types +but are not type parameters and at least one of V +or T is not a named type. +
  • +
  • +V and T are channel types with +identical element types, V is a bidirectional channel, +and at least one of V or T is not a named type. +
  • +
  • +T is an interface type, but not a type parameter, and +x implements T. +
  • +
  • +x is a (possibly partially instantiated) generic function, T +is a function type, and any type arguments not provided explicitly for x +can be inferred such that (after full instantiation) +x and T have identical underlying types +[Go 1.27]. +
  • +
  • +x is the predeclared identifier nil and T +is a pointer, function, slice, map, channel, or interface type, +but not a type parameter. +
  • +
  • +x is an untyped constant +representable +by a value of type T. +
  • +
+ +

+Additionally, if x's type V or T are type parameters, x +is assignable to a variable of type T if one of the following conditions applies: +

+ +
    +
  • +x is the predeclared identifier nil, T is +a type parameter, and x is assignable to each type in +T's type set. +
  • +
  • +V is not a named type, T is +a type parameter, and x is assignable to each type in +T's type set. +
  • +
  • +V is a type parameter and T is not a named type, +and values of each type in V's type set are assignable +to T. +
  • +
+ +

Representability

+ +

+A constant x is representable +by a value of type T, +where T is not a type parameter, +if one of the following conditions applies: +

+ +
    +
  • +x is in the set of values determined by T. +
  • + +
  • +T is a floating-point type and x can be rounded to T's +precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE +negative zero further simplified to an unsigned zero. Note that constant values never result +in an IEEE negative zero, NaN, or infinity. +
  • + +
  • +T is a complex type, and x's +components real(x) and imag(x) +are representable by values of T's component type (float32 or +float64). +
  • +
+ +

+If T is a type parameter, +x is representable by a value of type T if x is representable +by a value of each type in T's type set. +

+ +
+x                   T           x is representable by a value of T because
+
+'a'                 byte        97 is in the set of byte values
+97                  rune        rune is an alias for int32, and 97 is in the set of 32-bit integers
+"foo"               string      "foo" is in the set of string values
+1024                int16       1024 is in the set of 16-bit integers
+42.0                byte        42 is in the set of unsigned 8-bit integers
+1e10                uint64      10000000000 is in the set of unsigned 64-bit integers
+2.718281828459045   float32     2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
+-1e-1000            float64     -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
+0i                  int         0 is an integer value
+(42 + 0i)           float32     42.0 (with zero imaginary part) is in the set of float32 values
+
+ +
+x                   T           x is not representable by a value of T because
+
+0                   bool        0 is not in the set of boolean values
+'a'                 string      'a' is a rune, it is not in the set of string values
+1024                byte        1024 is not in the set of unsigned 8-bit integers
+-1                  uint16      -1 is not in the set of unsigned 16-bit integers
+1.1                 int         1.1 is not an integer value
+42i                 float32     (0 + 42i) is not in the set of float32 values
+1e1000              float64     1e1000 overflows to IEEE +Inf after rounding
+
+ +

Method sets

+ +

+The method set of a type determines the methods that can be +called on an operand of that type. +Every type has a (possibly empty) method set associated with it: +

+ +
    +
  • The method set of a defined type T consists of all +methods declared with receiver type T. +
  • + +
  • +The method set of a pointer to a defined type T +(where T is neither a pointer nor an interface) +is the set of all methods declared with receiver *T or T. +
  • + +
  • The method set of an interface type is the intersection +of the method sets of each type in the interface's type set +(the resulting method set is usually just the set of declared methods in the interface). +
  • +
+ +

+Further rules apply to structs (and pointer to structs) containing embedded fields, +as described in the section on struct types. +Any other type has an empty method set. +

+ +

+In a method set, each method must have a +unique +non-blank method name. +

+ +

Blocks

+ +

+A block is a possibly empty sequence of declarations and statements +within matching brace brackets. +

+ +
+Block         = "{" StatementList "}" .
+StatementList = { Statement ";" } .
+
+ +

+In addition to explicit blocks in the source code, there are implicit blocks: +

+ +
    +
  1. The universe block encompasses all Go source text.
  2. + +
  3. Each package has a package block containing all + Go source text for that package.
  4. + +
  5. Each file has a file block containing all Go source text + in that file.
  6. + +
  7. Each "if", + "for", and + "switch" + statement is considered to be in its own implicit block.
  8. + +
  9. Each clause in a "switch" + or "select" statement + acts as an implicit block.
  10. +
+ +

+Blocks nest and influence scoping. +

+ + +

Declarations and scope

+ +

+A declaration binds a non-blank identifier to a +constant, +type, +type parameter, +variable, +function, +label, or +package. +Every identifier in a program must be declared. +No identifier may be declared twice in the same block, and +no identifier may be declared in both the file and package block. +

+ +

+The blank identifier may be used like any other identifier +in a declaration, but it does not introduce a binding and thus is not declared. +In the package block, the identifier init may only be used for +init function declarations, +and like the blank identifier it does not introduce a new binding. +

+ +
+Declaration  = ConstDecl | TypeDecl | VarDecl .
+TopLevelDecl = Declaration | FunctionDecl | MethodDecl .
+
+ +

+The scope of a declared identifier is the extent of source text in which +the identifier denotes the specified constant, type, variable, function, label, or package. +

+ +

+Go is lexically scoped using blocks: +

+ +
    +
  1. The scope of a predeclared identifier is the universe block.
  2. + +
  3. The scope of an identifier denoting a constant, type, variable, + or function (but not method) declared at top level (outside any + function) is the package block.
  4. + +
  5. The scope of the package name of an imported package is the file block + of the file containing the import declaration.
  6. + +
  7. The scope of an identifier denoting a method receiver, function parameter, + or result variable is the function body.
  8. + +
  9. The scope of an identifier denoting a type parameter of a function + or declared by a method receiver begins after the name of the function + and ends at the end of the function body.
  10. + +
  11. The scope of an identifier denoting a type parameter of a type + begins after the name of the type and ends at the end + of the TypeSpec.
  12. + +
  13. The scope of a constant or variable identifier declared + inside a function begins at the end of the ConstSpec or VarSpec + (ShortVarDecl for short variable declarations) + and ends at the end of the innermost containing block.
  14. + +
  15. The scope of a type identifier declared inside a function + begins at the identifier in the TypeSpec + and ends at the end of the innermost containing block.
  16. +
+ +

+An identifier declared in a block may be redeclared in an inner block. +While the identifier of the inner declaration is in scope, it denotes +the entity declared by the inner declaration. +

+ +

+The package clause is not a declaration; the package name +does not appear in any scope. Its purpose is to identify the files belonging +to the same package and to specify the default package name for import +declarations. +

+ + +

Label scopes

+ +

+Labels are declared by labeled statements and are +used in the "break", +"continue", and +"goto" statements. +It is illegal to define a label that is never used. +In contrast to other identifiers, labels are not block scoped and do +not conflict with identifiers that are not labels. The scope of a label +is the body of the function in which it is declared and excludes +the body of any nested function. +

+ + +

Blank identifier

+ +

+The blank identifier is represented by the underscore character _. +It serves as an anonymous placeholder instead of a regular (non-blank) +identifier and has special meaning in declarations, +as an operand, and in assignment statements. +

+ + +

Predeclared identifiers

+ +

+The following identifiers are implicitly declared in the +universe block +[Go 1.18] +[Go 1.21]: +

+
+Types:
+	any bool byte comparable
+	complex64 complex128 error float32 float64
+	int int8 int16 int32 int64 rune string
+	uint uint8 uint16 uint32 uint64 uintptr
+
+Constants:
+	true false iota
+
+Zero value:
+	nil
+
+Functions:
+	append cap clear close complex copy delete imag len
+	make max min new panic print println real recover
+
+ +

Exported identifiers

+ +

+An identifier may be exported to permit access to it from another package. +An identifier is exported if both: +

+
    +
  1. the first character of the identifier's name is a Unicode uppercase + letter (Unicode character category Lu); and
  2. +
  3. the identifier is declared in the package block + or it is a field name or + method name.
  4. +
+

+All other identifiers are not exported. +

+ +

Uniqueness of identifiers

+ +

+Given a set of identifiers, an identifier is called unique if it is +different from every other in the set. +Two identifiers are different if they are spelled differently, or if they +appear in different packages and are not +exported. Otherwise, they are the same. +

+ +

Constant declarations

+ +

+A constant declaration binds a list of identifiers (the names of +the constants) to the values of a list of constant expressions. +The number of identifiers must be equal +to the number of expressions, and the nth identifier on +the left is bound to the value of the nth expression on the +right. +

+ +
+ConstDecl      = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
+ConstSpec      = IdentifierList [ [ Type ] "=" ExpressionList ] .
+
+IdentifierList = identifier { "," identifier } .
+ExpressionList = Expression { "," Expression } .
+
+ +

+If the type is present, all constants take the type specified, and +the expressions must be assignable to that type, +which must not be a type parameter. +If the type is omitted, the constants take the +individual types of the corresponding expressions. +If the expression values are untyped constants, +the declared constants remain untyped and the constant identifiers +denote the constant values. For instance, if the expression is a +floating-point literal, the constant identifier denotes a floating-point +constant, even if the literal's fractional part is zero. +

+ +
+const Pi float64 = 3.14159265358979323846
+const zero = 0.0         // untyped floating-point constant
+const (
+	size int64 = 1024
+	eof        = -1  // untyped integer constant
+)
+const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo", untyped integer and string constants
+const u, v float32 = 0, 3    // u = 0.0, v = 3.0
+
+ +

+Within a parenthesized const declaration list the +expression list may be omitted from any but the first ConstSpec. +Such an empty list is equivalent to the textual substitution of the +first preceding non-empty expression list and its type if any. +Omitting the list of expressions is therefore equivalent to +repeating the previous list. The number of identifiers must be equal +to the number of expressions in the previous list. +Together with the iota constant generator +this mechanism permits light-weight declaration of sequential values: +

+ +
+const (
+	Sunday = iota
+	Monday
+	Tuesday
+	Wednesday
+	Thursday
+	Friday
+	Partyday
+	numberOfDays  // this constant is not exported
+)
+
+ + +

Iota

+ +

+Within a constant declaration, the predeclared identifier +iota represents successive untyped integer +constants. Its value is the index of the respective ConstSpec +in that constant declaration, starting at zero. +It can be used to construct a set of related constants: +

+ +
+const (
+	c0 = iota  // c0 == 0
+	c1 = iota  // c1 == 1
+	c2 = iota  // c2 == 2
+)
+
+const (
+	a = 1 << iota  // a == 1  (iota == 0)
+	b = 1 << iota  // b == 2  (iota == 1)
+	c = 3          // c == 3  (iota == 2, unused)
+	d = 1 << iota  // d == 8  (iota == 3)
+)
+
+const (
+	u         = iota * 42  // u == 0     (untyped integer constant)
+	v float64 = iota * 42  // v == 42.0  (float64 constant)
+	w         = iota * 42  // w == 84    (untyped integer constant)
+)
+
+const x = iota  // x == 0
+const y = iota  // y == 0
+
+ +

+By definition, multiple uses of iota in the same ConstSpec all have the same value: +

+ +
+const (
+	bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0  (iota == 0)
+	bit1, mask1                           // bit1 == 2, mask1 == 1  (iota == 1)
+	_, _                                  //                        (iota == 2, unused)
+	bit3, mask3                           // bit3 == 8, mask3 == 7  (iota == 3)
+)
+
+ +

+This last example exploits the implicit repetition +of the last non-empty expression list. +

+ + +

Type declarations

+ +

+A type declaration binds an identifier, the type name, to a type. +Type declarations come in two forms: alias declarations and type definitions. +

+ +
+TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
+TypeSpec = AliasDecl | TypeDef .
+
+ +

Alias declarations

+ +

+An alias declaration binds an identifier to the given type +[Go 1.9]. +

+ +
+AliasDecl = identifier [ TypeParameters ] "=" Type .
+
+ +

+Within the scope of +the identifier, it serves as an alias for the given type. +

+ +
+type (
+	nodeList = []*Node  // nodeList and []*Node are identical types
+	Polar    = polar    // Polar and polar denote identical types
+)
+
+ +

+If the alias declaration specifies type parameters +[Go 1.24], the type name denotes a generic alias. +Generic aliases must be instantiated when they +are used. +

+ +
+type set[P comparable] = map[P]bool
+
+ +

+In an alias declaration the given type cannot be a type parameter declared in the same declaration. +

+ +
+type A[P any] = P   // illegal: P is a type parameter declared in the declaration of A
+
+func f[P any]() {
+	type A = P  // ok: T is a type parameter declared by the enclosing function
+}
+
+ +

Type definitions

+ +

+A type definition creates a new, distinct type with the same +underlying type and operations as the given type +and binds an identifier, the type name, to it. +

+ +
+TypeDef = identifier [ TypeParameters ] Type .
+
+ +

+The new type is called a defined type. +It is different from any other type, +including the type it is created from. +

+ +
+type (
+	Point struct{ x, y float64 }  // Point and struct{ x, y float64 } are different types
+	polar Point                   // polar and Point denote different types
+)
+
+type TreeNode struct {
+	left, right *TreeNode
+	value any
+}
+
+type Block interface {
+	BlockSize() int
+	Encrypt(src, dst []byte)
+	Decrypt(src, dst []byte)
+}
+
+ +

+A defined type may have methods associated with it. +It does not inherit any methods bound to the given type, +but the method set +of an interface type or of elements of a composite type remains unchanged: +

+ +
+// A Mutex is a data type with two methods, Lock and Unlock.
+type Mutex struct         { /* Mutex fields */ }
+func (m *Mutex) Lock()    { /* Lock implementation */ }
+func (m *Mutex) Unlock()  { /* Unlock implementation */ }
+
+// NewMutex has the same composition as Mutex but its method set is empty.
+type NewMutex Mutex
+
+// The method set of PtrMutex's underlying type *Mutex remains unchanged,
+// but the method set of PtrMutex is empty.
+type PtrMutex *Mutex
+
+// The method set of *PrintableMutex contains the methods
+// Lock and Unlock bound to its embedded field Mutex.
+type PrintableMutex struct {
+	Mutex
+}
+
+// MyBlock is an interface type that has the same method set as Block.
+type MyBlock Block
+
+ +

+Type definitions may be used to define different boolean, numeric, +or string types and associate methods with them: +

+ +
+type TimeZone int
+
+const (
+	EST TimeZone = -(5 + iota)
+	CST
+	MST
+	PST
+)
+
+func (tz TimeZone) String() string {
+	return fmt.Sprintf("GMT%+dh", tz)
+}
+
+ +

+If the type definition specifies type parameters, +the type name denotes a generic type. +Generic types must be instantiated when they +are used. +

+ +
+type List[T any] struct {
+	next  *List[T]
+	value T
+}
+
+ +

+In a type definition the given type cannot be a type parameter. +

+ +
+type T[P any] P    // illegal: P is a type parameter
+
+func f[P any]() {
+	type L P   // illegal: P is a type parameter declared by the enclosing function
+}
+
+ +

+A generic type may also have methods associated with it. +In this case, the method receivers must declare the same number of type parameters as +present in the generic type definition. +

+ +
+// The method Len returns the number of elements in the linked list l.
+func (l *List[T]) Len() int  { … }
+
+ +

Type parameter declarations

+ +

+A type parameter list declares the type parameters of a generic function, method, or type declaration. +The type parameter list looks like an ordinary function parameter list +except that the type parameter names must all be present and the list is enclosed +in square brackets rather than parentheses +[Go 1.18, Go 1.27]. +

+ +
+TypeParameters = "[" TypeParamList [ "," ] "]" .
+TypeParamList  = TypeParamDecl { "," TypeParamDecl } .
+TypeParamDecl  = IdentifierList TypeConstraint .
+
+ +

+All non-blank names in the list must be unique. +Each name declares a type parameter, which is a new and different named type +that acts as a placeholder for an (as of yet) unknown type in the declaration. +The type parameter is replaced with a type argument upon +instantiation of the generic function, method, or type. +

+ +
+[P any]
+[S interface{ ~[]byte|string }]
+[S ~[]E, E any]
+[P Constraint[int]]
+[_ any]
+
+ +

+Just as each ordinary function parameter has a parameter type, each type parameter +has a corresponding (meta-)type which is called its +type constraint. +

+ +

+A parsing ambiguity arises when the type parameter list for a generic type +declares a single type parameter P with a constraint C +such that the text P C forms a valid expression: +

+ +
+type T[P *C] …
+type T[P (C)] …
+type T[P *C|Q] …
+…
+
+ +

+In these rare cases, the type parameter list is indistinguishable from an +expression and the type declaration is parsed as an array type declaration. +To resolve the ambiguity, embed the constraint in an +interface or use a trailing comma: +

+ +
+type T[P interface{*C}] …
+type T[P *C,] …
+
+ +

+Type parameters may also be declared by the receiver specification +of a method declaration associated +with a generic type. +

+ +

Type constraints

+ +

+A type constraint is an interface that defines the +set of permissible type arguments for the respective type parameter and controls the +operations supported by values of that type parameter +[Go 1.18]. +

+ +
+TypeConstraint = TypeElem .
+
+ +

+If the constraint is an interface literal of the form interface{E} where +E is an embedded type element (not a method), in a type parameter list +the enclosing interface{ … } may be omitted for convenience: +

+ +
+[T []P]                      // = [T interface{[]P}]
+[T ~int]                     // = [T interface{~int}]
+[T int|string]               // = [T interface{int|string}]
+type Constraint ~int         // illegal: ~int is not in a type parameter list
+
+ + + +

+The predeclared +interface type comparable +denotes the set of all non-interface types that are +strictly comparable +[Go 1.18]. +

+ +

+Even though interfaces that are not type parameters are comparable, +they are not strictly comparable and therefore they do not implement comparable. +However, they satisfy comparable. +

+ +
+int                          // implements comparable (int is strictly comparable)
+[]byte                       // does not implement comparable (slices cannot be compared)
+interface{}                  // does not implement comparable (see above)
+interface{ ~int | ~string }  // type parameter only: implements comparable (int, string types are strictly comparable)
+interface{ comparable }      // type parameter only: implements comparable (comparable implements itself)
+interface{ ~int | ~[]byte }  // type parameter only: does not implement comparable (slices are not comparable)
+interface{ ~struct{ any } }  // type parameter only: does not implement comparable (field any is not strictly comparable)
+
+ +

+The comparable interface and interfaces that (directly or indirectly) embed +comparable may only be used as type constraints. They cannot be the types of +values or variables, or components of other, non-interface types. +

+ +

Satisfying a type constraint

+ +

+A type argument T satisfies a type constraint C +if T is an element of the type set defined by C; in other words, +if T implements C. +As an exception, a strictly comparable +type constraint may also be satisfied by a comparable +(not necessarily strictly comparable) type argument +[Go 1.20]. +More precisely: +

+ +

+A type T satisfies a constraint C if +

+ + + +
+type argument      type constraint                // constraint satisfaction
+
+int                interface{ ~int }              // satisfied: int implements interface{ ~int }
+string             comparable                     // satisfied: string implements comparable (string is strictly comparable)
+[]byte             comparable                     // not satisfied: slices are not comparable
+any                interface{ comparable; int }   // not satisfied: any does not implement interface{ int }
+any                comparable                     // satisfied: any is comparable and implements the basic interface any
+struct{f any}      comparable                     // satisfied: struct{f any} is comparable and implements the basic interface any
+any                interface{ comparable; m() }   // not satisfied: any does not implement the basic interface interface{ m() }
+interface{ m() }   interface{ comparable; m() }   // satisfied: interface{ m() } is comparable and implements the basic interface interface{ m() }
+
+ +

+Because of the exception in the constraint satisfaction rule, comparing operands of type parameter type +may panic at run-time (even though comparable type parameters are always strictly comparable). +

+ +

Variable declarations

+ +

+A variable declaration creates one or more variables, +binds corresponding identifiers to them, and gives each a type and an initial value. +

+ +
+VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
+VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
+
+ +
+var i int
+var U, V, W float64
+var k = 0
+var x, y float32 = -1, -2
+var (
+	i       int
+	u, v, s = 2.0, 3.0, "bar"
+)
+var re, im = complexSqrt(-1)
+var _, found = entries[name]  // map lookup; only interested in "found"
+
+ +

+If a list of expressions is given, the variables are initialized +with the expressions following the rules for assignment statements. +Otherwise, each variable is initialized to its zero value. +

+ +

+If a type is present, each variable is given that type. +Otherwise, each variable is given the type of the corresponding +initialization value in the assignment. +If that value is an untyped constant, it is first implicitly +converted to its default type; +if it is an untyped boolean value, it is first implicitly converted to type bool. +The predeclared identifier nil cannot be used to initialize a variable +with no explicit type. +

+ +
+var d = math.Sin(0.5)  // d is float64
+var i = 42             // i is int
+var t, ok = x.(T)      // t is T, ok is bool
+var n = nil            // illegal
+
+ +

+Implementation restriction: A compiler may make it illegal to declare a variable +inside a function body if the variable is +never used. +

+ +

Short variable declarations

+ +

+A short variable declaration uses the syntax: +

+ +
+ShortVarDecl = IdentifierList ":=" ExpressionList .
+
+ +

+It is shorthand for a regular variable declaration +with initializer expressions but no types: +

+ +
+"var" IdentifierList "=" ExpressionList .
+
+ +
+i, j := 0, 10
+f := func() int { return 7 }
+ch := make(chan int)
+r, w, _ := os.Pipe()  // os.Pipe() returns a connected pair of Files and an error, if any
+_, y, _ := coord(p)   // coord() returns three values; only interested in y coordinate
+
+ +

+Unlike regular variable declarations, a short variable declaration may redeclare +variables provided they were originally declared earlier in the same block +(or the parameter lists if the block is the function body) with the same type, +and at least one of the non-blank variables is new. +As a consequence, redeclaration can only appear in a multi-variable short declaration. +Redeclaration does not introduce a new variable; it just assigns a new value to the original. +The non-blank variable names on the left side of := +must be unique. +

+ +
+field1, offset := nextField(str, 0)
+field2, offset := nextField(str, offset)  // redeclares offset
+x, y, x := 1, 2, 3                        // illegal: x repeated on left side of :=
+
+ +

+Short variable declarations may appear only inside functions. +In some contexts such as the initializers for +"if", +"for", or +"switch" statements, +they can be used to declare local temporary variables. +

+ +

Function declarations

+ + + +

+A function declaration binds an identifier, the function name, +to a function. +

+ +
+FunctionDecl = "func" FunctionName [ TypeParameters ] Signature [ FunctionBody ] .
+FunctionName = identifier .
+FunctionBody = Block .
+
+ +

+If the function's signature declares +result parameters, the function body's statement list must end in +a terminating statement. +

+ +
+func IndexRune(s string, r rune) int {
+	for i, c := range s {
+		if c == r {
+			return i
+		}
+	}
+	// invalid: missing return statement
+}
+
+ +

+If the function declaration specifies type parameters, +the function name denotes a generic function [Go 1.18]. +A generic function must be instantiated before it can be +called or used as a value. +

+ +
+func min[T ~int|~float64](x, y T) T {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+ +

+A function declaration without type parameters may omit the body. +Such a declaration provides the signature for a function implemented outside Go, +such as an assembly routine. +

+ +
+func flushICache(begin, end uintptr)  // implemented externally
+
+ +

Method declarations

+ +

+A method is a function with a receiver. +A method declaration binds an identifier, the method name, to a method, +and associates the method with the receiver's base type. +

+ +
+MethodDecl = "func" Receiver MethodName [ TypeParameters ] Signature [ FunctionBody ] .
+Receiver   = Parameters .
+
+ +

+The receiver is specified via an extra parameter section preceding the method +name. That parameter section must declare a single non-variadic parameter, the receiver. +Its type must be a defined type T or a +pointer to a defined type T, possibly followed by a list of type parameter +names [P1, P2, …] enclosed in square brackets. +T is called the receiver base type. A receiver base type cannot be +a pointer or interface type and it must be declared in the same package as the method. +The method is said to be bound to its receiver base type and the method name +is visible only within selectors for type T +or *T. +

+ +

+A non-blank receiver identifier must be +unique in the method signature. +If the receiver's value is not referenced inside the body of the method, +its identifier may be omitted in the declaration. The same applies in +general to parameters of functions and methods. +

+ +

+For a base type, the non-blank names of methods bound to it must be unique. +If the base type is a struct type, +the non-blank method and field names must be distinct. +

+ +

+Given defined type Point the declarations +

+ +
+func (p *Point) Length() float64 {
+	return math.Sqrt(p.x * p.x + p.y * p.y)
+}
+
+func (p *Point) Scale(factor float64) {
+	p.x *= factor
+	p.y *= factor
+}
+
+ +

+bind the methods Length and Scale, +with receiver type *Point, +to the base type Point. +

+ +

+If the receiver base type is a generic type, the +receiver specification must declare corresponding type parameters for the method +to use. This makes the receiver type parameters available to the method. +Syntactically, this type parameter declaration looks like an +instantiation of the receiver base type: the type +arguments must be identifiers denoting the type parameters being declared, one +for each type parameter of the receiver base type. +The type parameter names do not need to match their corresponding parameter names in the +receiver base type definition, and all non-blank parameter names must be unique in the +receiver parameter section and the method signature. +The receiver type parameter constraints are implied by the receiver base type definition: +corresponding type parameters have corresponding constraints. +

+ +
+type Pair[A, B any] struct {
+	a A
+	b B
+}
+
+func (p Pair[A, B]) Swap() Pair[B, A]  { … }  // receiver declares A, B
+func (p Pair[First, _]) First() First  { … }  // receiver declares First, corresponds to A in Pair
+
+ +

+If the receiver type is denoted by (a pointer to) an alias, +the alias must not be generic and it must not denote an instantiated generic type, neither +directly nor indirectly via another alias, and irrespective of pointer indirections. +

+ +
+type GPoint[P any] = Point
+type HPoint        = *GPoint[int]
+type IPair         = Pair[int, int]
+
+func (*GPoint[P]) Draw(P)   { … }  // illegal: alias must not be generic
+func (HPoint) Draw(P)       { … }  // illegal: alias must not denote instantiated type GPoint[int]
+func (*IPair) Second() int  { … }  // illegal: alias must not denote instantiated type Pair[int, int]
+
+ +

+If the method declaration specifies type parameters +(possibly in addition to type parameters declared by the receiver specification), the method name denotes +a generic method [Go 1.27]. +Like a generic function, a generic method must be instantiated before it can +be called or used as a value. +

+ +
+type List[E any] []E
+
+// Apply returns the list obtained from applying f to each element of l.
+func (l List[E]) Apply[F any](f func(E) F) List[F] {
+	r := make(List[F], len(l))
+	for i, x := range l {
+		r[i] = f(x)
+	}
+	return r
+}
+
+ +

Expressions

+ +

+An expression specifies the computation of a value by applying +operators and functions to operands. +

+ +

Operands

+ +

+Operands denote the elementary values in an expression. An operand may be a +literal, a (possibly qualified) +non-blank identifier denoting a +constant, +variable, or +function, +or a parenthesized expression. +

+ +
+Operand     = Literal | OperandName [ TypeArgs ] | "(" Expression ")" .
+Literal     = BasicLit | CompositeLit | FunctionLit .
+BasicLit    = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
+OperandName = identifier | QualifiedIdent .
+
+ +

+An operand name denoting a generic function +may be followed by a list of type arguments; the +resulting operand is an instantiated function. +

+ +

+The blank identifier may appear as an +operand only on the left-hand side of an assignment statement. +

+ +

+Implementation restriction: A compiler need not report an error if an operand's +type is a type parameter with an empty +type set. Functions with such type parameters +cannot be instantiated; any attempt will lead +to an error at the instantiation site. +

+ +

Qualified identifiers

+ +

+A qualified identifier is an identifier qualified with a package name prefix. +Both the package name and the identifier must not be +blank. +

+ +
+QualifiedIdent = PackageName "." identifier .
+
+ +

+A qualified identifier accesses an identifier in a different package, which +must be imported. +The identifier must be exported and +declared in the package block of that package. +

+ +
+math.Sin // denotes the Sin function in package math
+
+ +

Composite literals

+ +

+Composite literals construct new values for structs, arrays, slices, and maps +each time they are evaluated. +They consist of the type of the literal followed by a (possibly empty) +brace-bound list of elements. +Each element may optionally be preceded by a corresponding key. +

+ +
+CompositeLit = LiteralType LiteralValue .
+LiteralType  = StructType | ArrayType | "[" "..." "]" ElementType |
+               SliceType | MapType | TypeName [ TypeArgs ] .
+LiteralValue = "{" [ ElementList [ "," ] ] "}" .
+ElementList  = KeyedElement { "," KeyedElement } .
+KeyedElement = [ Key ":" ] Element .
+Key          = FieldName | Expression | LiteralValue .
+FieldName    = identifier .
+Element      = Expression | LiteralValue .
+
+ +

+Unless the LiteralType is a type parameter, +its underlying type +must be a struct, array, slice, or map type +(the syntax enforces this constraint except when the type is given +as a TypeName). +If the LiteralType is a type parameter, all types in its type set +must have the same underlying type which must be +a valid composite literal type. +

+ +

+The types of the elements and keys must be assignable +to the respective field, element, and key types of the LiteralType; +there is no additional conversion. +The key is interpreted as a field selector for struct literals, +an index for array and slice literals, and a key for map literals. +It is an error to specify multiple elements with the same field selector +or constant key value. +A literal may omit the element list; such a literal evaluates +to the zero value for its type. +

+ +

+A parsing ambiguity arises when a composite literal using the +TypeName form of the LiteralType appears as an operand between the +keyword and the opening brace of the block +of an "if", "for", or "switch" statement, and the composite literal +is not enclosed in parentheses, square brackets, or curly braces. +In this rare case, the opening brace of the literal is erroneously parsed +as the one introducing the block of statements. To resolve the ambiguity, +the composite literal must appear within parentheses. +

+ +
+if x == (T{a,b,c}[i]) { … }
+if (x == T{a,b,c}[i]) { … }
+
+ +

Struct literals

+ +

+For struct literals without keys, the element list must contain an element +for each struct field in the order in which the fields are declared. +

+ +

+For struct literals with keys the following rules apply: +

+
    +
  • Every element must have a key. +
  • +
  • Each key must be a valid field selector + [Go 1.27] for a (possibly promoted) field + of the struct; the key selects that field. +
  • +
  • The types of the embedded fields (if any) traversed + to reach a selected field must not be pointer types. +
  • +
  • A key must not denote a promoted field inside an embedded struct if + that struct is also specified by another key. +
  • +
  • The element list does not need to have an element for each struct field. + Omitted fields get the zero value for that field. +
  • +
+ +

+Given the declarations +

+
+type Object  struct { name, color string }
+type Point3D struct { Object; x, y, z float64 }
+type Line    struct { Object; p, q Point3D }
+
+ +

+one may write +

+ +
+origin := Point3D{}                                       // zero value for Point3D
+line1 := Line{Object{}, origin, Point3D{y: -4, z: 12.3}}  // zero value for line1.q.x
+line2 := Line{name: "diagonal", q: Point3D{1, 1, 1}}      // zero value for line2.Object.color, line2.p
+
+ +

+but field selectors may not denote overlapping fields: +

+ +
+obj   := Object{"edge", "black"}
+line3 := Line{Object: obj, name: "diagonal"}              // invalid: name denotes a field inside Object
+
+ +

Array and slice literals

+ +

+For array and slice literals the following rules apply: +

+
    +
  • Each element has an associated integer index marking + its position in the array. +
  • +
  • An element with a key uses the key as its index. The + key must be a non-negative constant + representable by + a value of type int; and if it is typed + it must be of integer type. +
  • +
  • An element without a key uses the previous element's index plus one. + If the first element has no key, its index is zero. +
  • +
+ +

+Taking the address of a composite literal +generates a pointer to a unique variable initialized +with the literal's value. +

+ +
+var pointer *Point3D = &Point3D{y: 1000}
+
+ +

+Note that the zero value for a slice or map +type is not the same as an initialized but empty value of the same type. +Consequently, taking the address of an empty slice or map composite literal +does not have the same effect as allocating a new slice or map value with +new. +

+ +
+p1 := &[]int{}    // p1 points to an initialized, empty slice with value []int{} and length 0
+p2 := new([]int)  // p2 points to an uninitialized slice with value nil and length 0
+
+ +

+The length of an array literal is the length specified in the literal type. +If fewer elements than the length are provided in the literal, the missing +elements are set to the zero value for the array element type. +It is an error to provide elements with index values outside the index range +of the array. The notation ... specifies an array length equal +to the maximum element index plus one. +

+ +
+buffer := [10]string{}             // len(buffer) == 10
+intSet := [6]int{1, 2, 3, 5}       // len(intSet) == 6
+days := [...]string{"Sat", "Sun"}  // len(days) == 2
+
+ +

+A slice literal describes the entire underlying array literal. +Thus the length and capacity of a slice literal are the maximum +element index plus one. A slice literal has the form +

+ +
+[]T{x1, x2, … xn}
+
+ +

+and is shorthand for a slice operation applied to an array: +

+ +
+tmp := [n]T{x1, x2, … xn}
+tmp[0 : n]
+
+ +

Map literals

+ +

+For map literals, each element must have a key. +For non-constant map keys, see the section on +evaluation order. +

+ +

Elision of element types

+ +

+Within a composite literal of array, slice, or map type T, +elements or map keys that are themselves composite literals may elide the respective +literal type if it is identical to the element or key type of T. +Similarly, elements or keys that are addresses of composite literals may elide +the &T when the element or key type is *T. +

+ +
+[...]Point{{1.5, -3.5}, {0, 0}}     // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}
+[][]int{{1, 2, 3}, {4, 5}}          // same as [][]int{[]int{1, 2, 3}, []int{4, 5}}
+[][]Point{{{0, 1}, {1, 2}}}         // same as [][]Point{[]Point{Point{0, 1}, Point{1, 2}}}
+map[string]Point{"orig": {0, 0}}    // same as map[string]Point{"orig": Point{0, 0}}
+map[Point]string{{0, 0}: "orig"}    // same as map[Point]string{Point{0, 0}: "orig"}
+
+type PPoint *Point
+[2]*Point{{1.5, -3.5}, {}}          // same as [2]*Point{&Point{1.5, -3.5}, &Point{}}
+[2]PPoint{{1.5, -3.5}, {}}          // same as [2]PPoint{PPoint(&Point{1.5, -3.5}), PPoint(&Point{})}
+
+ +

+Examples of valid array, slice, and map literals: +

+ +
+// list of prime numbers
+primes := []int{2, 3, 5, 7, 9, 2147483647}
+
+// vowels[ch] is true if ch is a vowel
+vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}
+
+// the array [10]float32{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1}
+filter := [10]float32{-1, 4: -0.1, -0.1, 9: -1}
+
+// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
+noteFrequency := map[string]float32{
+	"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
+	"G0": 24.50, "A0": 27.50, "B0": 30.87,
+}
+
+ +

Function literals

+ +

+A function literal represents an anonymous function. +Function literals cannot declare type parameters. +

+ +
+FunctionLit = "func" Signature FunctionBody .
+
+ +
+func(a, b int, z float64) bool { return a*b < int(z) }
+
+ +

+A function literal can be assigned to a variable or invoked directly. +

+ +
+f := func(x, y int) int { return x + y }
+func(ch chan int) { ch <- ACK }(replyChan)
+
+ +

+Function literals are closures: they may refer to variables +declared in a surrounding function. Those variables are then shared between +the surrounding function and the function literal, and they survive as long +as they are accessible. +

+ + +

Primary expressions

+ +

+Primary expressions are the operands for unary and binary expressions. +

+ +
+PrimaryExpr   = Operand |
+                Conversion |
+                MethodExpr |
+                PrimaryExpr Selector |
+                PrimaryExpr Index |
+                PrimaryExpr Slice |
+                PrimaryExpr TypeAssertion |
+                PrimaryExpr Arguments .
+
+Selector      = "." identifier .
+Index         = "[" Expression [ "," ] "]" .
+Slice         = "[" [ Expression ] ":" [ Expression ] "]" |
+                "[" [ Expression ] ":" Expression ":" Expression "]" .
+TypeAssertion = "." "(" Type ")" .
+Arguments     = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
+
+ + +
+x
+2
+(s + ".txt")
+f(3.1415, true)
+Point{1, 2}
+m["foo"]
+s[i : j + 1]
+obj.color
+f.p[i].x()
+
+ + +

Selectors

+ +

+For a primary expression x +that is not a package name, the +selector expression +

+ +
+x.f
+
+ +

+denotes the field or method f of the value x +(or sometimes *x; see below). +The identifier f is called the (field or method) selector; +it must not be the blank identifier. +The type of the selector expression is the type of f. +If x is a package name, see the section on +qualified identifiers. +

+ +

+A selector f may denote a field or method f of +a type T, or it may refer +to a field or method f of a nested +embedded field of T. +The number of embedded fields traversed +to reach f is called its depth in T. +The depth of a field or method f +declared in T is zero. +The depth of a field or method f declared in +an embedded field A in T is the +depth of f in A plus one. +

+ +

+The following rules apply to selectors: +

+ +
    +
  1. +For a value x of type T or *T +where T is not a pointer or interface type, +x.f denotes the field or method at the shallowest depth +in T where there is such an f. +If there is not exactly one f +with shallowest depth, the selector expression is illegal. +
  2. + +
  3. +For a value x of type I where I +is an interface type, x.f denotes the actual method with name +f of the dynamic value of x. +If there is no method with name f in the +method set of I, the selector +expression is illegal. +
  4. + +
  5. +As an exception, if the type of x is a defined +pointer type and (*x).f is a valid selector expression denoting a field +(but not a method), x.f is shorthand for (*x).f. +
  6. + +
  7. +In all other cases, x.f is illegal. +
  8. + +
  9. +If x is of pointer type and has the value +nil and x.f denotes a struct field, +assigning to or evaluating x.f +causes a run-time panic. +
  10. + +
  11. +If x is of interface type and has the value +nil, calling or +evaluating the method x.f +causes a run-time panic. +
  12. +
+ +

+For example, given the declarations: +

+ +
+type T0 struct {
+	x int
+}
+
+func (*T0) M0()
+
+type T1 struct {
+	y int
+}
+
+func (T1) M1()
+
+type T2 struct {
+	z int
+	T1
+	*T0
+}
+
+func (*T2) M2()
+
+type Q *T2
+
+var t T2     // with t.T0 != nil
+var p *T2    // with p != nil and (*p).T0 != nil
+var q Q = p
+
+ +

+one may write: +

+ +
+t.z          // t.z
+t.y          // t.T1.y
+t.x          // (*t.T0).x
+
+p.z          // (*p).z
+p.y          // (*p).T1.y
+p.x          // (*(*p).T0).x
+
+q.x          // (*(*q).T0).x        (*q).x is a valid field selector
+
+p.M0()       // ((*p).T0).M0()      M0 expects *T0 receiver
+p.M1()       // ((*p).T1).M1()      M1 expects T1 receiver
+p.M2()       // p.M2()              M2 expects *T2 receiver
+t.M2()       // (&t).M2()           M2 expects *T2 receiver, see section on Calls
+
+ +

+but the following is invalid: +

+ +
+q.M0()       // (*q).M0 is valid but not a field selector
+
+ + +

Method expressions

+ +

+If M is in the method set of type T, +T.M is a function that is callable as a regular function +with the same arguments as M prefixed by an additional +argument that is the receiver of the method. +

+ +
+MethodExpr   = ReceiverType "." MethodName .
+ReceiverType = Type .
+
+ +

+Consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+
+ +

+The expression +

+ +
+T.Mv
+
+ +

+yields a function equivalent to Mv but +with an explicit receiver as its first argument; it has signature +

+ +
+func(tv T, a int) int
+
+ +

+That function may be called normally with an explicit receiver, so +these five invocations are equivalent: +

+ +
+t.Mv(7)
+T.Mv(t, 7)
+(T).Mv(t, 7)
+f1 := T.Mv; f1(t, 7)
+f2 := (T).Mv; f2(t, 7)
+
+ +

+Similarly, the expression +

+ +
+(*T).Mp
+
+ +

+yields a function value representing Mp with signature +

+ +
+func(tp *T, f float32) float32
+
+ +

+For a method with a value receiver, one can derive a function +with an explicit pointer receiver, so +

+ +
+(*T).Mv
+
+ +

+yields a function value representing Mv with signature +

+ +
+func(tv *T, a int) int
+
+ +

+Such a function indirects through the receiver to create a value +to pass as the receiver to the underlying method; +the method does not overwrite the value whose address is passed in +the function call. +

+ +

+The final case, a value-receiver function for a pointer-receiver method, +is illegal because pointer-receiver methods are not in the method set +of the value type. +

+ +

+Function values derived from methods are called with function call syntax; +the receiver is provided as the first argument to the call. +That is, given f := T.Mv, f is invoked +as f(t, 7) not t.f(7). +To construct a function that binds the receiver, use a +function literal or +method value. +

+ +

+It is legal to derive a function value from a method of an interface type. +The resulting function takes an explicit receiver of that interface type. +

+ +

Method values

+ +

+If the expression x has static type T and +M is in the method set of type T, +x.M is called a method value. +The method value x.M is a function value that is callable +with the same arguments as a method call of x.M. +The expression x is evaluated and saved during the evaluation of the +method value; the saved copy is then used as the receiver in any calls, +which may be executed later. +

+ +
+type S struct { *T }
+type T int
+func (t T) M() { print(t) }
+
+t := new(T)
+s := S{T: t}
+f := t.M                    // receiver *t is evaluated and stored in f
+g := s.M                    // receiver *(s.T) is evaluated and stored in g
+*t = 42                     // does not affect stored receivers in f and g
+
+ +

+The type T may be an interface or non-interface type. +

+ +

+As in the discussion of method expressions above, +consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+var pt *T
+func makeT() T
+
+ +

+The expression +

+ +
+t.Mv
+
+ +

+yields a function value of type +

+ +
+func(int) int
+
+ +

+These two invocations are equivalent: +

+ +
+t.Mv(7)
+f := t.Mv; f(7)
+
+ +

+Similarly, the expression +

+ +
+pt.Mp
+
+ +

+yields a function value of type +

+ +
+func(float32) float32
+
+ +

+As with selectors, a reference to a non-interface method with a value receiver +using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv. +

+ +

+As with method calls, a reference to a non-interface method with a pointer receiver +using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp. +

+ +
+f := t.Mv; f(7)   // like t.Mv(7)
+f := pt.Mp; f(7)  // like pt.Mp(7)
+f := pt.Mv; f(7)  // like (*pt).Mv(7)
+f := t.Mp; f(7)   // like (&t).Mp(7)
+f := makeT().Mp   // invalid: result of makeT() is not addressable
+
+ +

+Although the examples above use non-interface types, it is also legal to create a method value +from a value of interface type. +

+ +
+var i interface { M(int) } = myVal
+f := i.M; f(7)  // like i.M(7)
+
+ + +

Index expressions

+ +

+A primary expression of the form +

+ +
+a[x]
+
+ +

+denotes the element of the array, pointer to array, slice, string or map a indexed by x. +The value x is called the index or map key, respectively. +The following rules apply: +

+ +

+If a is neither a map nor a type parameter: +

+
    +
  • the index x must be an untyped constant, or its type must be + an integer or a type parameter whose type set + contains only integer types
  • +
  • a constant index must be non-negative and + representable by a value of type int
  • +
  • a constant index that is untyped is given type int
  • +
  • the index x is in range if 0 <= x < len(a), + otherwise it is out of range
  • +
+ +

+For a of array type A: +

+
    +
  • a constant index must be in range
  • +
  • if x is out of range at run time, + a run-time panic occurs
  • +
  • a[x] is the array element at index x and the type of + a[x] is the element type of A
  • +
+ +

+For a of pointer to array type: +

+
    +
  • a[x] is shorthand for (*a)[x]
  • +
+ +

+For a of slice type S: +

+
    +
  • if x is out of range at run time, + a run-time panic occurs
  • +
  • a[x] is the slice element at index x and the type of + a[x] is the element type of S
  • +
+ +

+For a of string type: +

+
    +
  • a constant index must be in range + if the string a is also constant
  • +
  • if x is out of range at run time, + a run-time panic occurs
  • +
  • a[x] is the non-constant byte value at index x and the type of + a[x] is byte
  • +
  • a[x] may not be assigned to
  • +
+ +

+For a of map type M: +

+
    +
  • x's type must be + assignable + to the key type of M
  • +
  • if the map contains an entry with key x, + a[x] is the map element with key x + and the type of a[x] is the element type of M
  • +
  • if the map is nil or does not contain such an entry, + a[x] is the zero value + for the element type of M
  • +
+ +

+For a of type parameter type P: +

+
    +
  • The index expression a[x] must be valid for values + of all types in P's type set.
  • +
  • The element types of all types in P's type set must be identical. + In this context, the element type of a string type is byte.
  • +
  • If there is a map type in the type set of P, + all types in that type set must be map types, and the respective key types + must be all identical.
  • +
  • a[x] is the array, slice, or string element at index x, + or the map element with key x of the type argument + that P is instantiated with, and the type of a[x] is + the type of the (identical) element types.
  • +
  • a[x] may not be assigned to if P's type set + includes string types.
  • +
+ +

+Otherwise a[x] is illegal. +

+ +

+An index expression on a map a of type map[K]V +used in an assignment statement or initialization of the special form +

+ +
+v, ok = a[x]
+v, ok := a[x]
+var v, ok = a[x]
+
+ +

+yields an additional untyped boolean value. The value of ok is +true if the key x is present in the map, and +false otherwise. +

+ +

+Assigning to an element of a nil map causes a +run-time panic. +

+ + +

Slice expressions

+ +

+Slice expressions construct a substring or slice from a string, array, pointer +to array, or slice operand. +There are two variants: a simple form that specifies a low +and high bound, and a full form that also specifies a bound on the capacity. +

+ +

+If the operand type is a type parameter, +unless its type set contains string types, +all types in the type set must have the same underlying type, and the slice expression +must be valid for an operand of that type. +If the type set contains string types it may also contain byte slices with underlying +type []byte. +In this case, the slice expression must be valid for an operand of string +type. +

+ +

Simple slice expressions

+ +

+For a string, array, pointer to array, or slice a, the primary expression +

+ +
+a[low : high]
+
+ +

+constructs a substring or slice. +The indices low and +high select which elements of operand a appear +in the result. The result has indices starting at 0 and length equal to +high - low. +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+s := a[1:4]
+
+ +

+the slice s has type []int, length 3, capacity 4, and elements +

+ +
+s[0] == 2
+s[1] == 3
+s[2] == 4
+
+ +

+For convenience, any of the indices may be omitted. A missing low +index defaults to zero; a missing high index defaults to the length of the +sliced operand: +

+ +
+a[2:]  // same as a[2 : len(a)]
+a[:3]  // same as a[0 : 3]
+a[:]   // same as a[0 : len(a)]
+
+ +

+If a is a pointer to an array, a[low : high] is shorthand for +(*a)[low : high]. +

+ +

+For arrays or strings, the indices are in range if +0 <= low <= high <= len(a), +otherwise they are out of range. +For slices, the upper index bound is the slice capacity cap(a) rather than the length. +A constant index must be non-negative and +representable by a value of type +int; for arrays or constant strings, constant indices must also be in range. +If both indices are constant, they must satisfy low <= high. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

+Except for untyped strings, if the sliced operand is a string or slice, +the result of the slice operation is a non-constant value of the same type as the operand. +For untyped string operands the result is a non-constant value of type string. +If the sliced operand is an array, it must be addressable +and the result of the slice operation is a slice with the same element type as the array. +

+ +

+If the sliced operand of a valid slice expression is a nil slice, the result +is a nil slice. Otherwise, if the result is a slice, it shares its underlying +array with the operand. +

+ +
+var a [10]int
+s1 := a[3:7]   // underlying array of s1 is array a; &s1[2] == &a[5]
+s2 := s1[1:4]  // underlying array of s2 is underlying array of s1 which is array a; &s2[1] == &a[5]
+s2[1] = 42     // s2[1] == s1[2] == a[5] == 42; they all refer to the same underlying array element
+
+var s []int
+s3 := s[:0]    // s3 == nil
+
+ + +

Full slice expressions

+ +

+For an array, pointer to array, or slice a (but not a string), the primary expression +

+ +
+a[low : high : max]
+
+ +

+constructs a slice of the same type, and with the same length and elements as the simple slice +expression a[low : high]. Additionally, it controls the resulting slice's capacity +by setting it to max - low. Only the first index may be omitted; it defaults to 0. +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+t := a[1:3:5]
+
+ +

+the slice t has type []int, length 2, capacity 4, and elements +

+ +
+t[0] == 2
+t[1] == 3
+
+ +

+As for simple slice expressions, if a is a pointer to an array, +a[low : high : max] is shorthand for (*a)[low : high : max]. +If the sliced operand is an array, it must be addressable. +

+ +

+The indices are in range if 0 <= low <= high <= max <= cap(a), +otherwise they are out of range. +A constant index must be non-negative and +representable by a value of type +int; for arrays, constant indices must also be in range. +If multiple indices are constant, the constants that are present must be in range relative to each +other. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

Type assertions

+ +

+For an expression x of interface type, +but not a type parameter, and a type T, +the primary expression +

+ +
+x.(T)
+
+ +

+asserts that x is not nil +and that the value stored in x is of type T. +The notation x.(T) is called a type assertion. +

+

+More precisely, if T is not an interface type, x.(T) asserts +that the dynamic type of x is identical +to the type T. +In this case, T must implement the (interface) type of x; +otherwise the type assertion is invalid since it is not possible for x +to store a value of type T. +If T is an interface type, x.(T) asserts that the dynamic type +of x implements the interface T. +

+

+If the type assertion holds, the value of the expression is the value +stored in x and its type is T. If the type assertion is false, +a run-time panic occurs. +In other words, even though the dynamic type of x +is known only at run time, the type of x.(T) is +known to be T in a correct program. +

+ +
+var x interface{} = 7          // x has dynamic type int and value 7
+i := x.(int)                   // i has type int and value 7
+
+type I interface { m() }
+
+func f(y I) {
+	s := y.(string)        // illegal: string does not implement I (missing method m)
+	r := y.(io.Reader)     // r has type io.Reader and the dynamic type of y must implement both I and io.Reader
+	…
+}
+
+ +

+A type assertion used in an assignment statement or initialization of the special form +

+ +
+v, ok = x.(T)
+v, ok := x.(T)
+var v, ok = x.(T)
+var v, ok interface{} = x.(T) // dynamic types of v and ok are T and bool
+
+ +

+yields an additional untyped boolean value. The value of ok is true +if the assertion holds. Otherwise it is false and the value of v is +the zero value for type T. +No run-time panic occurs in this case. +

+ + +

Calls

+ +

+Given an expression f of function type +F, +

+ +
+f(a1, a2, … an)
+
+ +

+calls f with arguments a1, a2, … an. +Except for one special case, arguments must be single-valued expressions +assignable to the parameter types of +F and are evaluated before the function is called. +The type of the expression is the result type of F. +A method invocation is similar but the method itself +is specified as a selector upon a value of the receiver type for +the method. +

+ +
+math.Atan2(x, y)  // function call
+var pt *Point
+pt.Scale(3.5)     // method call with receiver pt
+
+ +

+If f denotes a generic function, it must be +instantiated before it can be called +or used as a function value. +

+ +

+If the type of f is a type parameter, +all types in its type set must have the same underlying type, which must be a function type, +and the function call must be valid for that type. +

+ +

+In a function call, the function value and arguments are evaluated in +the usual order. +After they are evaluated, new storage is allocated for the function's +variables, which includes its parameters +and results. +Then, the arguments of the call are passed to the function, +which means that they are assigned +to their corresponding function parameters, +and the called function begins execution. +The return parameters of the function are passed +back to the caller when the function returns. +

+ +

+Calling a nil function value +causes a run-time panic. +

+ +

+As a special case, if the return values of a function or method +g are equal in number and individually +assignable to the parameters of another function or method +f, then the call f(g(parameters_of_g)) +will invoke f after passing the return values of +g to the parameters of f in order. +The call of f must contain no parameters other than the call of g, +and g must have at least one return value. +If f has a final ... parameter, it is +assigned the return values of g that remain after +assignment of regular parameters. +

+ +
+func Split(s string, pos int) (string, string) {
+	return s[0:pos], s[pos:]
+}
+
+func Join(s, t string) string {
+	return s + t
+}
+
+if Join(Split(value, len(value)/2)) != value {
+	log.Panic("test fails")
+}
+
+ +

+A method call x.m() is valid if the method set +of (the type of) x contains m and the +argument list can be assigned to the parameter list of m. +If x is addressable and &x's method +set contains m, x.m() is shorthand +for (&x).m(): +

+ +
+var p Point
+p.Scale(3.5)
+
+ +

+There is no distinct method type and there are no method literals. +

+ +

Passing arguments to ... parameters

+ +

+If f is variadic with a final +parameter p of type ...T, then within f +the type of p is equivalent to type []T. +If f is invoked with no actual arguments for p, +the value passed to p is nil. +Otherwise, the value passed is a new slice +of type []T with a new underlying array whose successive elements +are the actual arguments, which all must be assignable +to T. The length and capacity of the slice is therefore +the number of arguments bound to p and may differ for each +call site. +

+ +

+Given the function and calls +

+
+func Greeting(prefix string, who ...string)
+Greeting("nobody")
+Greeting("hello:", "Joe", "Anna", "Eileen")
+
+ +

+within Greeting, who will have the value +nil in the first call, and +[]string{"Joe", "Anna", "Eileen"} in the second. +

+ +

+If the final argument is assignable to a slice type []T and +is followed by ..., it is passed unchanged as the value +for a ...T parameter. In this case no new slice is created. +

+ +

+Given the slice s and call +

+ +
+s := []string{"James", "Jasmine"}
+Greeting("goodbye:", s...)
+
+ +

+within Greeting, who will have the same value as s +with the same underlying array. +

+ +

Instantiations

+ +

+A generic function, method, or type is instantiated by substituting type arguments +for the type parameters [Go 1.18][Go 1.27]. +Instantiation proceeds in two steps: +

+ +
    +
  1. +Each type argument is substituted for its corresponding type parameter in the generic +declaration. +This substitution happens across the entire function or type declaration, +including the type parameter list itself and any types in that list. +
  2. + +
  3. +After substitution, each type argument must satisfy +the constraint (instantiated, if necessary) +of the corresponding type parameter. Otherwise instantiation fails. +
  4. +
+ +

+Instantiating a generic type, function, or method results in a non-generic type, function, +or method, respectively. +

+ +
+type parameter list    type arguments    after substitution
+
+[P any]                int               int satisfies any
+[S ~[]E, E any]        []int, int        []int satisfies ~[]int, int satisfies any
+[P io.Writer]          string            illegal: string doesn't satisfy io.Writer
+[P comparable]         any               any satisfies (but does not implement) comparable
+
+ +

+When using a generic function or method, type arguments may be provided explicitly, +or they may be partially or completely inferred +from the context in which the function is used. +Provided that they can be inferred, type argument lists may be omitted entirely if the function is: +

+ + + +

+In all other cases, a (possibly partial) type argument list must be present. +If a type argument list is absent or partial, all missing type arguments +must be inferable from the context in which the function is used. +

+ +
+// sum returns the sum (concatenation, for strings) of its arguments.
+func sum[T ~int | ~float64 | ~string](x... T) T { … }
+
+x := sum                       // illegal: the type of x is unknown
+intSum := sum[int]             // intSum has type func(x... int) int
+a := intSum(2, 3)              // a has value 5 of type int
+b := sum[float64](2.0, 3)      // b has value 5.0 of type float64
+c := sum(b, -1)                // c has value 4.0 of type float64
+
+type sumFunc func(x... string) string
+var f sumFunc = sum            // same as var f sumFunc = sum[string]
+f = sum                        // same as f = sum[string]
+
+ +

+A partial type argument list cannot be empty; at least the first argument must be present. +The list is a prefix of the full list of type arguments, leaving the remaining arguments +to be inferred. Loosely speaking, type arguments may be omitted from "right to left". +

+ +
+func apply[S ~[]E, E any](s S, f func(E) E) S { … }
+
+f0 := apply[]                  // illegal: type argument list cannot be empty
+f1 := apply[[]int]             // type argument for S explicitly provided, type argument for E inferred
+f2 := apply[[]string, string]  // both type arguments explicitly provided
+
+var bytes []byte
+r := apply(bytes, func(byte) byte { … })  // both type arguments inferred from the function arguments
+
+ +

+For a generic type, all type arguments must always be provided explicitly. +

+ +

Type inference

+ +

+A use of a generic function may omit some or all type arguments if they can be +inferred from the context within which the function is used, including +the constraints of the function's type parameters. +Type inference succeeds if it can infer the missing type arguments +and instantiation succeeds with the +inferred type arguments. +Otherwise, type inference fails and the program is invalid. +

+ +

+Type inference uses the type relationships between pairs of types for inference: +For instance, a function argument must be assignable +to its respective function parameter; this establishes a relationship between the +type of the argument and the type of the parameter. +If either of these two types contains type parameters, type inference looks for the +type arguments to substitute the type parameters with such that the assignability +relationship is satisfied. +Similarly, type inference uses the fact that a type argument must +satisfy the constraint of its respective +type parameter. +

+ +

+Each such pair of matched types corresponds to a type equation containing +one or multiple type parameters, from one or possibly multiple generic functions. +Inferring the missing type arguments means solving the resulting set of type +equations for the respective type parameters. +

+ +

+For example, given +

+ +
+// dedup returns a copy of the argument slice with any duplicate entries removed.
+func dedup[S ~[]E, E comparable](S) S { … }
+
+type Slice []int
+var s Slice
+s = dedup(s)   // same as s = dedup[Slice, int](s)
+
+ +

+the variable s of type Slice must be assignable to +the function parameter type S for the program to be valid. +To reduce complexity, type inference ignores the directionality of assignments, +so the type relationship between Slice and S can be +expressed via the (symmetric) type equation Slice ≡A S +(or S ≡A Slice for that matter), +where the A in A +indicates that the LHS and RHS types must match per assignability rules +(see the section on type unification for +details). +Similarly, the type parameter S must satisfy its constraint +~[]E. This can be expressed as S ≡C ~[]E +where X ≡C Y stands for +"X satisfies constraint Y". +These observations lead to a set of two equations +

+ +
+	Slice ≡A S      (1)
+	S     ≡C ~[]E   (2)
+
+ +

+which now can be solved for the type parameters S and E. +From (1) a compiler can infer that the type argument for S is Slice. +Similarly, because the underlying type of Slice is []int +and []int must match []E of the constraint, +a compiler can infer that E must be int. +Thus, for these two equations, type inference infers +

+ +
+	S ➞ Slice
+	E ➞ int
+
+ +

+Given a set of type equations, the type parameters to solve for are +the type parameters of the functions that need to be instantiated +and for which no explicit type arguments is provided. +These type parameters are called bound type parameters. +For instance, in the dedup example above, the type parameters +S and E are bound to dedup. +An argument to a generic function call may be a generic function itself. +The type parameters of that function are included in the set of bound +type parameters. +The types of function arguments may contain type parameters from other +functions (such as a generic function enclosing a function call). +Those type parameters may also appear in type equations but they are +not bound in that context. +Type equations are always solved for the bound type parameters only. +

+ +

+Type inference supports calls of generic functions and any use of +a generic function in a context where the function must be +assignable to a (non-generic) +function type. +The latter includes assigning a generic function to a variable +(including passing it as an argument to another function), +converting a generic function to a function type, and others. +

+ +

+Type inference operates on a set of equations specific to each of +these cases. +The equations are as follows (type argument lists are omitted for clarity): +

+ +
    +
  • +

    + In a function call f(a0, a1, …) where + f or a function argument ai is + a generic function: +
    + Each pair (ai, pi) of corresponding + function arguments and parameters of fwhere ai is not an + untyped constant yields an equation + typeof(pi) ≡A typeof(ai). +
    + If ai is an untyped constant cj, + and typeof(pi) is a bound type parameter Pk, + the pair (cj, Pk) is collected separately from + the type equations. +

    +
  • +
  • +

    + In a context where a generic function f must be + assignable to a (non-generic) function type T: +
    + typeof(f) ≡A T. +

    +
  • +
+ +

+Additionally, each type parameter Pk and corresponding type constraint +Ck yields the type equation +PkC Ck. +

+ +

+Type inference gives precedence to type information obtained from typed operands +before considering untyped constants. +Therefore, inference proceeds in two phases: +

+ +
    +
  1. +

    + The type equations are solved for the bound + type parameters using type unification. + If unification fails, type inference fails. +

    +
  2. +
  3. +

    + For each bound type parameter Pk for which no type argument + has been inferred yet and for which one or more pairs + (cj, Pk) with that same type parameter + were collected, determine the constant kind + of the constants cj in all those pairs the same way as for + constant expressions. + The type argument for Pk is the + default type for the determined constant kind. + If a constant kind cannot be determined due to conflicting constant kinds, + type inference fails. +

    +
  4. +
+ +

+If not all type arguments have been found after these two phases, type inference fails. +

+ +

+If the two phases are successful, type inference determined a type argument for each +bound type parameter: +

+ +
+	Pk ➞ Ak
+
+ +

+A type argument Ak may be a composite type, +containing other bound type parameters Pk as element types +(or even be just another bound type parameter). +In a process of repeated simplification, the bound type parameters in each type +argument are substituted with the respective type arguments for those type +parameters until each type argument is free of bound type parameters. +

+ +

+If type arguments contain cyclic references to themselves +through bound type parameters, simplification and thus type +inference fails. +Otherwise, type inference succeeds. +

+ +

Type unification

+ +

+Type inference solves type equations through type unification. +Type unification recursively compares the LHS and RHS types of an +equation, where either or both types may be or contain bound type parameters, +and looks for type arguments for those type parameters such that the LHS +and RHS match (become identical or assignment-compatible, depending on +context). +To that effect, type inference maintains a map of bound type parameters +to inferred type arguments; this map is consulted and updated during type unification. +Initially, the bound type parameters are known but the map is empty. +During type unification, if a new type argument A is inferred, +the respective mapping P ➞ A from type parameter to argument +is added to the map. +Conversely, when comparing types, a known type argument +(a type argument for which a map entry already exists) +takes the place of its corresponding type parameter. +As type inference progresses, the map is populated more and more +until all equations have been considered, or until unification fails. +Type inference succeeds if no unification step fails and the map has +an entry for each type parameter. +

+ +

+For example, given the type equation with the bound type parameter +P +

+ +
+	[10]struct{ elem P, list []P } ≡A [10]struct{ elem string; list []string }
+
+ +

+type inference starts with an empty map. +Unification first compares the top-level structure of the LHS and RHS +types. +Both are arrays of the same length; they unify if the element types unify. +Both element types are structs; they unify if they have +the same number of fields with the same names and if the +field types unify. +The type argument for P is not known yet (there is no map entry), +so unifying P with string adds +the mapping P ➞ string to the map. +Unifying the types of the list field requires +unifying []P and []string and +thus P and string. +Since the type argument for P is known at this point +(there is a map entry for P), its type argument +string takes the place of P. +And since string is identical to string, +this unification step succeeds as well. +Unification of the LHS and RHS of the equation is now finished. +Type inference succeeds because there is only one type equation, +no unification step failed, and the map is fully populated. +

+ +

+Unification uses a combination of exact and loose +unification depending on whether two types have to be +identical, +assignment-compatible, or +only structurally equal. +The respective type unification rules +are spelled out in detail in the Appendix. +

+ +

+For an equation of the form X ≡A Y, +where X and Y are types involved +in an assignment (including parameter passing and return statements), +the top-level type structures may unify loosely but element types +must unify exactly, matching the rules for assignments. +

+ +

+For an equation of the form P ≡C C, +where P is a type parameter and C +its corresponding constraint, the unification rules are bit +more complicated: +

+ +
    +
  • + If all types in C's type set have the same + underlying type U, + and P has a known type argument A, + U and A must unify loosely. +
  • +
  • + Similarly, if all types in C's type set are + channel types with the same element type and non-conflicting + channel directions, + and P has a known type argument A, + the most restrictive channel type in C's type + set and A must unify loosely. +
  • +
  • + If P does not have a known type argument + and C contains exactly one type term T + that is not an underlying (tilde) type, unification adds the + mapping P ➞ T to the map. +
  • +
  • + If C does not have a type U + as described above + and P has a known type argument A, + A must have all methods of C, if any, + and corresponding method types must unify exactly. +
  • +
+ +

+When solving type equations from type constraints, +solving one equation may infer additional type arguments, +which in turn may enable solving other equations that depend +on those type arguments. +Type inference repeats type unification as long as new type +arguments are inferred. +

+ +

Operators

+ +

+Operators combine operands into expressions. +

+ +
+Expression = UnaryExpr | Expression binary_op Expression .
+UnaryExpr  = PrimaryExpr | unary_op UnaryExpr .
+
+binary_op  = "||" | "&&" | rel_op | add_op | mul_op .
+rel_op     = "==" | "!=" | "<" | "<=" | ">" | ">=" .
+add_op     = "+" | "-" | "|" | "^" .
+mul_op     = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
+
+unary_op   = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
+
+ +

+Comparisons are discussed elsewhere. +For other binary operators, the operand types must be identical +unless the operation involves shifts or untyped constants. +For operations involving constants only, see the section on +constant expressions. +

+ +

+Except for shift operations, if one operand is an untyped constant +and the other operand is not, the constant is implicitly converted +to the type of the other operand. +

+ +

+The right operand in a shift expression must have integer type +[Go 1.13] +or be an untyped constant representable by a +value of type uint. +If the left operand of a non-constant shift expression is an untyped constant, +it is first implicitly converted to the type it would assume if the shift expression were +replaced by its left operand alone. +

+ +
+var a [1024]byte
+var s uint = 33
+
+// The results of the following examples are given for 64-bit ints.
+var i = 1<<s                   // 1 has type int
+var j int32 = 1<<s             // 1 has type int32; j == 0
+var k = uint64(1<<s)           // 1 has type uint64; k == 1<<33
+var m int = 1.0<<s             // 1.0 has type int; m == 1<<33
+var n = 1.0<<s == j            // 1.0 has type int32; n == true
+var o = 1<<s == 2<<s           // 1 and 2 have type int; o == false
+var p = 1<<s == 1<<33          // 1 has type int; p == true
+var u = 1.0<<s                 // illegal: 1.0 has type float64, cannot shift
+var u1 = 1.0<<s != 0           // illegal: 1.0 has type float64, cannot shift
+var u2 = 1<<s != 1.0           // illegal: 1 has type float64, cannot shift
+var v1 float32 = 1<<s          // illegal: 1 has type float32, cannot shift
+var v2 = string(1<<s)          // illegal: 1 is converted to a string, cannot shift
+var w int64 = 1.0<<33          // 1.0<<33 is a constant shift expression; w == 1<<33
+var x = a[1.0<<s]              // panics: 1.0 has type int, but 1<<33 overflows array bounds
+var b = make([]byte, 1.0<<s)   // 1.0 has type int; len(b) == 1<<33
+
+// The results of the following examples are given for 32-bit ints,
+// which means the shifts will overflow.
+var mm int = 1.0<<s            // 1.0 has type int; mm == 0
+var oo = 1<<s == 2<<s          // 1 and 2 have type int; oo == true
+var pp = 1<<s == 1<<33         // illegal: 1 has type int, but 1<<33 overflows int
+var xx = a[1.0<<s]             // 1.0 has type int; xx == a[0]
+var bb = make([]byte, 1.0<<s)  // 1.0 has type int; len(bb) == 0
+
+ +

Operator precedence

+

+Unary operators have the highest precedence. +As the ++ and -- operators form +statements, not expressions, they fall +outside the operator hierarchy. +As a consequence, statement *p++ is the same as (*p)++. +

+

+There are five precedence levels for binary operators. +Multiplication operators bind strongest, followed by addition +operators, comparison operators, && (logical AND), +and finally || (logical OR): +

+ +
+Precedence    Operator
+    5             *  /  %  <<  >>  &  &^
+    4             +  -  |  ^
+    3             ==  !=  <  <=  >  >=
+    2             &&
+    1             ||
+
+ +

+Binary operators of the same precedence associate from left to right. +For instance, x / y * z is the same as (x / y) * z. +

+ +
++x                         // x
+42 + a - b                 // (42 + a) - b
+23 + 3*x[i]                // 23 + (3 * x[i])
+x <= f()                   // x <= f()
+^a >> b                    // (^a) >> b
+f() || g()                 // f() || g()
+x == y+1 && <-chanInt > 0  // (x == (y+1)) && ((<-chanInt) > 0)
+
+ + +

Arithmetic operators

+

+Arithmetic operators apply to numeric values and yield a result of the same +type as the first operand. The four standard arithmetic operators (+, +-, *, /) apply to +integer, floating-point, and +complex types; + also applies to strings. +The bitwise logical and shift operators apply to integers only. +

+ +
++    sum                    integers, floats, complex values, strings
+-    difference             integers, floats, complex values
+*    product                integers, floats, complex values
+/    quotient               integers, floats, complex values
+%    remainder              integers
+
+&    bitwise AND            integers
+|    bitwise OR             integers
+^    bitwise XOR            integers
+&^   bit clear (AND NOT)    integers
+
+<<   left shift             integer << integer >= 0
+>>   right shift            integer >> integer >= 0
+
+ +

+If the operand type is a type parameter, +the operator must apply to each type in that type set. +The operands are represented as values of the type argument that the type parameter +is instantiated with, and the operation is computed +with the precision of that type argument. For example, given the function: +

+ +
+func dotProduct[F ~float32|~float64](v1, v2 []F) F {
+	var s F
+	for i, x := range v1 {
+		y := v2[i]
+		s += x * y
+	}
+	return s
+}
+
+ +

+the product x * y and the addition s += x * y +are computed with float32 or float64 precision, +respectively, depending on the type argument for F. +

+ +

Integer operators

+ +

+For two integer values x and y, the integer quotient +q = x / y and remainder r = x % y satisfy the following +relationships: +

+ +
+x = q*y + r  and  |r| < |y|
+
+ +

+with x / y truncated towards zero +("truncated division"). +

+ +
+ x     y     x / y     x % y
+ 5     3       1         2
+-5     3      -1        -2
+ 5    -3      -1         2
+-5    -3       1        -2
+
+ +

+The one exception to this rule is that if the dividend x is +the most negative value for the int type of x, the quotient +q = x / -1 is equal to x (and r = 0) +due to two's-complement integer overflow: +

+ +
+                         x, q
+int8                     -128
+int16                  -32768
+int32             -2147483648
+int64    -9223372036854775808
+
+ +

+If the divisor is a constant, it must not be zero. +If the divisor is zero at run time, a run-time panic occurs. +If the dividend is non-negative and the divisor is a constant power of 2, +the division may be replaced by a right shift, and computing the remainder may +be replaced by a bitwise AND operation: +

+ +
+ x     x / 4     x % 4     x >> 2     x & 3
+ 11      2         3         2          3
+-11     -2        -3        -3          1
+
+ +

+The shift operators shift the left operand by the shift count specified by the +right operand, which must be non-negative. If the shift count is negative at run time, +a run-time panic occurs. +The shift operators implement arithmetic shifts if the left operand is a signed +integer and logical shifts if it is an unsigned integer. +There is no upper limit on the shift count. Shifts behave +as if the left operand is shifted n times by 1 for a shift +count of n. +As a result, x << 1 is the same as x*2 +and x >> 1 is the same as +x/2 but truncated towards negative infinity. +

+ +

+For integer operands, the unary operators ++, -, and ^ are defined as +follows: +

+ +
++x                          is 0 + x
+-x    negation              is 0 - x
+^x    bitwise complement    is m ^ x  with m = "all bits set to 1" for unsigned x
+                                      and  m = -1 for signed x
+
+ + +

Integer overflow

+ +

+For unsigned integer values, the operations +, +-, *, and << are +computed modulo 2n, where n is the bit width of +the unsigned integer's type. +Loosely speaking, these unsigned integer operations +discard high bits upon overflow, and programs may rely on "wrap around". +

+ +

+For signed integers, the operations +, +-, *, /, and << may legally +overflow and the resulting value exists and is deterministically defined +by the signed integer representation, the operation, and its operands. +Overflow does not cause a run-time panic. +A compiler may not optimize code under the assumption that overflow does +not occur. For instance, it may not assume that x < x + 1 is always true. +

+ +

Floating-point operators

+ +

+For floating-point and complex numbers, ++x is the same as x, +while -x is the negation of x. +The result of a floating-point or complex division by zero is not specified beyond the +IEEE 754 standard; whether a run-time panic +occurs is implementation-specific. +

+ +

+An implementation may combine multiple floating-point operations into a single +fused operation, possibly across statements, and produce a result that differs +from the value obtained by executing and rounding the instructions individually. +An explicit floating-point type conversion rounds to +the precision of the target type, preventing fusion that would discard that rounding. +

+ +

+For instance, some architectures provide a "fused multiply and add" (FMA) instruction +that computes x*y + z without rounding the intermediate result x*y. +These examples show when a Go implementation can use that instruction: +

+ +
+// FMA allowed for computing r, because x*y is not explicitly rounded:
+r  = x*y + z
+r  = z;   r += x*y
+t  = x*y; r = t + z
+*p = x*y; r = *p + z
+r  = x*y + float64(z)
+
+// FMA disallowed for computing r, because it would omit rounding of x*y:
+r  = float64(x*y) + z
+r  = z; r += float64(x*y)
+t  = float64(x*y); r = t + z
+
+ +

String concatenation

+ +

+Strings can be concatenated using the + operator +or the += assignment operator: +

+ +
+s := "hi" + string(c)
+s += " and good bye"
+
+ +

+String addition creates a new string by concatenating the operands. +

+ +

Comparison operators

+ +

+Comparison operators compare two operands and yield an untyped boolean value. +

+ +
+==    equal
+!=    not equal
+<     less
+<=    less or equal
+>     greater
+>=    greater or equal
+
+ +

+In any comparison, the first operand +must be assignable +to the type of the second operand, or vice versa. +

+

+The equality operators == and != apply +to operands of comparable types. +The ordering operators <, <=, >, and >= +apply to operands of ordered types. +These terms and the result of the comparisons are defined as follows: +

+ +
    +
  • + Boolean types are comparable. + Two boolean values are equal if they are either both + true or both false. +
  • + +
  • + Integer types are comparable and ordered. + Two integer values are compared in the usual way. +
  • + +
  • + Floating-point types are comparable and ordered. + Two floating-point values are compared as defined by the IEEE 754 standard. +
  • + +
  • + Complex types are comparable. + Two complex values u and v are + equal if both real(u) == real(v) and + imag(u) == imag(v). +
  • + +
  • + String types are comparable and ordered. + Two string values are compared lexically byte-wise. +
  • + +
  • + Pointer types are comparable. + Two pointer values are equal if they point to the same variable or if both have value nil. + Pointers to distinct zero-size variables may or may not be equal. +
  • + +
  • + Channel types are comparable. + Two channel values are equal if they were created by the same call to + make + or if both have value nil. +
  • + +
  • + Interface types that are not type parameters are comparable. + Two interface values are equal if they have identical dynamic types + and equal dynamic values or if both have value nil. +
  • + +
  • + A value x of non-interface type X and + a value t of interface type T can be compared + if type X is comparable and + X implements T. + They are equal if t's dynamic type is identical to X + and t's dynamic value is equal to x. +
  • + +
  • + Struct types are comparable if all their field types are comparable. + Two struct values are equal if their corresponding + non-blank field values are equal. + The fields are compared in source order, and comparison stops as + soon as two field values differ (or all fields have been compared). +
  • + +
  • + Array types are comparable if their array element types are comparable. + Two array values are equal if their corresponding element values are equal. + The elements are compared in ascending index order, and comparison stops + as soon as two element values differ (or all elements have been compared). +
  • + +
  • + Type parameters are comparable if they are strictly comparable (see below). +
  • +
+ +

+A comparison of two interface values with identical dynamic types +causes a run-time panic if that type +is not comparable. This behavior applies not only to direct interface +value comparisons but also when comparing arrays of interface values +or structs with interface-valued fields. +

+ +

+Slice, map, and function types are not comparable. +However, as a special case, a slice, map, or function value may +be compared to the predeclared identifier nil. +Comparison of pointer, channel, and interface values to nil +is also allowed and follows from the general rules above. +

+ +
+const c = 3 < 4            // c is the untyped boolean constant true
+
+type MyBool bool
+var x, y int
+var (
+	// The result of a comparison is an untyped boolean.
+	// The usual assignment rules apply.
+	b3        = x == y // b3 has type bool
+	b4 bool   = x == y // b4 has type bool
+	b5 MyBool = x == y // b5 has type MyBool
+)
+
+ +

+A type is strictly comparable if it is comparable and not an interface +type nor composed of interface types. +Specifically: +

+ +
    +
  • + Boolean, numeric, string, pointer, and channel types are strictly comparable. +
  • + +
  • + Struct types are strictly comparable if all their field types are strictly comparable. +
  • + +
  • + Array types are strictly comparable if their array element types are strictly comparable. +
  • + +
  • + Type parameters are strictly comparable if all types in their type set are strictly comparable. +
  • +
+ +

Logical operators

+ +

+Logical operators apply to boolean values +and yield a result of the same type as the operands. +The left operand is evaluated, and then the right if the condition requires it. +

+ +
+&&    conditional AND    p && q  is  "if p then q else false"
+||    conditional OR     p || q  is  "if p then true else q"
+!     NOT                !p      is  "not p"
+
+ + +

Address operators

+ +

+For an operand x of type T, the address operation +&x generates a pointer of type *T to x. +The operand must be addressable, +that is, either a variable, pointer indirection, or slice indexing +operation; or a field selector of an addressable struct operand; +or an array indexing operation of an addressable array. +As an exception to the addressability requirement, x may also be a +(possibly parenthesized) +composite literal. +If the evaluation of x would cause a run-time panic, +then the evaluation of &x does too. +

+ +

+For an operand x of pointer type *T, the pointer +indirection *x denotes the variable of type T pointed +to by x. +If x is nil, an attempt to evaluate *x +will cause a run-time panic. +

+ +
+&x
+&a[f(2)]
+&Point{2, 3}
+*p
+*pf(x)
+
+var x *int = nil
+*x   // causes a run-time panic
+&*x  // causes a run-time panic
+
+ + +

Receive operator

+ +

+For an operand ch of channel type, +the value of the receive operation <-ch is the value received +from the channel ch. +The channel direction must permit receive operations, +and the type of the receive operation is the element type of the channel. +The expression blocks until a value is available. +Receiving from a nil channel blocks forever. +A receive operation on a closed channel can always proceed +immediately, yielding the element type's zero value +after any previously sent values have been received. +

+ +
+v1 := <-ch
+v2 = <-ch
+f(<-ch)
+<-strobe  // wait until clock pulse and discard received value
+
+ +

+If the operand type is a type parameter, +all types in its type set must be channel types that permit receive operations, and +they must all have the same element type, which is the type of the receive operation. +

+ +

+A receive expression used in an assignment statement or initialization of the special form +

+ +
+x, ok = <-ch
+x, ok := <-ch
+var x, ok = <-ch
+var x, ok T = <-ch
+
+ +

+yields an additional untyped boolean result reporting whether the +communication succeeded. The value of ok is true +if the value received was delivered by a successful send operation to the +channel, or false if it is a zero value generated because the +channel is closed and empty. +

+ + +

Conversions

+ +

+A conversion changes the type of an expression +to the type specified by the conversion. +A conversion may appear literally in the source, or it may be implied +by the context in which an expression appears. +

+ +

+An explicit conversion is an expression of the form T(x) +where T is a type and x is an expression +that can be converted to type T. +

+ +
+Conversion = Type "(" Expression [ "," ] ")" .
+
+ +

+If the type starts with the operator * or <-, +or if the type starts with the keyword func +and has no result list, it must be parenthesized when +necessary to avoid ambiguity: +

+ +
+*Point(p)        // same as *(Point(p))
+(*Point)(p)      // p is converted to *Point
+<-chan int(c)    // same as <-(chan int(c))
+(<-chan int)(c)  // c is converted to <-chan int
+func()(x)        // function signature func() x
+(func())(x)      // x is converted to func()
+(func() int)(x)  // x is converted to func() int
+func() int(x)    // x is converted to func() int (unambiguous)
+
+ +

+A constant value x can be converted to +type T if x is representable +by a value of T. +As a special case, an integer constant x can be explicitly converted to a +string type using the +same rule +as for non-constant x. +

+ +

+Converting a constant to a type that is not a type parameter +yields a typed constant. +

+ +
+uint(iota)               // iota value of type uint
+float32(2.718281828)     // 2.718281828 of type float32
+complex128(1)            // 1.0 + 0.0i of type complex128
+float32(0.49999999)      // 0.5 of type float32
+float64(-1e-1000)        // 0.0 of type float64
+string('x')              // "x" of type string
+string(0x266c)           // "♬" of type string
+myString("foo" + "bar")  // "foobar" of type myString
+string([]byte{'a'})      // not a constant: []byte{'a'} is not a constant
+(*int)(nil)              // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type
+int(1.2)                 // illegal: 1.2 cannot be represented as an int
+string(65.0)             // illegal: 65.0 is not an integer constant
+
+ +

+Converting a constant to a type parameter yields a non-constant value of that type, +with the value represented as a value of the type argument that the type parameter +is instantiated with. +For example, given the function: +

+ +
+func f[P ~float32|~float64]() {
+	… P(1.1) …
+}
+
+ +

+the conversion P(1.1) results in a non-constant value of type P +and the value 1.1 is represented as a float32 or a float64 +depending on the type argument for f. +Accordingly, if f is instantiated with a float32 type, +the numeric value of the expression P(1.1) + 1.2 will be computed +with the same precision as the corresponding non-constant float32 +addition. +

+ +

+A non-constant value x can be converted to type T +in any of these cases: +

+ +
    +
  • + x is assignable + to T. +
  • +
  • + ignoring struct tags (see below), + x's type and T are not + type parameters but have + identical underlying types. +
  • +
  • + ignoring struct tags (see below), + x's type and T are pointer types + that are not named types, + and their pointer base types are not type parameters but + have identical underlying types. +
  • +
  • + x's type and T are both integer or floating + point types. +
  • +
  • + x's type and T are both complex types. +
  • +
  • + x is an integer or a slice of bytes or runes + and T is a string type. +
  • +
  • + x is a string and T is a slice of bytes or runes. +
  • +
  • + x is a slice, T is an array [Go 1.20] + or a pointer to an array [Go 1.17], + and the slice and array types have identical element types. +
  • +
+ +

+Additionally, if T or x's type V are type +parameters, x +can also be converted to type T if one of the following conditions applies: +

+ +
    +
  • +Both V and T are type parameters and a value of each +type in V's type set can be converted to each type in T's +type set. +
  • +
  • +Only V is a type parameter and a value of each +type in V's type set can be converted to T. +
  • +
  • +Only T is a type parameter and x can be converted to each +type in T's type set. +
  • +
+ +

+Struct tags are ignored when comparing struct types +for identity for the purpose of conversion: +

+ +
+type Person struct {
+	Name    string
+	Address *struct {
+		Street string
+		City   string
+	}
+}
+
+var data *struct {
+	Name    string `json:"name"`
+	Address *struct {
+		Street string `json:"street"`
+		City   string `json:"city"`
+	} `json:"address"`
+}
+
+var person = (*Person)(data)  // ignoring tags, the underlying types are identical
+
+ +

+Specific rules apply to (non-constant) conversions between numeric types or +to and from a string type. +These conversions may change the representation of x +and incur a run-time cost. +All other conversions only change the type but not the representation +of x. +

+ +

+There is no linguistic mechanism to convert between pointers and integers. +The package unsafe +implements this functionality under restricted circumstances. +

+ +

Conversions between numeric types

+ +

+For the conversion of non-constant numeric values, the following rules apply: +

+ +
    +
  1. +When converting between integer types, if the value is a signed integer, it is +sign extended to implicit infinite precision; otherwise it is zero extended. +It is then truncated to fit in the result type's size. +For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0. +The conversion always yields a valid value; there is no indication of overflow. +
  2. +
  3. +When converting a floating-point number to an integer, the fraction is discarded +(truncation towards zero). +
  4. +
  5. +When converting an integer or floating-point number to a floating-point type, +or a complex number to another complex type, the result value is rounded +to the precision specified by the destination type. +For instance, the value of a variable x of type float32 +may be stored using additional precision beyond that of an IEEE 754 32-bit number, +but float32(x) represents the result of rounding x's value to +32-bit precision. Similarly, x + 0.1 may use more than 32 bits +of precision, but float32(x + 0.1) does not. +
  6. +
+ +

+In all non-constant conversions involving floating-point or complex values, +if the result type cannot represent the value the conversion +succeeds but the result value is implementation-dependent. +

+ +

Conversions to and from a string type

+ +
    +
  1. +Converting a slice of bytes to a string type yields +a string whose successive bytes are the elements of the slice. + +
    +string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})   // "hellø"
    +string([]byte{})                                     // ""
    +string([]byte(nil))                                  // ""
    +
    +type bytes []byte
    +string(bytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})    // "hellø"
    +
    +type myByte byte
    +string([]myByte{'w', 'o', 'r', 'l', 'd', '!'})       // "world!"
    +myString([]myByte{'\xf0', '\x9f', '\x8c', '\x8d'})   // "🌍"
    +
    +
  2. + +
  3. +Converting a slice of runes to a string type yields +a string that is the concatenation of the individual rune values +converted to strings. + +
    +string([]rune{0x767d, 0x9d6c, 0x7fd4})   // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +string([]rune{})                         // ""
    +string([]rune(nil))                      // ""
    +
    +type runes []rune
    +string(runes{0x767d, 0x9d6c, 0x7fd4})    // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +
    +type myRune rune
    +string([]myRune{0x266b, 0x266c})         // "\u266b\u266c" == "♫♬"
    +myString([]myRune{0x1f30e})              // "\U0001f30e" == "🌎"
    +
    +
  4. + +
  5. +Converting a value of a string type to a slice of bytes type +yields a non-nil slice whose successive elements are the bytes of the string. +The capacity of the resulting slice is +implementation-specific and may be larger than the slice length. + +
    +[]byte("hellø")             // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +[]byte("")                  // []byte{}
    +
    +bytes("hellø")              // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +
    +[]myByte("world!")          // []myByte{'w', 'o', 'r', 'l', 'd', '!'}
    +[]myByte(myString("🌏"))    // []myByte{'\xf0', '\x9f', '\x8c', '\x8f'}
    +
    +
  6. + +
  7. +Converting a value of a string type to a slice of runes type +yields a slice containing the individual Unicode code points of the string. +The capacity of the resulting slice is +implementation-specific and may be larger than the slice length. + +
    +[]rune(myString("白鵬翔"))   // []rune{0x767d, 0x9d6c, 0x7fd4}
    +[]rune("")                  // []rune{}
    +
    +runes("白鵬翔")              // []rune{0x767d, 0x9d6c, 0x7fd4}
    +
    +[]myRune("♫♬")              // []myRune{0x266b, 0x266c}
    +[]myRune(myString("🌐"))    // []myRune{0x1f310}
    +
    +
  8. + +
  9. +Finally, for historical reasons, an integer value may be converted to a string type. +This form of conversion yields a string containing the (possibly multi-byte) UTF-8 +representation of the Unicode code point with the given integer value. +Values outside the range of valid Unicode code points are converted to "\uFFFD". + +
    +string('a')          // "a"
    +string(65)           // "A"
    +string('\xf8')       // "\u00f8" == "ø" == "\xc3\xb8"
    +string(-1)           // "\ufffd" == "\xef\xbf\xbd"
    +
    +type myString string
    +myString('\u65e5')   // "\u65e5" == "日" == "\xe6\x97\xa5"
    +
    + +Note: This form of conversion may eventually be removed from the language. +The go vet tool flags certain +integer-to-string conversions as potential errors. +Library functions such as +utf8.AppendRune or +utf8.EncodeRune +should be used instead. +
  10. +
+ +

Conversions from slice to array or array pointer

+ +

+Converting a slice to an array yields an array containing the elements of the underlying array of the slice. +Similarly, converting a slice to an array pointer yields a pointer to the underlying array of the slice. +In both cases, if the length of the slice is less than the length of the array, +a run-time panic occurs. +

+ +
+s := make([]byte, 2, 4)
+
+a0 := [0]byte(s)
+a1 := [1]byte(s[1:])     // a1[0] == s[1]
+a2 := [2]byte(s)         // a2[0] == s[0]
+a4 := [4]byte(s)         // panics: len([4]byte) > len(s)
+
+s0 := (*[0]byte)(s)      // s0 != nil
+s1 := (*[1]byte)(s[1:])  // &s1[0] == &s[1]
+s2 := (*[2]byte)(s)      // &s2[0] == &s[0]
+s4 := (*[4]byte)(s)      // panics: len([4]byte) > len(s)
+
+var t []string
+t0 := [0]string(t)       // ok for nil slice t
+t1 := (*[0]string)(t)    // t1 == nil
+t2 := (*[1]string)(t)    // panics: len([1]string) > len(t)
+
+u := make([]byte, 0)
+u0 := (*[0]byte)(u)      // u0 != nil
+
+ +

Constant expressions

+ +

+Constant expressions may contain only constant +operands and are evaluated at compile time. +

+ +

+Untyped boolean, numeric, and string constants may be used as operands +wherever it is legal to use an operand of boolean, numeric, or string type, +respectively. +

+ +

+A constant comparison always yields +an untyped boolean constant. If the left operand of a constant +shift expression is an untyped constant, the +result is an integer constant; otherwise it is a constant of the same +type as the left operand, which must be of +integer type. +

+ +

+Any other operation on untyped constants results in an untyped constant of the +same kind; that is, a boolean, integer, floating-point, complex, or string +constant. +If the untyped operands of a binary operation (other than a shift) are of +different kinds, the result is of the operand's kind that appears later in this +list: integer, rune, floating-point, complex. +For example, an untyped integer constant divided by an +untyped complex constant yields an untyped complex constant. +

+ +
+const a = 2 + 3.0          // a == 5.0   (untyped floating-point constant)
+const b = 15 / 4           // b == 3     (untyped integer constant)
+const c = 15 / 4.0         // c == 3.75  (untyped floating-point constant)
+const Θ float64 = 3/2      // Θ == 1.0   (type float64, 3/2 is integer division)
+const Π float64 = 3/2.     // Π == 1.5   (type float64, 3/2. is float division)
+const d = 1 << 3.0         // d == 8     (untyped integer constant)
+const e = 1.0 << 3         // e == 8     (untyped integer constant)
+const f = int32(1) << 33   // illegal    (constant 8589934592 overflows int32)
+const g = float64(2) >> 1  // illegal    (float64(2) is a typed floating-point constant)
+const h = "foo" > "bar"    // h == true  (untyped boolean constant)
+const j = true             // j == true  (untyped boolean constant)
+const k = 'w' + 1          // k == 'x'   (untyped rune constant)
+const l = "hi"             // l == "hi"  (untyped string constant)
+const m = string(k)        // m == "x"   (type string)
+const Σ = 1 - 0.707i       //            (untyped complex constant)
+const Δ = Σ + 2.0e-4       //            (untyped complex constant)
+const Φ = iota*1i - 1/1i   //            (untyped complex constant)
+
+ +

+Applying the built-in function complex to untyped +integer, rune, or floating-point constants yields +an untyped complex constant. +

+ +
+const ic = complex(0, c)   // ic == 3.75i  (untyped complex constant)
+const iΘ = complex(0, Θ)   // iΘ == 1i     (type complex128)
+
+ +

+Constant expressions are always evaluated exactly; intermediate values and the +constants themselves may require precision significantly larger than supported +by any predeclared type in the language. The following are legal declarations: +

+ +
+const Huge = 1 << 100         // Huge == 1267650600228229401496703205376  (untyped integer constant)
+const Four int8 = Huge >> 98  // Four == 4                                (type int8)
+
+ +

+The divisor of a constant division or remainder operation must not be zero: +

+ +
+3.14 / 0.0   // illegal: division by zero
+
+ +

+The values of typed constants must always be accurately +representable by values +of the constant type. The following constant expressions are illegal: +

+ +
+uint(-1)     // -1 cannot be represented as a uint
+int(3.14)    // 3.14 cannot be represented as an int
+int64(Huge)  // 1267650600228229401496703205376 cannot be represented as an int64
+Four * 300   // operand 300 cannot be represented as an int8 (type of Four)
+Four * 100   // product 400 cannot be represented as an int8 (type of Four)
+
+ +

+The mask used by the unary bitwise complement operator ^ matches +the rule for non-constants: the mask is all 1s for unsigned constants +and -1 for signed and untyped constants. +

+ +
+^1         // untyped integer constant, equal to -2
+uint8(^1)  // illegal: same as uint8(-2), -2 cannot be represented as a uint8
+^uint8(1)  // typed uint8 constant, same as 0xFF ^ uint8(1) = uint8(0xFE)
+int8(^1)   // same as int8(-2)
+^int8(1)   // same as -1 ^ int8(1) = -2
+
+ +

+Implementation restriction: A compiler may use rounding while +computing untyped floating-point or complex constant expressions; see +the implementation restriction in the section +on constants. This rounding may cause a +floating-point constant expression to be invalid in an integer +context, even if it would be integral when calculated using infinite +precision, and vice versa. +

+ + +

Order of evaluation

+ +

+At package level, initialization dependencies +determine the evaluation order of individual initialization expressions in +variable declarations. +Otherwise, when evaluating the operands of an +expression, assignment, or +return statement, +all function calls, method calls, +receive operations, +and binary logical operations +are evaluated in lexical left-to-right order. +

+ +

+For example, in the (function-local) assignment +

+
+y[f()], ok = g(z || h(), i()+x[j()], <-c), k()
+
+

+the function calls and communication happen in the order +f(), h() (if z +evaluates to false), i(), j(), +<-c, g(), and k(). +However, the order of those events compared to the evaluation +and indexing of x and the evaluation +of y and z is not specified, +except as required lexically. For instance, g +cannot be called before its arguments are evaluated. +

+ +
+a := 1
+f := func() int { a++; return a }
+x := []int{a, f()}            // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
+m := map[int]int{a: 1, a: 2}  // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
+n := map[int]int{a: f()}      // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
+
+ +

+At package level, initialization dependencies override the left-to-right rule +for individual initialization expressions, but not for operands within each +expression: +

+ +
+var a, b, c = f() + v(), g(), sqr(u()) + v()
+
+func f() int        { return c }
+func g() int        { return a }
+func sqr(x int) int { return x*x }
+
+// functions u and v are independent of all other variables and functions
+
+ +

+The function calls happen in the order +u(), sqr(), v(), +f(), v(), and g(). +

+ +

+Floating-point operations within a single expression are evaluated according to +the associativity of the operators. Explicit parentheses affect the evaluation +by overriding the default associativity. +In the expression x + (y + z) the addition y + z +is performed before adding x. +

+ +

Statements

+ +

+Statements control execution. +

+ +
+Statement  = Declaration | LabeledStmt | SimpleStmt |
+             GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
+             FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
+             DeferStmt .
+
+SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
+
+ +

Terminating statements

+ +

+A terminating statement interrupts the regular flow of control in +a block. The following statements are terminating: +

+ +
    +
  1. + A "return" or + "goto" statement. + +
    +
  2. + +
  3. + A call to the built-in function + panic. + +
    +
  4. + +
  5. + A block in which the statement list ends in a terminating statement. + +
    +
  6. + +
  7. + An "if" statement in which: +
      +
    • the "else" branch is present, and
    • +
    • both branches are terminating statements.
    • +
    +
  8. + +
  9. + A "for" statement in which: +
      +
    • there are no "break" statements referring to the "for" statement, and
    • +
    • the loop condition is absent, and
    • +
    • the "for" statement does not use a range clause.
    • +
    +
  10. + +
  11. + A "switch" statement in which: +
      +
    • there are no "break" statements referring to the "switch" statement,
    • +
    • there is a default case, and
    • +
    • the statement lists in each case, including the default, end in a terminating + statement, or a possibly labeled "fallthrough" + statement.
    • +
    +
  12. + +
  13. + A "select" statement in which: +
      +
    • there are no "break" statements referring to the "select" statement, and
    • +
    • the statement lists in each case, including the default if present, + end in a terminating statement.
    • +
    +
  14. + +
  15. + A labeled statement labeling + a terminating statement. +
  16. +
+ +

+All other statements are not terminating. +

+ +

+A statement list ends in a terminating statement if the list +is not empty and its final non-empty statement is terminating. +

+ + +

Empty statements

+ +

+The empty statement does nothing. +

+ +
+EmptyStmt = .
+
+ + +

Labeled statements

+ +

+A labeled statement may be the target of a goto, +break or continue statement. +

+ +
+LabeledStmt = Label ":" Statement .
+Label       = identifier .
+
+ +
+Error: log.Panic("error encountered")
+
+ + +

Expression statements

+ +

+With the exception of specific built-in functions, +function and method calls and +receive operations +can appear in statement context. Such statements may be parenthesized. +

+ +
+ExpressionStmt = Expression .
+
+ +

+The following built-in functions are not permitted in statement context: +

+ +
+append cap complex imag len make max min new real
+unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice unsafe.SliceData unsafe.String unsafe.StringData
+
+ +
+h(x+y)
+f.Close()
+<-ch
+(<-ch)
+len("foo")  // illegal if len is the built-in function
+
+ + +

Send statements

+ +

+A send statement sends a value on a channel. +The channel expression must be of channel type, +the channel direction must permit send operations, +and the type of the value to be sent must be assignable +to the channel's element type. +

+ +
+SendStmt = Channel "<-" Expression .
+Channel  = Expression .
+
+ +

+Both the channel and the value expression are evaluated before communication +begins. Communication blocks until the send can proceed. +A send on an unbuffered channel can proceed if a receiver is ready. +A send on a buffered channel can proceed if there is room in the buffer. +A send on a closed channel proceeds by causing a run-time panic. +A send on a nil channel blocks forever. +

+ +
+ch <- 3  // send value 3 to channel ch
+
+ +

+If the type of the channel expression is a +type parameter, +all types in its type set must be channel types that permit send operations, +they must all have the same element type, +and the type of the value to be sent must be assignable to that element type. +

+ +

IncDec statements

+ +

+The "++" and "--" statements increment or decrement their operands +by the untyped constant 1. +As with an assignment, the operand must be addressable +or a map index expression. +

+ +
+IncDecStmt = Expression ( "++" | "--" ) .
+
+ +

+The following assignment statements are semantically +equivalent: +

+ +
+IncDec statement    Assignment
+x++                 x += 1
+x--                 x -= 1
+
+ + +

Assignment statements

+ +

+An assignment replaces the current value stored in a variable +with a new value specified by an expression. +An assignment statement may assign a single value to a single variable, or multiple values to a +matching number of variables. +

+ +
+Assignment = ExpressionList assign_op ExpressionList .
+
+assign_op  = [ add_op | mul_op ] "=" .
+
+ +

+Each left-hand side operand must be addressable, +a map index expression, or (for = assignments only) the +blank identifier. +Operands may be parenthesized. +

+ +
+x = 1
+*p = f()
+a[i] = 23
+(k) = <-ch  // same as: k = <-ch
+
+ +

+An assignment operation x op= +y where op is a binary arithmetic operator +is equivalent to x = x op +(y) but evaluates x +only once. The op= construct is a single token. +In assignment operations, both the left- and right-hand expression lists +must contain exactly one single-valued expression, and the left-hand +expression must not be the blank identifier. +

+ +
+a[i] <<= 2
+i &^= 1<<n
+
+ +

+A tuple assignment assigns the individual elements of a multi-valued +operation to a list of variables. There are two forms. In the +first, the right hand operand is a single multi-valued expression +such as a function call, a channel or +map operation, or a type assertion. +The number of operands on the left +hand side must match the number of values. For instance, if +f is a function returning two values, +

+ +
+x, y = f()
+
+ +

+assigns the first value to x and the second to y. +In the second form, the number of operands on the left must equal the number +of expressions on the right, each of which must be single-valued, and the +nth expression on the right is assigned to the nth +operand on the left: +

+ +
+one, two, three = '一', '二', '三'
+
+ +

+The blank identifier provides a way to +ignore right-hand side values in an assignment: +

+ +
+_ = x       // evaluate x but ignore it
+x, _ = f()  // evaluate f() but ignore second result value
+
+ +

+The assignment proceeds in two phases. +First, the operands of index expressions +and pointer indirections +(including implicit pointer indirections in selectors) +on the left and the expressions on the right are all +evaluated in the usual order. +Second, the assignments are carried out in left-to-right order. +

+ +
+a, b = b, a  // exchange a and b
+
+x := []int{1, 2, 3}
+i := 0
+i, x[i] = 1, 2  // set i = 1, x[0] = 2
+
+i = 0
+x[i], i = 2, 1  // set x[0] = 2, i = 1
+
+x[0], x[0] = 1, 2  // set x[0] = 1, then x[0] = 2 (so x[0] == 2 at end)
+
+x[1], x[3] = 4, 5  // set x[1] = 4, then panic setting x[3] = 5.
+
+type Point struct { x, y int }
+var p *Point
+x[2], p.x = 6, 7  // set x[2] = 6, then panic setting p.x = 7
+
+i = 2
+x = []int{3, 5, 7}
+for i, x[i] = range x {  // set i, x[2] = 0, x[0]
+	break
+}
+// after this loop, i == 0 and x is []int{3, 5, 3}
+
+ +

+In assignments, each value must be assignable +to the type of the operand to which it is assigned, with the following special cases: +

+ +
    +
  1. + Any typed value may be assigned to the blank identifier. +
  2. + +
  3. + If an untyped constant + is assigned to a variable of interface type or the blank identifier, + the constant is first implicitly converted to its + default type. +
  4. + +
  5. + If an untyped boolean value is assigned to a variable of interface type or + the blank identifier, it is first implicitly converted to type bool. +
  6. +
+ +

+When a value is assigned to a variable, only the data that is stored in the variable +is replaced. If the value contains a reference, +the assignment copies the reference but does not make a copy of the referenced data +(such as the underlying array of a slice). +

+ +
+var s1 = []int{1, 2, 3}
+var s2 = s1                    // s2 stores the slice descriptor of s1
+s1 = s1[:1]                    // s1's length is 1 but it still shares its underlying array with s2
+s2[0] = 42                     // setting s2[0] changes s1[0] as well
+fmt.Println(s1, s2)            // prints [42] [42 2 3]
+
+var m1 = make(map[string]int)
+var m2 = m1                    // m2 stores the map descriptor of m1
+m1["foo"] = 42                 // setting m1["foo"] changes m2["foo"] as well
+fmt.Println(m2["foo"])         // prints 42
+
+ +

If statements

+ +

+"If" statements specify the conditional execution of two branches +according to the value of a boolean expression. If the expression +evaluates to true, the "if" branch is executed, otherwise, if +present, the "else" branch is executed. +

+ +
+IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
+
+ +
+if x > max {
+	x = max
+}
+
+ +

+The expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+if x := f(); x < y {
+	return x
+} else if x > z {
+	return z
+} else {
+	return y
+}
+
+ + +

Switch statements

+ +

+"Switch" statements provide multi-way execution. +An expression or type is compared to the "cases" +inside the "switch" to determine which branch +to execute. +

+ +
+SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
+
+ +

+There are two forms: expression switches and type switches. +In an expression switch, the cases contain expressions that are compared +against the value of the switch expression. +In a type switch, the cases contain types that are compared against the +type of a specially annotated switch expression. +The switch expression is evaluated exactly once in a switch statement. +

+ +

Expression switches

+ +

+In an expression switch, +the switch expression is evaluated and +the case expressions, which need not be constants, +are evaluated left-to-right and top-to-bottom; the first one that equals the +switch expression +triggers execution of the statements of the associated case; +the other cases are skipped. +If no case matches and there is a "default" case, +its statements are executed. +There can be at most one default case and it may appear anywhere in the +"switch" statement. +A missing switch expression is equivalent to the boolean value +true. +

+ +
+ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
+ExprCaseClause = ExprSwitchCase ":" StatementList .
+ExprSwitchCase = "case" ExpressionList | "default" .
+
+ +

+If the switch expression evaluates to an untyped constant, it is first implicitly +converted to its default type. +The predeclared untyped value nil cannot be used as a switch expression. +The switch expression type must be comparable. +

+ +

+If a case expression is untyped, it is first implicitly converted +to the type of the switch expression. +For each (possibly converted) case expression x and the value t +of the switch expression, x == t must be a valid comparison. +

+ +

+In other words, the switch expression is treated as if it were used to declare and +initialize a temporary variable t without explicit type; it is that +value of t against which each case expression x is tested +for equality. +

+ +

+In a case or default clause, the last non-empty statement +may be a (possibly labeled) +"fallthrough" statement to +indicate that control should flow from the end of this clause to +the first statement of the next clause. +Otherwise control flows to the end of the "switch" statement. +A "fallthrough" statement may appear as the last statement of all +but the last clause of an expression switch. +

+ +

+The switch expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+switch tag {
+default: s3()
+case 0, 1, 2, 3: s1()
+case 4, 5, 6, 7: s2()
+}
+
+switch x := f(); {  // missing switch expression means "true"
+case x < 0: return -x
+default: return x
+}
+
+switch {
+case x < y: f1()
+case x < z: f2()
+case x == 4: f3()
+}
+
+ +

+Implementation restriction: A compiler may disallow multiple case +expressions evaluating to the same constant. +For instance, the current compilers disallow duplicate integer, +floating point, or string constants in case expressions. +

+ +

Type switches

+ +

+A type switch compares types rather than values. It is otherwise similar +to an expression switch. It is marked by a special switch expression that +has the form of a type assertion +using the keyword type rather than an actual type: +

+ +
+switch x.(type) {
+// cases
+}
+
+ +

+Cases then match actual types T against the dynamic type of the +expression x. As with type assertions, x must be of +interface type, but not a +type parameter, and each non-interface type +T listed in a case must implement the type of x. +The types listed in the cases of a type switch must all be +different. +

+ +
+TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
+TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+TypeCaseClause  = TypeSwitchCase ":" StatementList .
+TypeSwitchCase  = "case" TypeList | "default" .
+
+ +

+The TypeSwitchGuard may include a +short variable declaration. +When that form is used, the variable is declared at the end of the +TypeSwitchCase in the implicit block of each clause. +In clauses with a case listing exactly one type, the variable +has that type; otherwise, the variable has the type of the expression +in the TypeSwitchGuard. +

+ +

+Instead of a type, a case may use the predeclared identifier +nil; +that case is selected when the expression in the TypeSwitchGuard +is a nil interface value. +There may be at most one nil case. +

+ +

+Given an expression x of type interface{}, +the following type switch: +

+ +
+switch i := x.(type) {
+case nil:
+	printString("x is nil")                // type of i is type of x (interface{})
+case int:
+	printInt(i)                            // type of i is int
+case float64:
+	printFloat64(i)                        // type of i is float64
+case func(int) float64:
+	printFunction(i)                       // type of i is func(int) float64
+case bool, string:
+	printString("type is bool or string")  // type of i is type of x (interface{})
+default:
+	printString("don't know the type")     // type of i is type of x (interface{})
+}
+
+ +

+could be rewritten: +

+ +
+v := x  // x is evaluated exactly once
+if v == nil {
+	i := v                                 // type of i is type of x (interface{})
+	printString("x is nil")
+} else if i, isInt := v.(int); isInt {
+	printInt(i)                            // type of i is int
+} else if i, isFloat64 := v.(float64); isFloat64 {
+	printFloat64(i)                        // type of i is float64
+} else if i, isFunc := v.(func(int) float64); isFunc {
+	printFunction(i)                       // type of i is func(int) float64
+} else {
+	_, isBool := v.(bool)
+	_, isString := v.(string)
+	if isBool || isString {
+		i := v                         // type of i is type of x (interface{})
+		printString("type is bool or string")
+	} else {
+		i := v                         // type of i is type of x (interface{})
+		printString("don't know the type")
+	}
+}
+
+ +

+A type parameter or a generic type +may be used as a type in a case. If upon instantiation that type turns +out to duplicate another entry in the switch, the first matching case is chosen. +

+ +
+func f[P any](x any) int {
+	switch x.(type) {
+	case P:
+		return 0
+	case string:
+		return 1
+	case []P:
+		return 2
+	case []byte:
+		return 3
+	default:
+		return 4
+	}
+}
+
+var v1 = f[string]("foo")   // v1 == 0
+var v2 = f[byte]([]byte{})  // v2 == 2
+
+ +

+The type switch guard may be preceded by a simple statement, which +executes before the guard is evaluated. +

+ +

+The "fallthrough" statement is not permitted in a type switch. +

+ +

For statements

+ +

+A "for" statement specifies repeated execution of a block. There are three forms: +The iteration may be controlled by a single condition, a "for" clause, or a "range" clause. +

+ +
+ForStmt   = "for" [ Condition | ForClause | RangeClause ] Block .
+Condition = Expression .
+
+ +

For statements with single condition

+ +

+In its simplest form, a "for" statement specifies the repeated execution of +a block as long as a boolean condition evaluates to true. +The condition is evaluated before each iteration. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for a < b {
+	a *= 2
+}
+
+ +

For statements with for clause

+ +

+A "for" statement with a ForClause is also controlled by its condition, but +additionally it may specify an init +and a post statement, such as an assignment, +an increment or decrement statement. The init statement may be a +short variable declaration, but the post statement must not. +

+ +
+ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
+InitStmt  = SimpleStmt .
+PostStmt  = SimpleStmt .
+
+ +
+for i := 0; i < 10; i++ {
+	f(i)
+}
+
+ +

+If non-empty, the init statement is executed once before evaluating the +condition for the first iteration; +the post statement is executed after each execution of the block (and +only if the block was executed). +Any element of the ForClause may be empty but the +semicolons are +required unless there is only a condition. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for cond { S() }    is the same as    for ; cond ; { S() }
+for      { S() }    is the same as    for true     { S() }
+
+ +

+Each iteration has its own separate declared variable (or variables) +[Go 1.22]. +The variable used by the first iteration is declared by the init statement. +The variable used by each subsequent iteration is declared implicitly before +executing the post statement and initialized to the value of the previous +iteration's variable at that moment. +

+ +
+var prints []func()
+for i := 0; i < 5; i++ {
+	prints = append(prints, func() { println(i) })
+	i++
+}
+for _, p := range prints {
+	p()
+}
+
+ +

+prints +

+ +
+1
+3
+5
+
+ +

+Prior to [Go 1.22], iterations share one set of variables +instead of having their own separate variables. +In that case, the example above prints +

+ +
+6
+6
+6
+
+ +

For statements with range clause

+ +

+A "for" statement with a "range" clause +iterates through all entries of an array, slice, string or map, values received on +a channel, integer values from zero to an upper limit [Go 1.22], +or values passed to an iterator function's yield function [Go 1.23]. +For each entry it assigns iteration values +to corresponding iteration variables if present and then executes the block. +

+ +
+RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
+
+ +

+The expression on the right in the "range" clause is called the range expression, +which may be an array, pointer to an array, slice, string, map, channel permitting +receive operations, an integer, or +a function with specific signature (see below). +As with an assignment, if present the operands on the left must be +addressable or map index expressions; they +denote the iteration variables. +If the range expression is a function, the maximum number of iteration variables depends on +the function signature. +If the range expression is a channel or integer, at most one iteration variable is permitted; +otherwise there may be up to two. +If the last iteration variable is the blank identifier, +the range clause is equivalent to the same clause without that identifier. +

+ +

+The range expression x is evaluated before beginning the loop, +with one exception: if at most one iteration variable is present and x or +len(x) is constant, +the range expression is not evaluated. +

+ +

+Function calls on the left are evaluated once per iteration. +For each iteration, iteration values are produced as follows +if the respective iteration variables are present: +

+ +
+Range expression                                       1st value                2nd value
+
+array or slice      a  [n]E, *[n]E, or []E             index    i  int          a[i]       E
+string              s  string type                     index    i  int          see below  rune
+map                 m  map[K]V                         key      k  K            m[k]       V
+channel             c  chan E, <-chan E                element  e  E
+integer value       n  integer type, or untyped int    value    i  see below
+function, 0 values  f  func(yield func() bool)
+function, 1 value   f  func(yield func(V) bool)        value    v  V                               yield cannot be variadic
+function, 2 values  f  func(yield func(K, V) bool)     key      k  K            v          V       yield cannot be variadic
+
+ +
    +
  1. +For an array, pointer to array, or slice value a, the index iteration +values are produced in increasing order, starting at element index 0. +If at most one iteration variable is present, the range loop produces +iteration values from 0 up to len(a)-1 and does not index into the array +or slice itself. For a nil slice, the number of iterations is 0. +
  2. + +
  3. +For a string value, the "range" clause iterates over the Unicode code points +in the string starting at byte index 0. On successive iterations, the index value will be the +index of the first byte of successive UTF-8-encoded code points in the string, +and the second value, of type rune, will be the value of +the corresponding code point. If the iteration encounters an invalid +UTF-8 sequence, the second value will be 0xFFFD, +the Unicode replacement character, and the next iteration will advance +a single byte in the string. +
  4. + +
  5. +The iteration order over maps is not specified +and is not guaranteed to be the same from one iteration to the next. +If a map entry that has not yet been reached is removed during iteration, +the corresponding iteration value will not be produced. If a map entry is +created during iteration, that entry may be produced during the iteration or +may be skipped. The choice may vary for each entry created and from one +iteration to the next. +If the map is nil, the number of iterations is 0. +
  6. + +
  7. +For channels, the iteration values produced are the successive values sent on +the channel until the channel is closed. If the channel +is nil, the range expression blocks forever. +
  8. + +
  9. +For an integer value n, where n is of integer type +or an untyped integer constant, the iteration values 0 through n-1 +are produced in increasing order. +If n is of integer type, the iteration values have that same type. +Otherwise, the type of n is determined as if it were assigned to the +iteration variable. +Specifically: +if the iteration variable is preexisting, the type of the iteration values is the type of the iteration +variable, which must be of integer type. +Otherwise, if the iteration variable is declared by the "range" clause or is absent, +the type of the iteration values is the default type for n. +If n <= 0, the loop does not run any iterations. +
  10. + +
  11. +For a function f, the iteration proceeds by calling f +with a new, synthesized yield function as its argument. +If yield is called before f returns, +the arguments to yield become the iteration values +for executing the loop body once. +After each successive loop iteration, yield returns true +and may be called again to continue the loop. +As long as the loop body does not terminate, the "range" clause will continue +to generate iteration values this way for each yield call until +f returns. +If the loop body terminates (such as by a break statement), +yield returns false and must not be called again. +
  12. +
+ +

+If the type of the range expression is a type parameter, +all types in its type set must have the same underlying type and the range expression must be valid +for that type, or, if the type set contains channel types, it must only contain channel types with +identical element types, and all channel types must permit receive operations. +

+ +

+The iteration variables may be declared by the "range" clause using a form of +short variable declaration +(:=). +In this case their scope is the block of the "for" statement +and each iteration has its own new variables [Go 1.22] +(see also "for" statements with a ForClause). +The variables have the types of their respective iteration values. +

+ +

+If the iteration variables are not explicitly declared by the "range" clause, +they must be preexisting. +In this case, the iteration values are assigned to the respective variables +as in an assignment statement. +

+ +
+var testdata *struct {
+	a *[7]int
+}
+for i, _ := range testdata.a {
+	// testdata.a is never evaluated; len(testdata.a) is constant
+	// i ranges from 0 to 6
+	f(i)
+}
+
+var a [10]string
+for i, s := range a {
+	// type of i is int
+	// type of s is string
+	// s == a[i]
+	g(i, s)
+}
+
+var key string
+var val interface{}  // element type of m is assignable to val
+m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
+for key, val = range m {
+	h(key, val)
+}
+// key == last map key encountered in iteration
+// val == map[key]
+
+var ch chan Work = producer()
+for w := range ch {
+	doWork(w)
+}
+
+// empty a channel
+for range ch {}
+
+// call f(0), f(1), ... f(9)
+for i := range 10 {
+	// type of i is int (default type for untyped constant 10)
+	f(i)
+}
+
+// invalid: 256 cannot be assigned to uint8
+var u uint8
+for u = range 256 {
+}
+
+// invalid: 1e3 is a floating-point constant
+for range 1e3 {
+}
+
+// fibo generates the Fibonacci sequence
+fibo := func(yield func(x int) bool) {
+	f0, f1 := 0, 1
+	for yield(f0) {
+		f0, f1 = f1, f0+f1
+	}
+}
+
+// print the Fibonacci numbers below 1000:
+for x := range fibo {
+	if x >= 1000 {
+		break
+	}
+	fmt.Printf("%d ", x)
+}
+// output: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
+
+// iteration support for a recursive tree data structure
+type Tree[K cmp.Ordered, V any] struct {
+	left, right *Tree[K, V]
+	key         K
+	value       V
+}
+
+func (t *Tree[K, V]) walk(yield func(key K, val V) bool) bool {
+	return t == nil || t.left.walk(yield) && yield(t.key, t.value) && t.right.walk(yield)
+}
+
+func (t *Tree[K, V]) Walk(yield func(key K, val V) bool) {
+	t.walk(yield)
+}
+
+// walk tree t in-order
+var t Tree[string, int]
+for k, v := range t.Walk {
+	// process k, v
+}
+
+// xor returns the xor-ed bytes of S
+func xor[S ~[]byte](s S) byte {
+	var r byte
+	for _, b := range s {
+		r ^= b
+	}
+	return r
+}
+
+ +

Go statements

+ +

+A "go" statement starts the execution of a function call +as an independent concurrent thread of control, or goroutine, +within the same address space. +

+ +
+GoStmt = "go" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+The function value and parameters are +evaluated as usual +in the calling goroutine, but +unlike with a regular call, program execution does not wait +for the invoked function to complete. +Instead, the function begins executing independently +in a new goroutine. +When the function terminates, its goroutine also terminates. +If the function has any return values, they are discarded when the +function completes. +

+ +
+go Server()
+go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c)
+
+ + +

Select statements

+ +

+A "select" statement chooses which of a set of possible +send or +receive +operations will proceed. +It looks similar to a +"switch" statement but with the +cases all referring to communication operations. +

+ +
+SelectStmt = "select" "{" { CommClause } "}" .
+CommClause = CommCase ":" StatementList .
+CommCase   = "case" ( SendStmt | RecvStmt ) | "default" .
+RecvStmt   = [ ExpressionList "=" | IdentifierList ":=" ] RecvExpr .
+RecvExpr   = Expression .
+
+ +

+A case with a RecvStmt may assign the result of a RecvExpr to one or +two variables, which may be declared using a +short variable declaration. +The RecvExpr must be a (possibly parenthesized) receive operation. +There can be at most one default case and it may appear anywhere +in the list of cases. +

+ +

+Execution of a "select" statement proceeds in several steps: +

+ +
    +
  1. +For all the cases in the statement, the channel operands of receive operations +and the channel and right-hand-side expressions of send statements are +evaluated exactly once, in source order, upon entering the "select" statement. +The result is a set of channels to receive from or send to, +and the corresponding values to send. +Any side effects in that evaluation will occur irrespective of which (if any) +communication operation is selected to proceed. +Expressions on the left-hand side of a RecvStmt with a short variable declaration +or assignment are not yet evaluated. +
  2. + +
  3. +If one or more of the communications can proceed, +a single one that can proceed is chosen via a uniform pseudo-random selection. +Otherwise, if there is a default case, that case is chosen. +If there is no default case, the "select" statement blocks until +at least one of the communications can proceed. +
  4. + +
  5. +Unless the selected case is the default case, the respective communication +operation is executed. +
  6. + +
  7. +If the selected case is a RecvStmt with a short variable declaration or +an assignment, the left-hand side expressions are evaluated and the +received value (or values) are assigned. +
  8. + +
  9. +The statement list of the selected case is executed. +
  10. +
+ +

+Since communication on nil channels can never proceed, +a select with only nil channels and no default case blocks forever. +

+ +
+var a []int
+var c, c1, c2, c3, c4 chan int
+var i1, i2 int
+select {
+case i1 = <-c1:
+	print("received ", i1, " from c1\n")
+case c2 <- i2:
+	print("sent ", i2, " to c2\n")
+case i3, ok := (<-c3):  // same as: i3, ok := <-c3
+	if ok {
+		print("received ", i3, " from c3\n")
+	} else {
+		print("c3 is closed\n")
+	}
+case a[f()] = <-c4:
+	// same as:
+	// case t := <-c4
+	//	a[f()] = t
+default:
+	print("no communication\n")
+}
+
+for {  // send random sequence of bits to c
+	select {
+	case c <- 0:  // note: no statement, no fallthrough, no folding of cases
+	case c <- 1:
+	}
+}
+
+select {}  // block forever
+
+ + +

Return statements

+ +

+A "return" statement in a function F terminates the execution +of F, and optionally provides one or more result values. +Any functions deferred by F +are executed before F returns to its caller. +

+ +
+ReturnStmt = "return" [ ExpressionList ] .
+
+ +

+In a function without a result type, a "return" statement must not +specify any result values. +

+
+func noResult() {
+	return
+}
+
+ +

+There are three ways to return values from a function with a result +type: +

+ +
    +
  1. The return value or values may be explicitly listed + in the "return" statement. Each expression must be single-valued + and assignable + to the corresponding element of the function's result type. +
    +func simpleF() int {
    +	return 2
    +}
    +
    +func complexF1() (re float64, im float64) {
    +	return -7.0, -4.0
    +}
    +
    +
  2. +
  3. The expression list in the "return" statement may be a single + call to a multi-valued function. The effect is as if each value + returned from that function were assigned to a temporary + variable with the type of the respective value, followed by a + "return" statement listing these variables, at which point the + rules of the previous case apply. +
    +func complexF2() (re float64, im float64) {
    +	return complexF1()
    +}
    +
    +
  4. +
  5. The expression list may be empty if the function's result + type specifies names for its result parameters. + The result parameters act as ordinary local variables + and the function may assign values to them as necessary. + The "return" statement returns the values of these variables. +
    +func complexF3() (re float64, im float64) {
    +	re = 7.0
    +	im = 4.0
    +	return
    +}
    +
    +func (devnull) Write(p []byte) (n int, _ error) {
    +	n = len(p)
    +	return
    +}
    +
    +
  6. +
+ +

+Regardless of how they are declared, all the result values are initialized to +the zero values for their type upon entry to the +function. A "return" statement that specifies results sets the result parameters before +any deferred functions are executed. +

+ +

+Implementation restriction: A compiler may disallow an empty expression list +in a "return" statement if a different entity (constant, type, or variable) +with the same name as a result parameter is in +scope at the place of the return. +

+ +
+func f(n int) (res int, err error) {
+	if _, err := f(n-1); err != nil {
+		return  // invalid return statement: err is shadowed
+	}
+	return
+}
+
+ +

Break statements

+ +

+A "break" statement terminates execution of the innermost +"for", +"switch", or +"select" statement +within the same function. +

+ +
+BreakStmt = "break" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for", "switch", or "select" statement, +and that is the one whose execution terminates. +

+ +
+OuterLoop:
+	for i = 0; i < n; i++ {
+		for j = 0; j < m; j++ {
+			switch a[i][j] {
+			case nil:
+				state = Error
+				break OuterLoop
+			case item:
+				state = Found
+				break OuterLoop
+			}
+		}
+	}
+
+ +

Continue statements

+ +

+A "continue" statement begins the next iteration of the +innermost enclosing "for" loop +by advancing control to the end of the loop block. +The "for" loop must be within the same function. +

+ +
+ContinueStmt = "continue" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for" statement, and that is the one whose execution +advances. +

+ +
+RowLoop:
+	for y, row := range rows {
+		for x, data := range row {
+			if data == endOfRow {
+				continue RowLoop
+			}
+			row[x] = data + bias(x, y)
+		}
+	}
+
+ +

Goto statements

+ +

+A "goto" statement transfers control to the statement with the corresponding label +within the same function. +

+ +
+GotoStmt = "goto" Label .
+
+ +
+goto Error
+
+ +

+Executing the "goto" statement must not cause any variables to come into +scope that were not already in scope at the point of the goto. +For instance, this example: +

+ +
+	goto L  // BAD
+	v := 3
+L:
+
+ +

+is erroneous because the jump to label L skips +the creation of v. +

+ +

+A "goto" statement outside a block cannot jump to a label inside that block. +For instance, this example: +

+ +
+if n%2 == 1 {
+	goto L1
+}
+for n > 0 {
+	f()
+	n--
+L1:
+	f()
+	n--
+}
+
+ +

+is erroneous because the label L1 is inside +the "for" statement's block but the goto is not. +

+ +

Fallthrough statements

+ +

+A "fallthrough" statement transfers control to the first statement of the +next case clause in an expression "switch" statement. +It may be used only as the final non-empty statement in such a clause. +

+ +
+FallthroughStmt = "fallthrough" .
+
+ + +

Defer statements

+ +

+A "defer" statement invokes a function whose execution is deferred +to the moment the surrounding function returns, either because the +surrounding function executed a return statement, +reached the end of its function body, +or because the corresponding goroutine is panicking. +

+ +
+DeferStmt = "defer" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+Each time a "defer" statement +executes, the function value and parameters to the call are +evaluated as usual +and saved anew but the actual function is not invoked. +Instead, deferred functions are invoked immediately before +the surrounding function returns, in the reverse order +they were deferred. That is, if the surrounding function +returns through an explicit return statement, +deferred functions are executed after any result parameters are set +by that return statement but before the function returns to its caller. +If a deferred function value evaluates +to nil, execution panics +when the function is invoked, not when the "defer" statement is executed. +

+ +

+For instance, if the deferred function is +a function literal and the surrounding +function has named result parameters that +are in scope within the literal, the deferred function may access and modify +the result parameters before they are returned. +If the deferred function has any return values, they are discarded when +the function completes. +(See also the section on handling panics.) +

+ +
+lock(l)
+defer unlock(l)  // unlocking happens before surrounding function returns
+
+// prints 3 2 1 0 before surrounding function returns
+for i := 0; i <= 3; i++ {
+	defer fmt.Print(i)
+}
+
+// f returns 42
+func f() (result int) {
+	defer func() {
+		// result is accessed after it was set to 6 by the return statement
+		result *= 7
+	}()
+	return 6
+}
+
+ +

Built-in functions

+ +

+Built-in functions are +predeclared. +They are called like any other function but some of them +accept a type instead of an expression as the first argument. +

+ +

+The built-in functions do not have standard Go types, +so they can only appear in call expressions; +they cannot be used as function values. +

+ + +

Appending to and copying slices

+ +

+The built-in functions append and copy assist in +common slice operations. +For both functions, the result is independent of whether the memory referenced +by the arguments overlaps. +

+ +

+The variadic function append +appends zero or more values x to a slice s of +type S and returns the resulting slice, also of type +S. +The values x are passed to a parameter of type ...E +where E is the element type of S +and the respective parameter +passing rules apply. +As a special case, append also accepts a slice whose type is assignable to +type []byte with a second argument of string type followed by +.... +This form appends the bytes of the string. +

+ +
+append(s S, x ...E) S  // E is the element type of S
+
+ +

+If S is a type parameter, +all types in its type set must have the same underlying slice type []E. +

+ +

+If the capacity of s is not large enough to fit the additional +values, append allocates a new, sufficiently large underlying +array that fits both the existing slice elements and the additional values. +Otherwise, append re-uses the underlying array. +

+ +
+s0 := []int{0, 0}
+s1 := append(s0, 2)                // append a single element     s1 is []int{0, 0, 2}
+s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 is []int{0, 0, 2, 3, 5, 7}
+s3 := append(s2, s0...)            // append a slice              s3 is []int{0, 0, 2, 3, 5, 7, 0, 0}
+s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 is []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+var t []interface{}
+t = append(t, 42, 3.1415, "foo")   //                             t is []interface{}{42, 3.1415, "foo"}
+
+var b []byte
+b = append(b, "bar"...)            // append string contents      b is []byte{'b', 'a', 'r' }
+
+ +

+The function copy copies slice elements from +a source src to a destination dst and returns the +number of elements copied. +Both arguments must have identical element type +E and must be assignable to a slice of type []E. +The number of elements copied is the minimum of +len(src) and len(dst). +As a special case, copy also accepts a destination argument +assignable to type []byte with a source argument of a +string type. +This form copies the bytes from the string into the byte slice. +

+ +
+copy(dst, src []T) int
+copy(dst []byte, src string) int
+
+ +

+If the type of one or both arguments is a type parameter, +all types in their respective type sets must have the same underlying slice type []E. +

+ +

+Examples: +

+ +
+var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+var s = make([]int, 6)
+var b = make([]byte, 5)
+n1 := copy(s, a[0:])            // n1 == 6, s is []int{0, 1, 2, 3, 4, 5}
+n2 := copy(s, s[2:])            // n2 == 4, s is []int{2, 3, 4, 5, 4, 5}
+n3 := copy(b, "Hello, World!")  // n3 == 5, b is []byte("Hello")
+
+ + +

Clear

+ +

+The built-in function clear takes an argument of map, +slice, or type parameter type, +and deletes or zeroes out all elements +[Go 1.21]. +

+ +
+Call        Argument type     Result
+
+clear(m)    map[K]T           deletes all entries, resulting in an
+                              empty map (len(m) == 0)
+
+clear(s)    []T               sets all elements up to the length of
+                              s to the zero value of T
+
+clear(t)    type parameter    see below
+
+ +

+If the type of the argument to clear is a +type parameter, +all types in its type set must be maps or slices, and clear +performs the operation corresponding to the actual type argument. +

+ +

+If the map or slice is nil, clear is a no-op. +

+ + +

Close

+ +

+For a channel ch, the built-in function close(ch) +records that no more values will be sent on the channel. +It is an error if ch is a receive-only channel. +Sending to or closing a closed channel causes a run-time panic. +Closing the nil channel also causes a run-time panic. +After calling close, and after any previously +sent values have been received, receive operations will return +the zero value for the channel's type without blocking. +The multi-valued receive operation +returns a received value along with an indication of whether the channel is closed. +

+ +

+If the type of the argument to close is a +type parameter, +all types in its type set must be channels. +It is an error if any of those channels is a receive-only channel. +

+ +

Manipulating complex numbers

+ +

+Three functions assemble and disassemble complex numbers. +The built-in function complex constructs a complex +value from a floating-point real and imaginary part, while +real and imag +extract the real and imaginary parts of a complex value. +

+ +
+complex(realPart, imaginaryPart floatT) complexT
+real(complexT) floatT
+imag(complexT) floatT
+
+ +

+The type of the arguments and return value correspond. +For complex, the two arguments must be of the same +floating-point type and the return type is the +complex type +with the corresponding floating-point constituents: +complex64 for float32 arguments, and +complex128 for float64 arguments. +If one of the arguments evaluates to an untyped constant, it is first implicitly +converted to the type of the other argument. +If both arguments evaluate to untyped constants, they must be non-complex +numbers or their imaginary parts must be zero, and the return value of +the function is an untyped complex constant. +

+ +

+For real and imag, the argument must be +of complex type, and the return type is the corresponding floating-point +type: float32 for a complex64 argument, and +float64 for a complex128 argument. +If the argument evaluates to an untyped constant, it must be a number, +and the return value of the function is an untyped floating-point constant. +

+ +

+The real and imag functions together form the inverse of +complex, so for a value z of a complex type Z, +z == Z(complex(real(z), imag(z))). +

+ +

+If the operands of these functions are all constants, the return +value is a constant. +

+ +
+var a = complex(2, -2)             // complex128
+const b = complex(1.0, -1.4)       // untyped complex constant 1 - 1.4i
+x := float32(math.Cos(math.Pi/2))  // float32
+var c64 = complex(5, -x)           // complex64
+var s int = complex(1, 0)          // untyped complex constant 1 + 0i can be converted to int
+_ = complex(1, 2<<s)               // illegal: 2 assumes floating-point type, cannot shift
+var rl = real(c64)                 // float32
+var im = imag(a)                   // float64
+const c = imag(b)                  // untyped constant -1.4
+_ = imag(3 << s)                   // illegal: 3 assumes complex type, cannot shift
+
+ +

+Arguments of type parameter type are not permitted. +

+ + +

Deletion of map elements

+ +

+The built-in function delete removes the element with key +k from a map m. The +value k must be assignable +to the key type of m. +

+ +
+delete(m, k)  // remove element m[k] from map m
+
+ +

+If the type of m is a type parameter, +all types in that type set must be maps, and they must all have identical key types. +

+ +

+If the map m is nil or the element m[k] +does not exist, delete is a no-op. +

+ + +

Length and capacity

+ +

+The built-in functions len and cap take arguments +of various types and return a result of type int. +The implementation guarantees that the result always fits into an int. +

+ +
+Call      Argument type    Result
+
+len(s)    string type      string length in bytes
+          [n]T, *[n]T      array length (== n)
+          []T              slice length
+          map[K]T          map length (number of defined keys)
+          chan T           number of elements queued in channel buffer
+          type parameter   see below
+
+cap(s)    [n]T, *[n]T      array length (== n)
+          []T              slice capacity
+          chan T           channel buffer capacity
+          type parameter   see below
+
+ +

+If the argument type is a type parameter P, +the call len(e) (or cap(e) respectively) must be valid for +each type in P's type set. +The result is the length (or capacity, respectively) of the argument whose type +corresponds to the type argument with which P was +instantiated. +

+ +

+The capacity of a slice is the number of elements for which there is +space allocated in the underlying array. +At any time the following relationship holds: +

+ +
+0 <= len(s) <= cap(s)
+
+ +

+The length of a nil slice, map or channel is 0. +The capacity of a nil slice or channel is 0. +

+ +

+The expression len(s) is constant if +s is a string constant. The expressions len(s) and +cap(s) are constants if the type of s is an array +or pointer to an array and the expression s does not contain +channel receives or (non-constant) +function calls; in this case s is not evaluated. +Otherwise, invocations of len and cap are not +constant and s is evaluated. +

+ +
+const (
+	c1 = imag(2i)                    // imag(2i) = 2.0 is a constant
+	c2 = len([10]float64{2})         // [10]float64{2} contains no function calls
+	c3 = len([10]float64{c1})        // [10]float64{c1} contains no function calls
+	c4 = len([10]float64{imag(2i)})  // imag(2i) is a constant and no function call is issued
+	c5 = len([10]float64{imag(z)})   // invalid: imag(z) is a (non-constant) function call
+)
+var z complex128
+
+ + +

Making slices, maps and channels

+ +

+The built-in function make takes a type T, +which must be a slice, map or channel type, or a type parameter, +optionally followed by a type-specific list of expressions. +It returns a value of type T (not *T). +The memory is initialized as described in the section on +initial values. +

+ +
+Call             Type T            Result
+
+make(T, n)       slice             slice of type T with length n and capacity n
+make(T, n, m)    slice             slice of type T with length n and capacity m
+
+make(T)          map               map of type T
+make(T, n)       map               map of type T with initial space for approximately n elements
+
+make(T)          channel           unbuffered channel of type T
+make(T, n)       channel           buffered channel of type T, buffer size n
+
+make(T, n)       type parameter    see below
+make(T, n, m)    type parameter    see below
+
+ +

+If the first argument is a type parameter, +all types in its type set must have the same underlying type, which must be a slice +or map type, or, if there are channel types, there must only be channel types, they +must all have the same element type, and the channel directions must not conflict. +

+ +

+Each of the size arguments n and m must be of integer type, +have a type set containing only integer types, +or be an untyped constant. +A constant size argument must be non-negative and representable +by a value of type int; if it is an untyped constant it is given type int. +If both n and m are provided and are constant, then +n must be no larger than m. +For slices and channels, if n is negative or larger than m at run time, +a run-time panic occurs. +

+ +
+s := make([]int, 10, 100)       // slice with len(s) == 10, cap(s) == 100
+s := make([]int, 1e3)           // slice with len(s) == cap(s) == 1000
+s := make([]int, 1<<63)         // illegal: len(s) is not representable by a value of type int
+s := make([]int, 10, 0)         // illegal: len(s) > cap(s)
+c := make(chan int, 10)         // channel with a buffer size of 10
+m := make(map[string]int, 100)  // map with initial space for approximately 100 elements
+
+ +

+Calling make with a map type and size hint n will +create a map with initial space to hold n map elements. +The precise behavior is implementation-dependent. +

+ + +

Min and max

+ +

+The built-in functions min and max compute the +smallest—or largest, respectively—value of a fixed number of +arguments of ordered types. +There must be at least one argument +[Go 1.21]. +

+ +

+The same type rules as for operators apply: +for ordered arguments x and +y, min(x, y) is valid if x + y is valid, +and the type of min(x, y) is the type of x + y +(and similarly for max). +If all arguments are constant, the result is constant. +

+ +
+var x, y int
+m := min(x)                 // m == x
+m := min(x, y)              // m is the smaller of x and y
+m := max(x, y, 10)          // m is the larger of x and y but at least 10
+c := max(1, 2.0, 10)        // c == 10.0 (floating-point kind)
+f := max(0, float32(x))     // type of f is float32
+var s []string
+_ = min(s...)               // invalid: slice arguments are not permitted
+t := max("", "foo", "bar")  // t == "foo" (string kind)
+
+ +

+For numeric arguments, assuming all NaNs are equal, min and max are +commutative and associative: +

+ +
+min(x, y)    == min(y, x)
+min(x, y, z) == min(min(x, y), z) == min(x, min(y, z))
+
+ +

+For floating-point arguments negative zero, NaN, and infinity the following rules apply: +

+ +
+   x        y    min(x, y)    max(x, y)
+
+  -0.0    0.0         -0.0          0.0    // negative zero is smaller than (non-negative) zero
+  -Inf      y         -Inf            y    // negative infinity is smaller than any other number
+  +Inf      y            y         +Inf    // positive infinity is larger than any other number
+   NaN      y          NaN          NaN    // if any argument is a NaN, the result is a NaN
+
+ +

+For string arguments the result for min is the first argument +with the smallest (or for max, largest) value, +compared lexically byte-wise: +

+ +
+min(x, y)    == if x <= y then x else y
+min(x, y, z) == min(min(x, y), z)
+
+ +

Allocation

+ +

+The built-in function new creates a new, initialized +variable and returns +a pointer to it. +It accepts a single argument, which may be either a type or an expression. +

+ +

+If the argument is a type T, then new(T) +allocates a variable of type T initialized to its +zero value. +

+ +

+If the argument is an expression x, then new(x) +allocates a variable of the type of x initialized to the value of x. +If that value is an untyped constant, it is first implicitly converted +to its default type; +if it is an untyped boolean value, it is first implicitly converted to type bool. +The predeclared identifier nil cannot be used as an argument to new. +

+ +

+For example, new(int) and new(123) each +return a pointer to a new variable of type int. +The value of the first variable is 0, and the value +of the second is 123. Similarly +

+ +
+type S struct { a int; b float64 }
+new(S)
+
+ +

+allocates a variable of type S, +initializes it (a=0, b=0.0), +and returns a value of type *S containing the address +of the variable. +

+ +

Handling panics

+ +

Two built-in functions, panic and recover, +assist in reporting and handling run-time panics +and program-defined error conditions. +

+ +
+func panic(interface{})
+func recover() interface{}
+
+ +

+While executing a function F, +an explicit call to panic or a run-time panic +terminates the execution of F. +Any functions deferred by F +are then executed as usual. +Next, any deferred functions run by F's caller are run, +and so on up to any deferred by the top-level function in the executing goroutine. +At that point, the program is terminated and the error +condition is reported, including the value of the argument to panic. +This termination sequence is called panicking. +

+ +
+panic(42)
+panic("unreachable")
+panic(Error("cannot parse"))
+
+ +

+The recover function allows a program to manage behavior +of a panicking goroutine. +Suppose a function G defers a function D that calls +recover and a panic occurs in a function on the same goroutine in which G +is executing. +When the running of deferred functions reaches D, +the return value of D's call to recover will be the value passed to the call of panic. +If D returns normally, without starting a new +panic, the panicking sequence stops. In that case, +the state of functions called between G and the call to panic +is discarded, and normal execution resumes. +Any functions deferred by G before D are then run and G's +execution terminates by returning to its caller. +

+ +

+The return value of recover is nil when the +goroutine is not panicking or recover was not called directly by a deferred function. +Conversely, if a goroutine is panicking and recover was called directly by a deferred function, +the return value of recover is guaranteed not to be nil. +To ensure this, calling panic with a nil interface value (or an untyped nil) +causes a run-time panic. +

+ +

+The protect function in the example below invokes +the function argument g and protects callers from +run-time panics caused by g. +

+ +
+func protect(g func()) {
+	defer func() {
+		log.Println("done")  // Println executes normally even if there is a panic
+		if x := recover(); x != nil {
+			log.Printf("run time panic: %v", x)
+		}
+	}()
+	log.Println("start")
+	g()
+}
+
+ + +

Bootstrapping

+ +

+Current implementations provide several built-in functions useful during +bootstrapping. These functions are documented for completeness but are not +guaranteed to stay in the language. They do not return a result. +

+ +
+Function   Behavior
+
+print      prints all arguments; formatting of arguments is implementation-specific
+println    like print but prints spaces between arguments and a newline at the end
+
+ +

+Implementation restriction: print and println need not +accept arbitrary argument types, but printing of boolean, numeric, and string +types must be supported. +

+ + +

Packages

+ +

+Go programs are constructed by linking together packages. +A package in turn is constructed from one or more source files +that together declare constants, types, variables and functions +belonging to the package and which are accessible in all files +of the same package. Those elements may be +exported and used in another package. +

+ +

Source file organization

+ +

+Each source file consists of a package clause defining the package +to which it belongs, followed by a possibly empty set of import +declarations that declare packages whose contents it wishes to use, +followed by a possibly empty set of declarations of functions, +types, variables, and constants. +

+ +
+SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
+
+ +

Package clause

+ +

+A package clause begins each source file and defines the package +to which the file belongs. +

+ +
+PackageClause = "package" PackageName .
+PackageName   = identifier .
+
+ +

+The PackageName must not be the blank identifier. +

+ +
+package math
+
+ +

+A set of files sharing the same PackageName form the implementation of a package. +An implementation may require that all source files for a package inhabit the same directory. +

+ +

Import declarations

+ +

+An import declaration states that the source file containing the declaration +depends on functionality of the imported package +(§Program initialization and execution) +and enables access to exported identifiers +of that package. +The import names an identifier (PackageName) to be used for access and an ImportPath +that specifies the package to be imported. +

+ +
+ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
+ImportSpec = [ "." | PackageName ] ImportPath .
+ImportPath = string_lit .
+
+ +

+The PackageName is used in qualified identifiers +to access exported identifiers of the package within the importing source file. +It is declared in the file block. +If the PackageName is omitted, it defaults to the identifier specified in the +package clause of the imported package. +If an explicit period (.) appears instead of a name, all the +package's exported identifiers declared in that package's +package block will be declared in the importing source +file's file block and must be accessed without a qualifier. +

+ +

+The interpretation of the ImportPath is implementation-dependent but +it is typically a substring of the full file name of the compiled +package and may be relative to a repository of installed packages. +

+ +

+Implementation restriction: A compiler may restrict ImportPaths to +non-empty strings using only characters belonging to +Unicode's +L, M, N, P, and S general categories (the Graphic characters without +spaces) and may also exclude the characters +!"#$%&'()*,:;<=>?[\]^`{|} +and the Unicode replacement character U+FFFD. +

+ +

+Consider a compiled a package containing the package clause +package math, which exports function Sin, and +installed the compiled package in the file identified by +"lib/math". +This table illustrates how Sin is accessed in files +that import the package after the +various types of import declaration. +

+ +
+Import declaration          Local name of Sin
+
+import   "lib/math"         math.Sin
+import m "lib/math"         m.Sin
+import . "lib/math"         Sin
+
+ +

+An import declaration declares a dependency relation between +the importing and imported package. +It is illegal for a package to import itself, directly or indirectly, +or to directly import a package without +referring to any of its exported identifiers. To import a package solely for +its side-effects (initialization), use the blank +identifier as explicit package name: +

+ +
+import _ "lib/math"
+
+ + +

An example package

+ +

+Here is a complete Go package that implements a concurrent prime sieve. +

+ +
+package main
+
+import "fmt"
+
+// Send the sequence 2, 3, 4, … to channel 'ch'.
+func generate(ch chan<- int) {
+	for i := 2; ; i++ {
+		ch <- i  // Send 'i' to channel 'ch'.
+	}
+}
+
+// Copy the values from channel 'src' to channel 'dst',
+// removing those divisible by 'prime'.
+func filter(src <-chan int, dst chan<- int, prime int) {
+	for i := range src {  // Loop over values received from 'src'.
+		if i%prime != 0 {
+			dst <- i  // Send 'i' to channel 'dst'.
+		}
+	}
+}
+
+// The prime sieve: Daisy-chain filter processes together.
+func sieve() {
+	ch := make(chan int)  // Create a new channel.
+	go generate(ch)       // Start generate() as a subprocess.
+	for {
+		prime := <-ch
+		fmt.Print(prime, "\n")
+		ch1 := make(chan int)
+		go filter(ch, ch1, prime)
+		ch = ch1
+	}
+}
+
+func main() {
+	sieve()
+}
+
+ +

Program initialization and execution

+ +

The zero value

+

+When storage is allocated for a variable, +either through a declaration or a call of new, or when +a new value is created, either through a composite literal or a call +of make, +and no explicit initialization is provided, the variable or value is +given a default value. Each element of such a variable or value is +set to the zero value for its type: false for booleans, +0 for numeric types, "" +for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. +This initialization is done recursively, so for instance each element of an +array of structs will have its fields zeroed if no value is specified. +

+

+These two simple declarations are equivalent: +

+ +
+var i int
+var i int = 0
+
+ +

+After +

+ +
+type T struct { i int; f float64; next *T }
+t := new(T)
+
+ +

+the following holds: +

+ +
+t.i == 0
+t.f == 0.0
+t.next == nil
+
+ +

+The same would also be true after +

+ +
+var t T
+
+ +

Package initialization

+ +

+Within a package, package-level variable initialization proceeds stepwise, +with each step selecting the variable earliest in declaration order +which has no dependencies on uninitialized variables. +

+ +

+More precisely, a package-level variable is considered ready for +initialization if it is not yet initialized and either has +no initialization expression or +its initialization expression has no dependencies on uninitialized variables. +Initialization proceeds by repeatedly initializing the next package-level +variable that is earliest in declaration order and ready for initialization, +until there are no variables ready for initialization. +

+ +

+If any variables are still uninitialized when this +process ends, those variables are part of one or more initialization cycles, +and the program is not valid. +

+ +

+Multiple variables on the left-hand side of a variable declaration initialized +by single (multi-valued) expression on the right-hand side are initialized +together: If any of the variables on the left-hand side is initialized, all +those variables are initialized in the same step. +

+ +
+var x = a
+var a, b = f() // a and b are initialized together, before x is initialized
+
+ +

+For the purpose of package initialization, blank +variables are treated like any other variables in declarations. +

+ +

+The declaration order of variables declared in multiple files is determined +by the order in which the files are presented to the compiler: Variables +declared in the first file are declared before any of the variables declared +in the second file, and so on. +To ensure reproducible initialization behavior, build systems are encouraged +to present multiple files belonging to the same package in lexical file name +order to a compiler. +

+ +

+Dependency analysis does not rely on the actual values of the +variables, only on lexical references to them in the source, +analyzed transitively. For instance, if a variable x's +initialization expression refers to a function whose body refers to +variable y then x depends on y. +Specifically: +

+ +
    +
  • +A reference to a variable or function is an identifier denoting that +variable or function. +
  • + +
  • +A reference to a method m is a +method value or +method expression of the form +t.m, where the (static) type of t is +not an interface type, and the method m is in the +method set of t. +It is immaterial whether the resulting function value +t.m is invoked. +
  • + +
  • +A variable, function, or method x depends on a variable +y if x's initialization expression or body +(for functions and methods) contains a reference to y +or to a function or method that depends on y. +
  • +
+ +

+For example, given the declarations +

+ +
+var (
+	a = c + b  // == 9
+	b = f()    // == 4
+	c = f()    // == 5
+	d = 3      // == 5 after initialization has finished
+)
+
+func f() int {
+	d++
+	return d
+}
+
+ +

+the initialization order is d, b, c, a. +Note that the order of subexpressions in initialization expressions is irrelevant: +a = c + b and a = b + c result in the same initialization +order in this example. +

+ +

+Dependency analysis is performed per package; only references referring +to variables, functions, and (non-interface) methods declared in the current +package are considered. If other, hidden, data dependencies exists between +variables, the initialization order between those variables is unspecified. +

+ +

+For instance, given the declarations +

+ +
+var x = I(T{}).ab()   // x has an undetected, hidden dependency on a and b
+var _ = sideEffect()  // unrelated to x, a, or b
+var a = b
+var b = 42
+
+type I interface      { ab() []int }
+type T struct{}
+func (T) ab() []int   { return []int{a, b} }
+
+ +

+the variable a will be initialized after b but +whether x is initialized before b, between +b and a, or after a, and +thus also the moment at which sideEffect() is called (before +or after x is initialized) is not specified. +

+ +

+Variables may also be initialized using functions named init +declared in the package block, with no arguments and no result parameters. +

+ +
+func init() { … }
+
+ +

+Multiple such functions may be declared per package, even within a single +source file. In the package block, the init identifier can +be used only to declare init functions, yet the identifier +itself is not declared. Thus +init functions cannot be referred to from anywhere +in a program. +

+ +

+The entire package is initialized by assigning initial values +to all its package-level variables followed by calling +all init functions in the order they appear +in the source, possibly in multiple files, as presented +to the compiler. +

+ +

Program initialization

+ +

+The packages of a complete program are initialized stepwise, one package at a time. +If a package has imports, the imported packages are initialized +before initializing the package itself. If multiple packages import +a package, the imported package will be initialized only once. +The importing of packages, by construction, guarantees that there +can be no cyclic initialization dependencies. +More precisely: +

+ +

+Given the list of all packages, sorted by import path, in each step the first +uninitialized package in the list for which all imported packages (if any) are +already initialized is initialized. +This step is repeated until all packages are initialized. +

+ +

+Package initialization—variable initialization and the invocation of +init functions—happens in a single goroutine, +sequentially, one package at a time. +An init function may launch other goroutines, which can run +concurrently with the initialization code. However, initialization +always sequences +the init functions: it will not invoke the next one +until the previous one has returned. +

+ +

Program execution

+

+A complete program is created by linking a single, unimported package +called the main package with all the packages it imports, transitively. +The main package must +have package name main and +declare a function main that takes no +arguments and returns no value. +

+ +
+func main() { … }
+
+ +

+Program execution begins by initializing the program +and then invoking the function main in package main. +When that function invocation returns, the program exits. +It does not wait for other (non-main) goroutines to complete. +

+ +

Errors

+ +

+The predeclared type error is defined as +

+ +
+type error interface {
+	Error() string
+}
+
+ +

+It is the conventional interface for representing an error condition, +with the nil value representing no error. +For instance, a function to read data from a file might be declared: +

+ +
+func Read(f *File, b []byte) (n int, err error)
+
+ +

Run-time panics

+ +

+Execution errors such as attempting to index an array out +of bounds trigger a run-time panic equivalent to a call of +the built-in function panic +with a value of the implementation-defined interface type runtime.Error. +That type satisfies the predeclared interface type +error. +The exact error values that +represent distinct run-time error conditions are unspecified. +

+ +
+package runtime
+
+type Error interface {
+	error
+	// and perhaps other methods
+}
+
+ +

System considerations

+ +

Package unsafe

+ +

+The built-in package unsafe, known to the compiler +and accessible through the import path "unsafe", +provides facilities for low-level programming including operations +that violate the type system. A package using unsafe +must be vetted manually for type safety and may not be portable. +The package provides the following interface: +

+ +
+package unsafe
+
+type ArbitraryType int  // shorthand for an arbitrary Go type; it is not a real type
+type Pointer *ArbitraryType
+
+func Alignof(variable ArbitraryType) uintptr
+func Offsetof(selector ArbitraryType) uintptr
+func Sizeof(variable ArbitraryType) uintptr
+
+type IntegerType int  // shorthand for an integer type; it is not a real type
+func Add(ptr Pointer, len IntegerType) Pointer
+func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
+func SliceData(slice []ArbitraryType) *ArbitraryType
+func String(ptr *byte, len IntegerType) string
+func StringData(str string) *byte
+
+ +

+A Pointer is a pointer type but a Pointer +value may not be dereferenced. +Any pointer or value of underlying type uintptr can be +converted to a type of underlying type Pointer and vice versa. +If the respective types are type parameters, all types in +their respective type sets must have the same underlying type, which must be uintptr and +Pointer, respectively. +The effect of converting between Pointer and uintptr is implementation-defined. +

+ +
+var f float64
+bits = *(*uint64)(unsafe.Pointer(&f))
+
+type ptr unsafe.Pointer
+bits = *(*uint64)(ptr(&f))
+
+func f[P ~*B, B any](p P) uintptr {
+	return uintptr(unsafe.Pointer(p))
+}
+
+var p ptr = nil
+
+ +

+The functions Alignof and Sizeof take an expression x +of any type and return the alignment or size, respectively, of a hypothetical variable v +as if v were declared via var v = x. +

+

+The function Offsetof takes a (possibly parenthesized) selector +s.f, denoting a field f of the struct denoted by s +or *s, and returns the field offset in bytes relative to the struct's address. +If f is an embedded field, it must be reachable +without pointer indirections through fields of the struct. +For a struct s with field f: +

+ +
+uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
+
+ +

+Computer architectures may require memory addresses to be aligned; +that is, for addresses of a variable to be a multiple of a factor, +the variable's type's alignment. The function Alignof +takes an expression denoting a variable of any type and returns the +alignment of the (type of the) variable in bytes. For a variable +x: +

+ +
+uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0
+
+ +

+A (variable of) type T has variable size if T +is a type parameter, or if it is an +array or struct type containing elements +or fields of variable size. Otherwise the size is constant. +Calls to Alignof, Offsetof, and Sizeof +are compile-time constant expressions of +type uintptr if their arguments (or the struct s in +the selector expression s.f for Offsetof) are types +of constant size. +

+ +

+The function Add adds len to ptr +and returns the updated pointer unsafe.Pointer(uintptr(ptr) + uintptr(len)) +[Go 1.17]. +The len argument must be of integer type or an untyped constant. +A constant len argument must be representable by a value of type int; +if it is an untyped constant it is given type int. +The rules for valid uses of Pointer still apply. +

+ +

+The function Slice returns a slice whose underlying array starts at ptr +and whose length and capacity are len. +Slice(ptr, len) is equivalent to +

+ +
+(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
+
+ +

+except that, as a special case, if ptr +is nil and len is zero, +Slice returns nil +[Go 1.17]. +

+ +

+The len argument must be of integer type or an untyped constant. +A constant len argument must be non-negative and representable by a value of type int; +if it is an untyped constant it is given type int. +At run time, if len is negative, +or if ptr is nil and len is not zero, +a run-time panic occurs +[Go 1.17]. +

+ +

+The function SliceData returns a pointer to the underlying array of the slice argument. +If the slice's capacity cap(slice) is not zero, that pointer is &slice[:1][0]. +If slice is nil, the result is nil. +Otherwise it is a non-nil pointer to an unspecified memory address +[Go 1.20]. +

+ +

+The function String returns a string value whose underlying bytes start at +ptr and whose length is len. +The same requirements apply to the ptr and len argument as in the function +Slice. If len is zero, the result is the empty string "". +Since Go strings are immutable, the bytes passed to String must not be modified afterwards. +[Go 1.20] +

+ +

+The function StringData returns a pointer to the underlying bytes of the str argument. +For an empty string the return value is unspecified, and may be nil. +Since Go strings are immutable, the bytes returned by StringData must not be modified +[Go 1.20]. +

+ +

Size and alignment guarantees

+ +

+For the numeric types, the following sizes are guaranteed: +

+ +
+type                                 size in bytes
+
+byte, uint8, int8                     1
+uint16, int16                         2
+uint32, int32, float32                4
+uint64, int64, float64, complex64     8
+complex128                           16
+
+ +

+The following minimal alignment properties are guaranteed: +

+
    +
  1. For a variable x of any type: unsafe.Alignof(x) is at least 1. +
  2. + +
  3. For a variable x of struct type: unsafe.Alignof(x) is the largest of + all the values unsafe.Alignof(x.f) for each field f of x, but at least 1. +
  4. + +
  5. For a variable x of array type: unsafe.Alignof(x) is the same as + the alignment of a variable of the array's element type. +
  6. +
+ +

+A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory. +

+ +

Appendix

+ +

Language versions

+ +

+The Go 1 compatibility guarantee ensures that +programs written to the Go 1 specification will continue to compile and run +correctly, unchanged, over the lifetime of that specification. +More generally, as adjustments are made and features added to the language, +the compatibility guarantee ensures that a Go program that works with a +specific Go language version will continue to work with any subsequent version. +

+ +

+For instance, the ability to use the prefix 0b for binary +integer literals was introduced with Go 1.13, indicated +by [Go 1.13] in the section on +integer literals. +Source code containing an integer literal such as 0b1011 +will be rejected if the implied or required language version used by +the compiler is older than Go 1.13. +

+ +

+The following table describes the minimum language version required for +features introduced after Go 1. +

+ +

Go 1.9

+ + +

Go 1.13

+
    +
  • +Integer literals may use the prefixes 0b, 0B, 0o, +and 0O for binary, and octal literals, respectively. +
  • +
  • +Hexadecimal floating-point literals may be written using the prefixes +0x and 0X. +
  • +
  • +The imaginary suffix i may be used with any (binary, decimal, hexadecimal) +integer or floating-point literal, not just decimal literals. +
  • +
  • +The digits of any number literal may be separated (grouped) +using underscores _. +
  • +
  • +The shift count in a shift operation may be a signed integer type. +
  • +
+ +

Go 1.14

+
    +
  • +Emdedding a method more than once through different embedded interfaces +is not an error. +
  • +
+ +

Go 1.17

+
    +
  • +A slice may be converted to an array pointer if the slice and array element +types match, and the array is not longer than the slice. +
  • +
  • +The built-in package unsafe includes the new functions +Add and Slice. +
  • +
+ +

Go 1.18

+

+The 1.18 release adds polymorphic functions and types ("generics") to the language. +Specifically: +

+ + +

Go 1.20

+
    +
  • +A slice may be converted to an array if the slice and array element +types match and the array is not longer than the slice. +
  • +
  • +The built-in package unsafe includes the new functions +SliceData, String, and StringData. +
  • +
  • +Comparable types (such as ordinary interfaces) may satisfy +comparable constraints, even if the type arguments are not strictly comparable. +
  • +
+ +

Go 1.21

+
    +
  • +The set of predeclared functions includes the new functions +min, max, and clear. +
  • +
  • +Type inference uses the types of interface methods for inference. +It also infers type arguments for generic functions assigned to variables or +passed as arguments to other (possibly generic) functions. +
  • +
+ +

Go 1.22

+
    +
  • +In a "for" statement, each iteration has its own set of iteration +variables rather than sharing the same variables in each iteration. +
  • +
  • +A "for" statement with "range" clause may iterate over +integer values from zero to an upper limit. +
  • +
+ +

Go 1.23

+
    +
  • A "for" statement with "range" clause accepts an iterator +function as range expression. +
  • +
+ +

Go 1.24

+ + +

Go 1.27

+ + +

Type unification rules

+ +

+The type unification rules describe if and how two types unify. +The precise details are relevant for Go implementations, +affect the specifics of error messages (such as whether +a compiler reports a type inference or other error), +and may explain why type inference fails in unusual code situations. +But by and large these rules can be ignored when writing Go code: +type inference is designed to mostly "work as expected", +and the unification rules are fine-tuned accordingly. +

+ +

+Type unification is controlled by a matching mode, which may +be exact or loose. +As unification recursively descends a composite type structure, +the matching mode used for elements of the type, the element matching mode, +remains the same as the matching mode except when two types are unified for +assignability (A): +in this case, the matching mode is loose at the top level but +then changes to exact for element types, reflecting the fact +that types don't have to be identical to be assignable. +

+ +

+Two types that are not bound type parameters unify exactly if any of +following conditions is true: +

+ +
    +
  • + Both types are identical. +
  • +
  • + Both types have identical structure and their element types + unify exactly. +
  • +
  • + Exactly one type is an unbound + type parameter, and all the types in its type set unify with + the other type + per the unification rules for A + (loose unification at the top level and exact unification + for element types). +
  • +
+ +

+If both types are bound type parameters, they unify per the given +matching modes if: +

+ +
    +
  • + Both type parameters are identical. +
  • +
  • + At most one of the type parameters has a known type argument. + In this case, the type parameters are joined: + they both stand for the same type argument. + If neither type parameter has a known type argument yet, + a future type argument inferred for one the type parameters + is simultaneously inferred for both of them. +
  • +
  • + Both type parameters have a known type argument + and the type arguments unify per the given matching modes. +
  • +
+ +

+A single bound type parameter P and another type T unify +per the given matching modes if: +

+ +
    +
  • + P doesn't have a known type argument. + In this case, T is inferred as the type argument for P. +
  • +
  • + P does have a known type argument A, + A and T unify per the given matching modes, + and one of the following conditions is true: +
      +
    • + Both A and T are interface types: + In this case, if both A and T are + also defined types, + they must be identical. + Otherwise, if neither of them is a defined type, they must + have the same number of methods + (unification of A and T already + established that the methods match). +
    • +
    • + Neither A nor T are interface types: + In this case, if T is a defined type, T + replaces A as the inferred type argument for P. +
    • +
    +
  • +
+ +

+Finally, two types that are not bound type parameters unify loosely +(and per the element matching mode) if: +

+ +
    +
  • + Both types unify exactly. +
  • +
  • + One type is a defined type, + the other type is a type literal, but not an interface, + and their underlying types unify per the element matching mode. +
  • +
  • + Both types are interfaces (but not type parameters) with + identical type terms, + both or neither embed the predeclared type + comparable, + corresponding method types unify exactly, + and the method set of one of the interfaces is a subset of + the method set of the other interface. +
  • +
  • + Only one type is an interface (but not a type parameter), + corresponding methods of the two types unify per the element matching mode, + and the method set of the interface is a subset of + the method set of the other type. +
  • +
  • + Both types have the same structure and their element types + unify per the element matching mode. +
  • +
+ + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/stdlib/kvlang/reference/python/cpython/.coveragerc b/stdlib/kvlang/reference/python/cpython/.coveragerc new file mode 100644 index 00000000..b5d94317 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.coveragerc @@ -0,0 +1,24 @@ +[run] +branch = True + +[report] +# Regexes for lines to exclude from consideration +exclude_lines = + # Don't complain if non-runnable code isn't run: + if 0: + if __name__ == .__main__.: + raise AssertionError\( + + # Empty bodies in protocols or abstract methods + ^\s*def [a-zA-Z0-9_]+\(.*\)(\s*->.*)?:\s*\.\.\.(\s*#.*)?$ + ^\s*\.\.\.(\s*#.*)?$ + + .*# pragma: no cover + .*# pragma: no branch + + # Additions for IDLE: + .*# htest # + if not (_htest or _utest): + if not .*_utest: + if .*_htest: + diff --git a/stdlib/kvlang/reference/python/cpython/.editorconfig b/stdlib/kvlang/reference/python/cpython/.editorconfig new file mode 100644 index 00000000..ab1f7ce8 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*.{py,c,cpp,h,js,rst,md,yml,yaml,toml,gram}] +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space + +[*.{py,c,cpp,h,toml,gram}] +indent_size = 4 + +[*.rst] +indent_size = 3 + +[*.{js,yml,yaml}] +indent_size = 2 diff --git a/stdlib/kvlang/reference/python/cpython/.gitattributes b/stdlib/kvlang/reference/python/cpython/.gitattributes new file mode 100644 index 00000000..7ca49c3e --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.gitattributes @@ -0,0 +1,119 @@ +# Binary data types +*.aif binary +*.aifc binary +*.aiff binary +*.au binary +*.bmp binary +*.exe binary +*.icns binary +*.gif binary +*.ico binary +*.jpg binary +*.pck binary +*.pdf binary +*.png binary +*.psd binary +*.tar binary +*.wav binary +*.whl binary +*.zip binary + +# Specific binary files +# -- None right now -- + +# Text files that should not be subject to eol conversion +[attr]noeol -text + +Lib/test/cjkencodings/* noeol +Lib/test/tokenizedata/coding20731.py noeol +Lib/test/decimaltestdata/*.decTest noeol +Lib/test/test_email/data/*.txt noeol +Lib/test/xmltestdata/* noeol + +# Shell scripts should have LF even on Windows because of Cygwin +Lib/venv/scripts/common/activate text eol=lf +Lib/venv/scripts/posix/* text eol=lf + +# Prevent GitHub's web conflict editor from converting LF to CRLF +*.rst text eol=lf + +# CRLF files +[attr]dos text eol=crlf + +*.bat dos +*.proj dos +*.props dos +*.ps1 dos +*.sln dos +*.vcxproj* dos +PC/readme.txt dos +PCbuild/readme.txt dos + +# Language aware diff headers +# https://tekin.co.uk/2020/10/better-git-diff-output-for-ruby-python-elixir-and-more +# https://gist.github.com/tekin/12500956bd56784728e490d8cef9cb81 +*.c diff=cpp +*.h diff=cpp +*.css diff=css +*.html diff=html +*.py diff=python +*.md diff=markdown + +# Generated files +# https://github.com/github/linguist/blob/master/docs/overrides.md +# +# To always hide generated files in local diffs, mark them as binary: +# $ git config diff.generated.binary true +# +[attr]generated linguist-generated=true diff=generated + +**/clinic/*.c.h generated +**/clinic/*.cpp.h generated +**/clinic/*.h.h generated +*_db.h generated +Doc/_static/tachyon-example-*.html generated +Doc/c-api/lifecycle.dot.svg generated +Doc/data/stable_abi.dat generated +Doc/library/token-list.inc generated +Include/internal/pycore_ast.h generated +Include/internal/pycore_ast_state.h generated +Include/internal/pycore_opcode.h generated +Include/internal/pycore_opcode_metadata.h generated +Include/internal/pycore_*_generated.h generated +Include/internal/pycore_token.h generated +Include/internal/pycore_uop_ids.h generated +Include/internal/pycore_uop_metadata.h generated +Include/opcode.h generated +Include/opcode_ids.h generated +Include/slots_generated.h generated +Lib/_opcode_metadata.py generated +Lib/idlelib/help.html generated +Lib/keyword.py generated +Lib/pydoc_data/topics.py generated +Lib/pydoc_data/module_docs.py generated +Lib/test/certdata/*.pem generated +Lib/test/certdata/*.0 generated +Lib/test/levenshtein_examples.json generated +Lib/test/test_stable_abi_ctypes.py generated +Lib/test/test_zoneinfo/data/*.json generated +Lib/token.py generated +Misc/sbom.spdx.json generated +Modules/_testinternalcapi/test_cases.c.h generated +Modules/_testinternalcapi/test_targets.h generated +PC/python3dll.c generated +Parser/parser.c generated +Parser/token.c generated +Programs/test_frozenmain.h generated +Python/Python-ast.c generated +Python/executor_cases.c.h generated +Python/generated_cases.c.h generated +Python/optimizer_cases.c.h generated +Python/opcode_targets.h generated +Python/record_functions.c.h generated +Python/slots_generated.c generated +Python/stdlib_module_names.h generated +Tools/peg_generator/pegen/grammar_parser.py generated +aclocal.m4 generated +configure generated +*.min.js generated +package-lock.json generated diff --git a/stdlib/kvlang/reference/python/cpython/.gitignore b/stdlib/kvlang/reference/python/cpython/.gitignore new file mode 100644 index 00000000..00813f9d --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.gitignore @@ -0,0 +1,191 @@ +##### +# First, rules intended to apply in all subdirectories. +# These contain no slash, or only a trailing slash. + +*.cover +*.iml +*.o +*.o.tmp +*.lto +*.a +*.so +*.so.* +*.dylib +*.dSYM +*.dll +*.wasm +*.orig +*.pyc +*.pyd +*.pyo +*.rej +*.swp +*~ +*.gc?? +*.profclang? +*.profraw +# Copies of binaries before BOLT optimizations. +*.prebolt +# BOLT profile data. +*.fdata +*.dyn +.gdb_history +.purify +__pycache__ +.hg/ +.svn/ +.idea/ +tags +TAGS +.vs/ +.vscode/ +.cache/ +gmon.out +.coverage +.mypy_cache/ +.pytest_cache/ +.ruff_cache/ +.DS_Store +.pixi/ + +*.exe + +# Ignore core dumps... but not .../core/ subdirectories +core +!core/ + + +##### +# Then, rules meant for a specific location relative to the repo root. +# These must contain a non-trailing slash (and may also have a trailing slash.) + +Doc/build/ +Doc/venv/ +Doc/.venv/ +Doc/env/ +Doc/.env/ +Include/pydtrace_probes.h +Lib/site-packages/* +!Lib/site-packages/README.txt +Lib/test/data/* +!Lib/test/data/README +/_bootstrap_python +/Makefile +/Makefile.pre +/iOSTestbed.* +Apple/iOS/Frameworks/ +Apple/iOS/Resources/Info.plist +Apple/testbed/build +Apple/testbed/Python.xcframework/*/bin +Apple/testbed/Python.xcframework/*/include +Apple/testbed/Python.xcframework/*/lib +Apple/testbed/Python.xcframework/*/Python.framework +Apple/testbed/*Testbed.xcodeproj/project.xcworkspace +Apple/testbed/*Testbed.xcodeproj/xcuserdata +Mac/Makefile +Mac/PythonLauncher/Info.plist +Mac/PythonLauncher/Makefile +Mac/PythonLauncher/Python Launcher +Mac/PythonLauncher/Python Launcher.app/* +Mac/Resources/app/Info.plist +Mac/Resources/framework/Info.plist +Mac/pythonw +/*.framework/ +Misc/python.pc +Misc/python-embed.pc +Misc/python-config.sh +Modules/Setup.bootstrap +Modules/Setup.config +Modules/Setup.local +Modules/Setup.stdlib +Modules/config.c +Modules/ld_so_aix +Programs/_freeze_module +Programs/_testembed +PC/python_nt*.h +PC/pythonnt_rc*.h +Modules/python.exp +PC/*/*.exp +PC/*/*.lib +PC/*/*.bsc +PC/*/*.dll +PC/*/*.pdb +PC/*/*.user +PC/*/*.ncb +PC/*/*.suo +PC/*/Win32-temp-* +PC/*/x64-temp-* +PC/*/amd64 +PCbuild/*.user +PCbuild/*.suo +PCbuild/*.*sdf +PCbuild/*-pgi +PCbuild/*-pgo +PCbuild/*.VC.db +PCbuild/*.VC.opendb +PCbuild/amd64/ +PCbuild/amd64t/ +PCbuild/arm32/ +PCbuild/arm32t/ +PCbuild/arm64/ +PCbuild/arm64t/ +PCbuild/obj/ +PCbuild/win32/ +PCbuild/win32t/ +Tools/unicode/data/ +/autom4te.cache +/build/ +/builddir/ +/compile_commands.json +/config.cache +/config.log +/config.status +/config.status.lineno +/.ccache +/cross-build*/ +/dist/ +/jit_stencils*.h +/jit_unwind_info*.h +.jit-stamp +/platform +/profile-clean-stamp +/profile-run-stamp +/profile-bolt-stamp +/profile-gen-stamp +/pybuilddir.txt +/pyconfig.h +/python-config +/python-config.py +/python.bat +/python-gdb.py +/python.exe-gdb.py +/reflog.txt +/coverage/ +/externals/ +/htmlcov/ +Tools/ssl/amd64 +Tools/ssl/win32 +Tools/freeze/test/outdir + +# The frozen modules are always generated by the build so we don't +# keep them in the repo. Also see Tools/build/freeze_modules.py. +Python/frozen_modules/*.h +# The manifest can be generated at any time with "make regen-frozen". +Python/frozen_modules/MANIFEST + +# Two-trick pony for OSX and other case insensitive file systems: +# Ignore ./python binary on Unix but still look into ./Python/ directory. +/python +!/Python/ + +# Local AI agent scratch state (per-PR and per-branch notebooks, sandbox +# experiments) and personal agent overrides, none of which are committed. +/.claude/pr-* +/.claude/branch-* +/.claude/sandbox/ +AGENTS.local.md +CLAUDE.local.md + +#### main branch only stuff below this line, things to backport go above. #### +# main branch only: ABI files are not checked/maintained. +Doc/data/python*.abi diff --git a/stdlib/kvlang/reference/python/cpython/.mailmap b/stdlib/kvlang/reference/python/cpython/.mailmap new file mode 100644 index 00000000..8f11bebb --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.mailmap @@ -0,0 +1,4 @@ +# This file sets the canonical name for contributors to the repository. +# Documentation: https://git-scm.com/docs/gitmailmap +Willow Chargin +Amethyst Reese diff --git a/stdlib/kvlang/reference/python/cpython/.pre-commit-config.yaml b/stdlib/kvlang/reference/python/cpython/.pre-commit-config.yaml new file mode 100644 index 00000000..615ba587 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.pre-commit-config.yaml @@ -0,0 +1,149 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: 3b3f7c3f57fe9925356faf5fe6230835138be230 # frozen: v0.15.17 + hooks: + - id: ruff-check + name: Run Ruff (lint) on Platforms/Apple/ + args: [--exit-non-zero-on-fix, --config=Platforms/Apple/.ruff.toml] + files: ^Platforms/Apple/ + - id: ruff-check + name: Run Ruff (lint) on Doc/ + args: [--exit-non-zero-on-fix] + files: ^Doc/ + - id: ruff-check + name: Run Ruff (lint) on Lib/ + args: [--exit-non-zero-on-fix] + files: ^Lib/ + exclude: ^Lib/test/ + - id: ruff-check + name: Run Ruff (lint) on Lib/test/ + args: [--exit-non-zero-on-fix] + files: ^Lib/test/ + - id: ruff-check + name: Run Ruff (lint) on Platforms/WASI/ + args: [--exit-non-zero-on-fix, --config=Platforms/WASI/.ruff.toml] + files: ^Platforms/WASI/ + - id: ruff-check + name: Run Ruff (lint) on Tools/ + args: [--exit-non-zero-on-fix] + files: ^Tools/ + exclude: ^Tools/(build|clinic|i18n|peg_generator|wasm)/ + - id: ruff-check + name: Run Ruff (lint) on Tools/build/ + args: [--exit-non-zero-on-fix, --config=Tools/build/.ruff.toml] + files: ^Tools/build/ + - id: ruff-check + name: Run Ruff (lint) on Tools/i18n/ + args: [--exit-non-zero-on-fix, --config=Tools/i18n/.ruff.toml] + files: ^Tools/i18n/ + - id: ruff-check + name: Run Ruff (lint) on Argument Clinic + args: [--exit-non-zero-on-fix, --config=Tools/clinic/.ruff.toml] + files: ^Tools/clinic/|Lib/test/test_clinic.py + - id: ruff-check + name: Run Ruff (lint) on Tools/peg_generator/ + args: [--exit-non-zero-on-fix, --config=Tools/peg_generator/.ruff.toml] + files: ^Tools/peg_generator/ + - id: ruff-check + name: Run Ruff (lint) on Tools/wasm/ + args: [--exit-non-zero-on-fix, --config=Tools/wasm/.ruff.toml] + files: ^Tools/wasm/ + - id: ruff-format + name: Run Ruff (format) on Platforms/Apple/ + args: [--exit-non-zero-on-fix, --config=Platforms/Apple/.ruff.toml] + files: ^Platforms/Apple/ + - id: ruff-format + name: Run Ruff (format) on Doc/ + args: [--exit-non-zero-on-fix] + files: ^Doc/ + - id: ruff-format + name: Run Ruff (format) on Platforms/WASI/ + args: [--exit-non-zero-on-fix, --config=Platforms/WASI/.ruff.toml] + files: ^Platforms/WASI/ + - id: ruff-format + name: Run Ruff (format) on Tools/build/check_warnings.py + args: [--exit-non-zero-on-fix, --config=Tools/build/.ruff.toml] + files: ^Tools/build/check_warnings.py + - id: ruff-format + name: Run Ruff (format) on Tools/wasm/ + args: [--exit-non-zero-on-fix, --config=Tools/wasm/.ruff.toml] + files: ^Tools/wasm/ + + - repo: https://github.com/psf/black-pre-commit-mirror + rev: ea488cebbfd88a5f50b8bd95d5c829d0bb76feb8 # frozen: 26.1.0 + hooks: + - id: black + name: Run Black on Tools/jit/ + files: ^Tools/jit/ + + - repo: https://github.com/Lucas-C/pre-commit-hooks + rev: ad1b27d73581aa16cca06fc4a0761fc563ffe8e8 # frozen: v1.5.6 + hooks: + - id: remove-tabs + types: [python] + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 + hooks: + - id: check-case-conflict + - id: check-merge-conflict + - id: check-toml + exclude: ^Lib/test/test_tomllib/ + - id: check-yaml + - id: end-of-file-fixer + types_or: [python, yaml] + exclude: Lib/test/tokenizedata/coding20731.py + - id: end-of-file-fixer + files: '^\.github/CODEOWNERS$' + - id: mixed-line-ending + args: [--fix=auto] + exclude: '^Lib/test/.*data/' + - id: trailing-whitespace + types_or: [c, inc, python, rst, yaml] + - id: trailing-whitespace + files: '^\.github/CODEOWNERS|\.(gram)$' + + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 9f48a48aa91a6040d749ad68ec70907d907a5a7f # frozen: 0.37.0 + hooks: + - id: check-dependabot + - id: check-github-workflows + - id: check-readthedocs + + - repo: https://github.com/rhysd/actionlint + rev: 914e7df21a07ef503a81201c76d2b11c789d3fca # frozen: v1.7.12 + hooks: + - id: actionlint + + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: b546b77c44c466a54a42af5499dcc0dcc1a3193f # frozen: v1.22.0 + hooks: + - id: zizmor + + - repo: https://github.com/sphinx-contrib/sphinx-lint + rev: c883505f64b59c3c5c9375191e4ad9f98e727ccd # frozen: v1.0.2 + hooks: + - id: sphinx-lint + args: [--enable=default-role] + files: ^Doc/|^Misc/NEWS.d/ + + - repo: local + hooks: + - id: blurb-no-space-c-api + name: Check C API news entries + language: fail + entry: Space found in path, move to Misc/NEWS.d/next/C_API/ + files: Misc/NEWS.d/next/C API/20.*.rst + + - repo: local + hooks: + - id: blurb-no-space-core-and-builtins + name: Check Core and Builtins news entries + language: fail + entry: Space found in path, move to Misc/NEWS.d/next/Core_and_Builtins/ + files: Misc/NEWS.d/next/Core and Builtins/20.*.rst + + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes diff --git a/stdlib/kvlang/reference/python/cpython/.readthedocs.yml b/stdlib/kvlang/reference/python/cpython/.readthedocs.yml new file mode 100644 index 00000000..038417e4 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.readthedocs.yml @@ -0,0 +1,60 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +# Project page: https://readthedocs.org/projects/cpython-previews/ + +version: 2 + +sphinx: + configuration: Doc/conf.py + +build: + os: ubuntu-24.04 + tools: + python: "3" + apt_packages: + - jq + + jobs: + post_system_dependencies: + # https://docs.readthedocs.com/platform/stable/guides/build/skip-build.html#skip-builds-based-on-conditions + # + # Cancel building pull requests when there are no changes in the Doc + # directory or RTD configuration, or if we can't cleanly merge the base + # branch. + - | + set -eEux; + if [ "$READTHEDOCS_VERSION_TYPE" = "external" ]; + then + base_branch=$(wget -qO- "https://api.github.com/repos/python/cpython/pulls/$READTHEDOCS_VERSION" | jq -er ".base.ref"); + git fetch --depth=50 origin $base_branch:origin-$base_branch; + for attempt in $(seq 10); + do + if ! git merge-base HEAD origin-$base_branch; + then + git fetch --deepen=50 origin $base_branch; + else + break; + fi; + done; + if ! git -c "user.name=rtd" -c "user.email=no-reply@readthedocs.org" merge --no-stat --no-edit origin-$base_branch; + then + echo "Unsuccessful merge with '$base_branch' branch, skipping the build"; + exit 183; + fi; + if git diff --exit-code --stat origin-$base_branch -- Doc/ .readthedocs.yml; + then + echo "No changes to Doc/ - skipping the build."; + exit 183; + fi; + fi; + create_environment: + - echo "Skipping default environment creation" + install: + - asdf plugin add uv + - asdf install uv latest + - asdf global uv latest + build: + html: + - make -C Doc venv html + - mkdir -p "$READTHEDOCS_OUTPUT" + - mv Doc/build/html "$READTHEDOCS_OUTPUT/" diff --git a/stdlib/kvlang/reference/python/cpython/.ruff.toml b/stdlib/kvlang/reference/python/cpython/.ruff.toml new file mode 100644 index 00000000..1c015fa8 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/.ruff.toml @@ -0,0 +1,12 @@ +# Default settings for Ruff in CPython + +# PYTHON_FOR_REGEN +target-version = "py310" + +# PEP 8 +line-length = 79 + +# Enable automatic fixes by default. +# To override this, use ``fix = false`` in a subdirectory's config file +# or ``--no-fix`` on the command line. +fix = true diff --git a/stdlib/kvlang/reference/python/cpython/AGENTS.md b/stdlib/kvlang/reference/python/cpython/AGENTS.md new file mode 100644 index 00000000..d23d0c93 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/AGENTS.md @@ -0,0 +1,16 @@ +# AI agent guidance + +CPython has a [policy on the use of AI tools](https://devguide.python.org/getting-started/ai-tools/). +All use of AI tools and agents when working on or interacting with CPython +must follow it. + +> [!important] +> **Primary directive**: Read the policy before making or proposing any changes. + +When acting on this repository, apply the policy's core principles: + +- Consider whether the change is necessary. +- Make minimal, focused changes. +- Follow existing coding style and patterns. +- Write tests that exercise the change. +- Keep backwards compatibility with prior releases in mind. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/.ruff.toml b/stdlib/kvlang/reference/python/cpython/Doc/.ruff.toml new file mode 100644 index 00000000..6b573fd5 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/.ruff.toml @@ -0,0 +1,44 @@ +extend = "../.ruff.toml" # Inherit the project-wide settings + +target-version = "py312" # Align with the version in oldest_supported_sphinx +extend-exclude = [ + "includes/*", + # Temporary exclusions: + "tools/extensions/pyspecific.py", +] + +[lint] +preview = true +select = [ + "C4", # flake8-comprehensions + "B", # flake8-bugbear + "E", # pycodestyle + "F", # pyflakes + "FA", # flake8-future-annotations + "FLY", # flynt + "FURB", # refurb + "G", # flake8-logging-format + "I", # isort + "LOG", # flake8-logging + "N", # pep8-naming + "PERF", # perflint + "PGH", # pygrep-hooks + "PT", # flake8-pytest-style + "TCH", # flake8-type-checking + "UP", # pyupgrade + "W", # pycodestyle +] +ignore = [ + "E501", # Ignore line length errors (we use auto-formatting) +] + +[lint.per-file-ignores] +"tools/check-html-ids.py" = ["I001"] # Unsorted imports + +[format] +preview = true +quote-style = "preserve" +docstring-code-format = true +exclude = [ + "tools/extensions/lexers/*", +] diff --git a/stdlib/kvlang/reference/python/cpython/Doc/Makefile b/stdlib/kvlang/reference/python/cpython/Doc/Makefile new file mode 100644 index 00000000..ef6ef8c4 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/Makefile @@ -0,0 +1,363 @@ +# +# Makefile for Python documentation +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +# You can set these variables from the command line. +PYTHON = python3 +VENVDIR = ./venv +UV = uv +SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-build +BLURB = PATH=$(VENVDIR)/bin:$$PATH blurb +JOBS = auto +PAPER = +SOURCES = +DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) +REQUIREMENTS = pylock.toml +SPHINXERRORHANDLING = --fail-on-warning + +# Internal variables. +PAPEROPT_a4 = --define latex_elements.papersize=a4paper +PAPEROPT_letter = --define latex_elements.papersize=letterpaper + +ALLSPHINXOPTS = --builder $(BUILDER) \ + --doctree-dir build/doctrees \ + --jobs $(JOBS) \ + $(PAPEROPT_$(PAPER)) \ + $(SPHINXOPTS) $(SPHINXERRORHANDLING) \ + . build/$(BUILDER) $(SOURCES) + +.PHONY: help +help: + @echo "Please use \`make ' where is one of" + @echo " clean to remove build files" + @echo " venv to create a venv with necessary tools" + @echo " lock to regenerate the pinned dependencies in $(REQUIREMENTS)" + @echo " html to make standalone HTML files" + @echo " gettext to generate POT files" + @echo " htmlview to open the index page built by the html target in your browser" + @echo " htmllive to rebuild and reload HTML files in your browser" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " text to make plain text files" + @echo " texinfo to make Texinfo file" + @echo " epub to make EPUB files" + @echo " changes to make an overview over all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " coverage to check documentation coverage for library and C API" + @echo " doctest to run doctests in the documentation" + @echo " pydoc-topics to regenerate the pydoc topics file" + @echo " dist to create a \"dist\" directory with archived docs for download" + @echo " check to run a check for frequent markup errors" + +.PHONY: build +build: + -mkdir -p build +# Look first for a Misc/NEWS file (building from a source release tarball +# or old repo) and use that, otherwise look for a Misc/NEWS.d directory +# (building from a newer repo) and use blurb to generate the NEWS file. + @if [ -f ../Misc/NEWS ] ; then \ + echo "Using existing Misc/NEWS file"; \ + cp ../Misc/NEWS build/NEWS; \ + elif $(BLURB) --version && $(SPHINXBUILD) --version ; then \ + if [ -d ../Misc/NEWS.d ]; then \ + echo "Building NEWS from Misc/NEWS.d with blurb"; \ + $(BLURB) merge -f build/NEWS; \ + else \ + echo "Neither Misc/NEWS.d nor Misc/NEWS found; cannot build docs"; \ + exit 1; \ + fi \ + else \ + echo ""; \ + echo "Missing the required blurb or sphinx-build tools."; \ + echo "Please run 'make venv' to install local copies."; \ + echo ""; \ + exit 1; \ + fi + $(SPHINXBUILD) $(ALLSPHINXOPTS) + @echo + +.PHONY: html +html: BUILDER = html +html: build + @echo "Build finished. The HTML pages are in build/html." + +.PHONY: htmlhelp +htmlhelp: BUILDER = htmlhelp +htmlhelp: build + @echo "Build finished; now you can run HTML Help Workshop with the" \ + "build/htmlhelp/pydoc.hhp project file." + +.PHONY: latex +latex: BUILDER = latex +latex: _ensure-sphinxcontrib-svg2pdfconverter + $(MAKE) build BUILDER=$(BUILDER) + @echo "Build finished; the LaTeX files are in build/latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +.PHONY: text +text: BUILDER = text +text: build + @echo "Build finished; the text files are in build/text." + +.PHONY: texinfo +texinfo: BUILDER = texinfo +texinfo: build + @echo "Build finished; the python.texi file is in build/texinfo." + @echo "Run \`make info' in that directory to run it through makeinfo." + +.PHONY: epub +epub: BUILDER = epub +epub: build + @echo "Build finished; the epub files are in build/epub." + +.PHONY: changes +changes: BUILDER = changes +changes: build + @echo "The overview file is in build/changes." + +.PHONY: linkcheck +linkcheck: BUILDER = linkcheck +linkcheck: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Link check complete; look for any errors in the above output" \ + "or in build/$(BUILDER)/output.txt"; \ + false; } + +.PHONY: coverage +coverage: BUILDER = coverage +coverage: build + @echo "Coverage finished; see c.txt and python.txt in build/coverage" + +.PHONY: doctest +doctest: BUILDER = doctest +doctest: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Testing of doctests in the sources finished, look at the" \ + "results in build/doctest/output.txt"; \ + false; } + +.PHONY: pydoc-topics +pydoc-topics: BUILDER = pydoc-topics +pydoc-topics: build + @echo "Building finished; now run this:" \ + "cp build/pydoc-topics/topics.py ../Lib/pydoc_data/topics.py" \ + "&& cp build/pydoc-topics/module_docs.py ../Lib/pydoc_data/module_docs.py" + +.PHONY: gettext +gettext: BUILDER = gettext +gettext: override SPHINXOPTS := --doctree-dir build/doctrees-gettext $(SPHINXOPTS) +gettext: build + +.PHONY: htmlview +htmlview: html + $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/html/index.html'))" + +.PHONY: htmllive +htmllive: SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-autobuild +htmllive: SPHINXOPTS = --re-ignore="/venv/" --open-browser --delay 0 +htmllive: _ensure-sphinx-autobuild html + +.PHONY: clean +clean: clean-venv + -rm -rf build/* + +.PHONY: clean-venv +clean-venv: + rm -rf $(VENVDIR) + +.PHONY: venv +venv: + @if [ -d $(VENVDIR) ] ; then \ + echo "venv already exists."; \ + echo "To recreate it, remove it first with \`make clean-venv'."; \ + else \ + set -e; \ + echo "Creating venv in $(VENVDIR)"; \ + if $(UV) --version >/dev/null 2>&1; then \ + $(UV) venv --python=$(PYTHON) $(VENVDIR); \ + VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \ + else \ + $(PYTHON) -m venv $(VENVDIR); \ + $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \ + $(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \ + fi; \ + echo "The venv has been created in the $(VENVDIR) directory"; \ + fi + +.PHONY: lock +lock: +# Dependencies have a 14 day cooldown period to mitigate supply chain attacks, +# except for sphinx_linklint and python-docs-theme, which are maintained by +# core team members. + uv pip compile requirements.txt \ + --exclude-newer P14D \ + --exclude-newer-package sphinx_linklint=PT0S \ + --exclude-newer-package python-docs-theme=PT0S \ + --no-cache --output-file $(REQUIREMENTS) \ + --python-version 3.12 --universal \ + --custom-compile-command="make lock" + +.PHONY: dist-no-html +dist-no-html: dist-text dist-epub dist-texinfo + +.PHONY: dist +dist: + rm -rf dist + mkdir -p dist + $(MAKE) dist-html + $(MAKE) dist-text + $(MAKE) dist-pdf + $(MAKE) dist-epub + $(MAKE) dist-texinfo + +.PHONY: dist-html +dist-html: + # archive the HTML + @echo "Building HTML..." + mkdir -p dist + rm -rf build/html + find dist -name 'python-$(DISTVERSION)-docs-html*' -exec rm -rf {} \; + $(MAKE) html + cp -pPR build/html dist/python-$(DISTVERSION)-docs-html + rm -rf dist/python-$(DISTVERSION)-docs-html/_images/social_previews/ + tar -C dist -cf dist/python-$(DISTVERSION)-docs-html.tar python-$(DISTVERSION)-docs-html + bzip2 -9 -k dist/python-$(DISTVERSION)-docs-html.tar + (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-html.zip python-$(DISTVERSION)-docs-html) + rm -r dist/python-$(DISTVERSION)-docs-html + rm dist/python-$(DISTVERSION)-docs-html.tar + @echo "Build finished and archived!" + +.PHONY: dist-text +dist-text: + # archive the text build + @echo "Building text..." + mkdir -p dist + rm -rf build/text + find dist -name 'python-$(DISTVERSION)-docs-text*' -exec rm -rf {} \; + $(MAKE) text + cp -pPR build/text dist/python-$(DISTVERSION)-docs-text + tar -C dist -cf dist/python-$(DISTVERSION)-docs-text.tar python-$(DISTVERSION)-docs-text + bzip2 -9 -k dist/python-$(DISTVERSION)-docs-text.tar + (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-text.zip python-$(DISTVERSION)-docs-text) + rm -r dist/python-$(DISTVERSION)-docs-text + rm dist/python-$(DISTVERSION)-docs-text.tar + @echo "Build finished and archived!" + +.PHONY: dist-pdf +dist-pdf: _ensure-sphinxcontrib-svg2pdfconverter + # archive the A4 latex + @echo "Building LaTeX (A4 paper)..." + mkdir -p dist + rm -rf build/latex + find dist -name 'python-$(DISTVERSION)-docs-pdf*' -exec rm -rf {} \; + $(MAKE) latex PAPER=a4 + # remove zip & bz2 dependency on all-pdf, + # as otherwise the full latexmk process is run twice. + # ($$ is needed to escape the $; https://www.gnu.org/software/make/manual/make.html#Basics-of-Variable-References) + -sed -i 's/: all-$$(FMT)/:/' build/latex/Makefile + if [ -n "$(filter output-sync,$(value .FEATURES))" ]; then OUTPUTSYNC=--output-sync; else OUTPUTSYNC=; fi && \ + (cd build/latex; $(MAKE) clean && $(MAKE) --jobs=$$((`getconf _NPROCESSORS_ONLN`+1)) $$OUTPUTSYNC LATEXMKOPTS='-quiet' all-pdf && $(MAKE) FMT=pdf zip bz2) + cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-a4.zip + cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-a4.tar.bz2 + @echo "Build finished and archived!" + +.PHONY: dist-epub +dist-epub: + # copy the epub build + @echo "Building EPUB..." + mkdir -p dist + rm -rf build/epub + rm -f dist/python-$(DISTVERSION)-docs.epub + $(MAKE) epub + cp -pPR build/epub/Python.epub dist/python-$(DISTVERSION)-docs.epub + @echo "Build finished and archived!" + +.PHONY: dist-texinfo +dist-texinfo: + # archive the texinfo build + @echo "Building Texinfo..." + mkdir -p dist + rm -rf build/texinfo + find dist -name 'python-$(DISTVERSION)-docs-texinfo*' -exec rm -rf {} \; + $(MAKE) texinfo + $(MAKE) info --directory=build/texinfo + cp -pPR build/texinfo dist/python-$(DISTVERSION)-docs-texinfo + tar -C dist -cf dist/python-$(DISTVERSION)-docs-texinfo.tar python-$(DISTVERSION)-docs-texinfo + bzip2 -9 -k dist/python-$(DISTVERSION)-docs-texinfo.tar + (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-texinfo.zip python-$(DISTVERSION)-docs-texinfo) + rm -r dist/python-$(DISTVERSION)-docs-texinfo + rm dist/python-$(DISTVERSION)-docs-texinfo.tar + @echo "Build finished and archived!" + +.PHONY: _ensure-package +_ensure-package: venv + if $(UV) --version >/dev/null 2>&1; then \ + VIRTUAL_ENV=$(VENVDIR) $(UV) pip install $(PACKAGE); \ + else \ + $(VENVDIR)/bin/python3 -m pip install $(PACKAGE); \ + fi + +.PHONY: _ensure-pre-commit +_ensure-pre-commit: + $(MAKE) _ensure-package PACKAGE=pre-commit + +.PHONY: _ensure-sphinx-autobuild +_ensure-sphinx-autobuild: + $(MAKE) _ensure-package PACKAGE=sphinx-autobuild + +.PHONY: _ensure-sphinxcontrib-svg2pdfconverter +_ensure-sphinxcontrib-svg2pdfconverter: + $(MAKE) _ensure-package PACKAGE=sphinxcontrib-svg2pdfconverter + +.PHONY: check +check: _ensure-pre-commit + $(VENVDIR)/bin/python3 -m pre_commit run --all-files + +.PHONY: serve +serve: + @echo "The serve target was removed, use htmllive instead (see gh-80510)" + +# Targets for daily automated doc build +# By default, Sphinx only rebuilds pages where the page content has changed. +# This means it doesn't always pick up changes to preferred link targets, etc +# To ensure such changes are picked up, we build the published docs with +# ``--fresh-env`` (to ignore the cached environment) and ``--write-all`` +# (to ignore already existing output files) + +# for development releases: always build +.PHONY: autobuild-dev +autobuild-dev: DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py --short) +autobuild-dev: + $(MAKE) dist-no-html SPHINXOPTS='$(SPHINXOPTS) --fresh-env --write-all --html-define daily=1' DISTVERSION=$(DISTVERSION) + +# for HTML-only rebuilds +.PHONY: autobuild-dev-html +autobuild-dev-html: DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py --short) +autobuild-dev-html: + $(MAKE) dist-html SPHINXOPTS='$(SPHINXOPTS) --fresh-env --write-all --html-define daily=1' DISTVERSION=$(DISTVERSION) + +# for stable releases: only build if not in pre-release stage (alpha, beta) +# release candidate downloads are okay, since the stable tree can be in that stage +.PHONY: autobuild-stable +autobuild-stable: + @case $(DISTVERSION) in *[ab]*) \ + echo "Not building; $(DISTVERSION) is not a release version."; \ + exit 1;; \ + esac + @$(MAKE) autobuild-dev + +.PHONY: autobuild-stable-html +autobuild-stable-html: + @case $(DISTVERSION) in *[ab]*) \ + echo "Not building; $(DISTVERSION) is not a release version."; \ + exit 1;; \ + esac + @$(MAKE) autobuild-dev-html + +# Collect HTML IDs to a JSON document +.PHONY: html-ids +html-ids: + $(PYTHON) tools/check-html-ids.py collect build/html \ + -o build/html/html-ids.json.gz diff --git a/stdlib/kvlang/reference/python/cpython/Doc/README.rst b/stdlib/kvlang/reference/python/cpython/Doc/README.rst new file mode 100644 index 00000000..2d114875 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/README.rst @@ -0,0 +1,137 @@ +Python Documentation README +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This directory contains the reStructuredText (reST) sources to the Python +documentation. You don't need to build them yourself, `prebuilt versions are +available `_. + +Documentation on authoring Python documentation, including information about +both style and markup, is available in the "`Documenting Python +`_" chapter of the +developers guide. + + +Building the docs +================= + +The documentation is built with several tools which are not included in this +tree but are maintained separately and are available from +`PyPI `_. + +* `Sphinx `_ +* `blurb `_ +* `python-docs-theme `_ + +The easiest way to install these tools is to create a virtual environment and +install the tools into there. + +Using make +---------- + +To get started on Unix, you can create a virtual environment and build +documentation with the commands:: + + make venv + make html + +The virtual environment in the ``venv`` directory will contain all the tools +necessary to build the documentation downloaded and installed from PyPI. +If you'd like to create the virtual environment in a different location, +you can specify it using the ``VENVDIR`` variable. + +You can also skip creating the virtual environment altogether, in which case +the ``Makefile`` will look for instances of ``sphinx-build`` and ``blurb`` +installed on your process ``PATH`` (configurable with the ``SPHINXBUILD`` and +``BLURB`` variables). + +On Windows, we try to emulate the ``Makefile`` as closely as possible with a +``make.bat`` file. If you need to specify the Python interpreter to use, +set the ``PYTHON`` environment variable. + +Available make targets are: + +* "clean", which removes all build files and the virtual environment. + +* "clean-venv", which removes the virtual environment directory. + +* "venv", which creates a virtual environment with all necessary tools + installed. + +* "html", which builds standalone HTML files for offline viewing. + +* "htmlview", which re-uses the "html" builder, but then opens the main page + in your default web browser. + +* "htmllive", which re-uses the "html" builder, rebuilds the docs, + starts a local server, and automatically reloads the page in your browser + when you make changes to reST files (Unix only). + +* "htmlhelp", which builds HTML files and a HTML Help project file usable to + convert them into a single Compiled HTML (.chm) file -- these are popular + under Microsoft Windows, but very handy on every platform. + + To create the CHM file, you need to run the Microsoft HTML Help Workshop + over the generated project (.hhp) file. The ``make.bat`` script does this for + you on Windows. + +* "latex", which builds LaTeX source files as input to ``pdflatex`` to produce + PDF documents. + +* "text", which builds a plain text file for each source file. + +* "epub", which builds an EPUB document, suitable to be viewed on e-book + readers. + +* "linkcheck", which checks all external references to see whether they are + broken, redirected or malformed, and outputs this information to stdout as + well as a plain-text (.txt) file. + +* "changes", which builds an overview over all versionadded/versionchanged/ + deprecated items in the current version. This is meant as a help for the + writer of the "What's New" document. + +* "coverage", which builds a coverage overview for standard library modules and + C API. + +* "pydoc-topics", which builds a Python module containing a dictionary with + plain text documentation for the labels defined in + ``tools/pyspecific.py`` -- pydoc needs these to show topic and keyword help. + +* "check", which checks for frequent markup errors. + +* "dist", (Unix only) which creates distributable archives of HTML, text, + PDF, and EPUB builds. + + +Without make +------------ + +First, install the tool dependencies from PyPI. + +Then, from the ``Doc`` directory, run :: + + sphinx-build -b . build/ + +where ```` is one of html, text, latex, or htmlhelp (for explanations +see the make targets above). + +Deprecation header +================== + +You can define the ``outdated`` variable in ``html_context`` to show a +red banner on each page redirecting to the "latest" version. + +The link points to the same page on ``/3/``, sadly for the moment the +language is lost during the process. + + +Contributing +============ + +Bugs in the content should be reported to the +`Python bug tracker `_. + +Bugs in the toolset should be reported to the tools themselves. + +To help with the documentation, or report any problems, please leave a message +on `discuss.python.org `_. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/about.rst b/stdlib/kvlang/reference/python/cpython/Doc/about.rst new file mode 100644 index 00000000..84ae3492 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/about.rst @@ -0,0 +1,40 @@ +======================== +About this documentation +======================== + + +Python's documentation is generated from `reStructuredText`_ sources +using `Sphinx`_, a documentation generator originally created for Python +and now maintained as an independent project. + +.. _reStructuredText: https://docutils.sourceforge.io/rst.html +.. _Sphinx: https://www.sphinx-doc.org/ + +.. In the online version of this documentation, you can submit comments and suggest + changes directly on the documentation pages. + +Development of the documentation and its toolchain is an entirely volunteer +effort, just like Python itself. If you want to contribute, please take a +look at the :ref:`reporting-bugs` page for information on how to do so. New +volunteers are always welcome! + +Many thanks go to: + +* Fred L. Drake, Jr., the creator of the original Python documentation toolset + and author of much of the content; +* the `Docutils `_ project for creating + reStructuredText and the Docutils suite; +* Fredrik Lundh for his Alternative Python Reference project from which Sphinx + got many good ideas. + + +Contributors to the Python documentation +---------------------------------------- + +Many people have contributed to the Python language, the Python standard +library, and the Python documentation. See the `CPython +GitHub repository `__ +for a partial list of contributors. + +It is only with the input and contributions of the Python community +that Python has such wonderful documentation -- Thank You! diff --git a/stdlib/kvlang/reference/python/cpython/Doc/bugs.rst b/stdlib/kvlang/reference/python/cpython/Doc/bugs.rst new file mode 100644 index 00000000..a6ea0a72 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/bugs.rst @@ -0,0 +1,116 @@ +.. _reporting-bugs: + +***************** +Dealing with Bugs +***************** + +Python is a mature programming language which has established a reputation for +stability. In order to maintain this reputation, the developers would like to +know of any deficiencies you find in Python. + +It can be sometimes faster to fix bugs yourself and contribute patches to +Python as it streamlines the process and involves fewer people. Learn how to +:ref:`contribute `. + + +.. _reporting-documentation-bugs: + +Documentation bugs +================== + +If you find a bug in this documentation or would like to propose an improvement, +please submit a bug report on the :ref:`issue tracker `. If you +have a suggestion on how to fix it, include that as well. + +.. only:: translation + + If the bug or suggested improvement concerns the translation of this + documentation, submit the report to the + `translation’s repository `_ instead. + +You can also open a discussion item on our +`Documentation Discourse forum `_. + +If you find a bug in the theme (HTML / CSS / JavaScript) of the +documentation, please submit a bug report on the `python-doc-theme issue +tracker `_. + +.. seealso:: + + `Documentation bugs`_ + A list of documentation bugs that have been submitted to the Python issue tracker. + + `Issue Tracking `_ + Overview of the process involved in reporting an improvement on the tracker. + + `Helping with Documentation `_ + Comprehensive guide for individuals that are interested in contributing to Python documentation. + + `Documentation Translations `_ + A list of GitHub pages for documentation translation and their coordination teams. + + +.. _using-the-tracker: + +Using the Python issue tracker +============================== + +Issue reports for Python itself should be submitted via the GitHub issues +tracker (https://github.com/python/cpython/issues). +The GitHub issues tracker offers a web form which allows pertinent information +to be entered and submitted to the developers. + +The first step in filing a report is to determine whether the problem has +already been reported. The advantage in doing so, aside from saving the +developers' time, is that you learn what has been done to fix it; it may be that +the problem has already been fixed for the next release, or additional +information is needed (in which case you are welcome to provide it if you can!). +To do this, search the tracker using the search box at the top of the page. + +If the problem you're reporting is not already in the list, log in to GitHub. +If you don't already have a GitHub account, create a new account using the +"Sign up" link. +It is not possible to submit a bug report anonymously. + +Being now logged in, you can submit an issue. +Click on the "New issue" button in the top bar to report a new issue. + +The submission form has two fields, "Title" and "Comment". + +For the "Title" field, enter a *very* short description of the problem; +fewer than ten words is good. + +In the "Comment" field, describe the problem in detail, including what you +expected to happen and what did happen. Be sure to include whether any +extension modules were involved, and what hardware and software platform you +were using (including version information as appropriate). + +Each issue report will be reviewed by a developer who will determine what needs to +be done to correct the problem. You will receive an update each time an action is +taken on the issue. + + +.. seealso:: + + `How to Report Bugs Effectively `_ + Article which goes into some detail about how to create a useful bug report. + This describes what kind of information is useful and why it is useful. + + `Bug Writing Guidelines `_ + Information about writing a good bug report. Some of this is specific to the + Mozilla project, but describes general good practices. + +.. _contributing-to-python: + +Getting started contributing to Python yourself +=============================================== + +Beyond just reporting bugs that you find, you are also welcome to submit +patches to fix them. You can find more information on how to get started +patching Python in the `Python Developer's Guide`_. If you have questions, +the `core-mentorship mailing list`_ is a friendly place to get answers to +any and all questions pertaining to the process of fixing issues in Python. + +.. _Documentation bugs: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Adocs +.. _Python Developer's Guide: https://devguide.python.org/ +.. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/ diff --git a/stdlib/kvlang/reference/python/cpython/Doc/conf.py b/stdlib/kvlang/reference/python/cpython/Doc/conf.py new file mode 100644 index 00000000..c768e6fd --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/conf.py @@ -0,0 +1,608 @@ +# +# Python documentation build configuration file +# +# This file is execfile()d with the current directory set to its containing dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed automatically). + +import os +import sys +from importlib.util import find_spec + +# Make our custom extensions available to Sphinx +sys.path.append(os.path.abspath('tools/extensions')) +sys.path.append(os.path.abspath('includes')) + +from patchlevel import get_header_version_info, get_version_info + +# General configuration +# --------------------- + +# Our custom Sphinx extensions are found in Doc/Tools/extensions/ +extensions = [ + 'audit_events', + 'availability', + 'c_annotations', + 'changes', + 'glossary_search', + 'grammar_snippet', + 'implementation_detail', + 'issue_role', + 'lexers', + 'misc_news', + 'profiling_trace', + 'pydoc_topics', + 'pyspecific', + 'sphinx.ext.coverage', + 'sphinx.ext.doctest', + 'sphinx.ext.extlinks', +] + +# Skip if downstream redistributors haven't installed them +_OPTIONAL_EXTENSIONS = ( + 'sphinx_linklint.ext', + 'notfound.extension', + 'sphinxext.opengraph', + 'sphinxcontrib.rsvgconverter', +) +for optional_ext in _OPTIONAL_EXTENSIONS: + try: + if find_spec(optional_ext) is not None: + extensions.append(optional_ext) + except (ImportError, ValueError): + pass +del _OPTIONAL_EXTENSIONS + +doctest_global_setup = ''' +try: + import _tkinter +except ImportError: + _tkinter = None +# Treat warnings as errors, done here to prevent warnings in Sphinx code from +# causing spurious CPython test failures. +import warnings +warnings.simplefilter('error') +del warnings +''' + +manpages_url = 'https://manpages.debian.org/{path}' + +# General substitutions. +project = 'Python' +copyright = "2001 Python Software Foundation" +_doc_authors = 'Python documentation authors' + +# We look for the Include/patchlevel.h file in the current Python source tree +# and replace the values accordingly. +# See Doc/tools/extensions/patchlevel.py +version, release = get_version_info() + +rst_epilog = f""" +.. |python_version_literal| replace:: ``Python {version}`` +.. |python_x_dot_y_literal| replace:: ``python{version}`` +.. |python_x_dot_y_t_literal| replace:: ``python{version}t`` +.. |python_x_dot_y_t_literal_config| replace:: ``python{version}t-config`` +.. |x_dot_y_b2_literal| replace:: ``{version}.0b2`` +.. |applications_python_version_literal| replace:: ``/Applications/Python {version}/`` +.. |usr_local_bin_python_x_dot_y_literal| replace:: ``/usr/local/bin/python{version}`` + +.. Apparently this how you hack together a formatted link: + (https://www.docutils.org/docs/ref/rst/directives.html#replacement-text) +.. |FORCE_COLOR| replace:: ``FORCE_COLOR`` +.. _FORCE_COLOR: https://force-color.org/ +.. |NO_COLOR| replace:: ``NO_COLOR`` +.. _NO_COLOR: https://no-color.org/ +""" + +# There are two options for replacing |today|. Either, you set today to some +# non-false value and use it. +today = '' +# Or else, today_fmt is used as the format for a strftime call. +today_fmt = '%B %d, %Y' + +# By default, highlight as Python 3. +highlight_language = 'python3' + +# Minimum version of sphinx required +# Keep this version in sync with ``Doc/requirements.txt``. +needs_sphinx = '8.2.0' + +# Create table of contents entries for domain objects (e.g. functions, classes, +# attributes, etc.). Default is True. +toc_object_entries = False + +# Ignore any .rst files in the includes/ directory; +# they're embedded in pages but not rendered as individual pages. +# Ignore any .rst files in the venv/ directory. +exclude_patterns = ['includes/*.rst', 'venv/*', 'README.rst'] +venvdir = os.getenv('VENVDIR') +if venvdir is not None: + exclude_patterns.append(venvdir + '/*') + +nitpick_ignore = [ + # Standard C functions + ('c:func', 'calloc'), + ('c:func', 'ctime'), + ('c:func', 'dlopen'), + ('c:func', 'exec'), + ('c:func', 'fcntl'), + ('c:func', 'flock'), + ('c:func', 'fork'), + ('c:func', 'free'), + ('c:func', 'gettimeofday'), + ('c:func', 'gmtime'), + ('c:func', 'grantpt'), + ('c:func', 'ioctl'), + ('c:func', 'localeconv'), + ('c:func', 'localtime'), + ('c:func', 'main'), + ('c:func', 'malloc'), + ('c:func', 'mktime'), + ('c:func', 'posix_openpt'), + ('c:func', 'printf'), + ('c:func', 'ptsname'), + ('c:func', 'ptsname_r'), + ('c:func', 'realloc'), + ('c:func', 'snprintf'), + ('c:func', 'sprintf'), + ('c:func', 'stat'), + ('c:func', 'strftime'), + ('c:func', 'system'), + ('c:func', 'time'), + ('c:func', 'unlockpt'), + ('c:func', 'vsnprintf'), + # Standard C types + ('c:type', 'FILE'), + ('c:type', 'int8_t'), + ('c:type', 'int16_t'), + ('c:type', 'int32_t'), + ('c:type', 'int64_t'), + ('c:type', 'intmax_t'), + ('c:type', 'off_t'), + ('c:type', 'ptrdiff_t'), + ('c:type', 'siginfo_t'), + ('c:type', 'size_t'), + ('c:type', 'ssize_t'), + ('c:type', 'time_t'), + ('c:type', 'uint8_t'), + ('c:type', 'uint16_t'), + ('c:type', 'uint32_t'), + ('c:type', 'uint64_t'), + ('c:type', 'uintmax_t'), + ('c:type', 'uintptr_t'), + ('c:type', 'va_list'), + ('c:type', 'wchar_t'), + ('c:type', '__int64'), + ('c:type', 'unsigned __int64'), + ('c:type', 'double'), + ('c:type', '_Float16'), + # Standard C structures + ('c:struct', 'in6_addr'), + ('c:struct', 'in_addr'), + ('c:struct', 'stat'), + ('c:struct', 'statvfs'), + ('c:struct', 'timeval'), + ('c:struct', 'timespec'), + # Standard C macros + ('c:macro', 'LLONG_MAX'), + ('c:macro', 'LLONG_MIN'), + ('c:macro', 'LONG_MAX'), + ('c:macro', 'LONG_MIN'), + # Standard C variables + ('c:data', 'errno'), + # Standard environment variables + ('envvar', 'BROWSER'), + ('envvar', 'COLUMNS'), + ('envvar', 'COMSPEC'), + ('envvar', 'DISPLAY'), + ('envvar', 'HOME'), + ('envvar', 'HOMEDRIVE'), + ('envvar', 'HOMEPATH'), + ('envvar', 'IDLESTARTUP'), + ('envvar', 'LANG'), + ('envvar', 'LANGUAGE'), + ('envvar', 'LC_ALL'), + ('envvar', 'LC_CTYPE'), + ('envvar', 'LC_COLLATE'), + ('envvar', 'LC_MESSAGES'), + ('envvar', 'LC_MONETARY'), + ('envvar', 'LC_NUMERIC'), + ('envvar', 'LC_TIME'), + ('envvar', 'LINES'), + ('envvar', 'LOGNAME'), + ('envvar', 'MANPAGER'), + ('envvar', 'PAGER'), + ('envvar', 'PATH'), + ('envvar', 'PATHEXT'), + ('envvar', 'SOURCE_DATE_EPOCH'), + ('envvar', 'TEMP'), + ('envvar', 'TERM'), + ('envvar', 'TMP'), + ('envvar', 'TMPDIR'), + ('envvar', 'TZ'), + ('envvar', 'USER'), + ('envvar', 'USERNAME'), + ('envvar', 'USERPROFILE'), +] + +# Temporary undocumented names. +# In future this list must be empty. +nitpick_ignore += [ + # Attributes/methods/etc. that definitely should be documented better, + # but are deferred for now: + ('py:attr', '__wrapped__'), +] + +# gh-106948: Copy standard C types declared in the "c:type" domain and C +# structures declared in the "c:struct" domain to the "c:identifier" domain, +# since "c:function" markup looks for types in the "c:identifier" domain. Use +# list() to not iterate on items which are being added +for role, name in list(nitpick_ignore): + if role in ('c:type', 'c:struct'): + nitpick_ignore.append(('c:identifier', name)) +del role, name + +# Disable Docutils smartquotes for several translations +smartquotes_excludes = { + 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], + 'builders': ['man', 'text'], +} + +# Avoid a warning with Sphinx >= 4.0 +root_doc = 'contents' + +# Allow translation of index directives +gettext_additional_targets = [ + 'index', + 'literal-block', +] + +# Options for HTML output +# ----------------------- + +# Use our custom theme: https://github.com/python/python-docs-theme +html_theme = 'python_docs_theme' +# Location of overrides for theme templates and static files +html_theme_path = ['tools'] +html_theme_options = { + 'collapsiblesidebar': True, + 'issues_url': '/bugs.html', + 'license_url': '/license.html', + 'root_include_title': False, # We use the version switcher instead. +} + +if os.getenv("READTHEDOCS"): + html_theme_options["hosted_on"] = ( + 'Read the Docs' + ) + +# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207 +# https://github.com/python/cpython/issues/91207 +if any('htmlhelp' in arg for arg in sys.argv): + html_style = 'pydoctheme.css' + print("\nWARNING: Windows CHM Help is no longer supported.") + print("It may be removed in the future\n") + +# Short title used e.g. for HTML tags. +html_short_title = f'{release} Documentation' + +# Deployment preview information +# (See .readthedocs.yml and https://docs.readthedocs.io/en/stable/reference/environment-variables.html) +is_deployment_preview = os.getenv("READTHEDOCS_VERSION_TYPE") == "external" +repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL", "") +repository_url = repository_url.removesuffix(".git") +html_context = { + "is_deployment_preview": is_deployment_preview, + "repository_url": repository_url or None, + "pr_id": os.getenv("READTHEDOCS_VERSION"), + "enable_analytics": os.getenv("PYTHON_DOCS_ENABLE_ANALYTICS"), +} + +# This 'Last updated on:' timestamp is inserted at the bottom of every page. +html_last_updated_fmt = '%b %d, %Y (%H:%M UTC)' +html_last_updated_use_utc = True + +# Path to find HTML templates to override theme +templates_path = ['tools/templates'] + +# Custom sidebar templates, filenames relative to this file. +html_sidebars = { + # Defaults taken from https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_sidebars + # Removes the quick search block + '**': ['localtoc.html', 'relations.html', 'customsourcelink.html'], + 'index': ['indexsidebar.html'], +} + +# Additional templates that should be rendered to pages. +html_additional_pages = { + 'download': 'download.html', + 'index': 'indexcontent.html', +} + +# Output an OpenSearch description file. +html_use_opensearch = 'https://docs.python.org/' + version + +# Additional static files. +html_static_path = ['_static', 'tools/static'] + +# Output file base name for HTML help builder. +htmlhelp_basename = 'python' + release.replace('.', '') + +# Split the index +html_split_index = True + +# Split pot files one per reST file +gettext_compact = False + +# Options for LaTeX output +# ------------------------ + +latex_engine = 'xelatex' + +latex_elements = { + # For the LaTeX preamble. + 'preamble': r''' +\authoraddress{ + \sphinxstrong{Python Software Foundation}\\ + Email: \sphinxemail{docs@python.org} +} +\setcounter{tocdepth}{2} +''', + # The paper size ('letterpaper' or 'a4paper'). + 'papersize': 'a4paper', + # The font size ('10pt', '11pt' or '12pt'). + 'pointsize': '10pt', + 'maxlistdepth': '8', # See https://github.com/python/cpython/issues/139588 +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, document class [howto/manual]). +latex_documents = [ + ('c-api/index', 'c-api.tex', 'The Python/C API', _doc_authors, 'manual'), + ( + 'extending/index', + 'extending.tex', + 'Extending and Embedding Python', + _doc_authors, + 'manual', + ), + ( + 'installing/index', + 'installing.tex', + 'Installing Python Modules', + _doc_authors, + 'manual', + ), + ( + 'library/index', + 'library.tex', + 'The Python Library Reference', + _doc_authors, + 'manual', + ), + ( + 'reference/index', + 'reference.tex', + 'The Python Language Reference', + _doc_authors, + 'manual', + ), + ( + 'tutorial/index', + 'tutorial.tex', + 'Python Tutorial', + _doc_authors, + 'manual', + ), + ( + 'using/index', + 'using.tex', + 'Python Setup and Usage', + _doc_authors, + 'manual', + ), + ( + 'faq/index', + 'faq.tex', + 'Python Frequently Asked Questions', + _doc_authors, + 'manual', + ), + ( + 'whatsnew/' + version, + 'whatsnew.tex', + 'What\'s New in Python', + _doc_authors, + 'howto', + ), +] +# Collect all HOWTOs individually +latex_documents.extend( + ( + 'howto/' + fn[:-4], + 'howto-' + fn[:-4] + '.tex', + '', + _doc_authors, + 'howto', + ) + for fn in os.listdir('howto') + if fn.endswith('.rst') and fn != 'index.rst' +) + +# Documents to append as an appendix to all manuals. +latex_appendices = ['glossary', 'about', 'license', 'copyright'] + +# Options for Epub output +# ----------------------- + +epub_author = _doc_authors +epub_publisher = 'Python Software Foundation' +epub_exclude_files = ( + 'index.xhtml', + 'download.xhtml', + '_static/tachyon-example-flamegraph.html', + '_static/tachyon-example-heatmap.html', +) + +# index pages are not valid xhtml +# https://github.com/sphinx-doc/sphinx/issues/12359 +epub_use_index = False + +# translation tag +# --------------- + +language_code = None +for arg in sys.argv: + if arg.startswith('language='): + language_code = arg.split('=', 1)[1] + +if language_code: + tags.add('translation') # noqa: F821 + + rst_epilog += f"""\ +.. _TRANSLATION_REPO: https://github.com/python/python-docs-{language_code.replace("_", "-").lower()} +""" # noqa: F821 +else: + rst_epilog += """\ +.. _TRANSLATION_REPO: https://github.com/python +""" + +# Options for the coverage checker +# -------------------------------- + +# The coverage checker will ignore all modules/functions/classes whose names +# match any of the following regexes (using re.match). +coverage_ignore_modules = [ + r'[T|t][k|K]', +] + +coverage_ignore_functions = [ + 'test($|_)', +] + +coverage_ignore_classes = [] + +# Glob patterns for C source files for C API coverage, relative to this directory. +coverage_c_path = [ + '../Include/*.h', +] + +# Regexes to find C items in the source files. +coverage_c_regexes = { + 'cfunction': r'^PyAPI_FUNC\(.*\)\s+([^_][\w_]+)', + 'data': r'^PyAPI_DATA\(.*\)\s+([^_][\w_]+)', + 'macro': r'^#define ([^_][\w_]+)\(.*\)[\s|\\]', +} + +# The coverage checker will ignore all C items whose names match these regexes +# (using re.match) -- the keys must be the same as in coverage_c_regexes. +coverage_ignore_c_items = { + # 'cfunction': [...] +} + + +# Options for the link checker +# ---------------------------- + +linkcheck_allowed_redirects = { + # bpo-NNNN -> BPO -> GH Issues + r'https://bugs.python.org/issue\?@action=redirect&bpo=\d+': r'https://github.com/python/cpython/issues/\d+', + # GH-NNNN used to refer to pull requests + r'https://github.com/python/cpython/issues/\d+': r'https://github.com/python/cpython/pull/\d+', + # :source:`something` linking files in the repository + r'https://github.com/python/cpython/tree/.*': 'https://github.com/python/cpython/blob/.*', + # Intentional HTTP use at Misc/NEWS.d/3.5.0a1.rst + r'http://www.python.org/$': 'https://www.python.org/$', + # Microsoft's redirects to learn.microsoft.com + r'https://msdn.microsoft.com/.*': 'https://learn.microsoft.com/.*', + r'https://docs.microsoft.com/.*': 'https://learn.microsoft.com/.*', + r'https://go.microsoft.com/fwlink/\?LinkID=\d+': 'https://learn.microsoft.com/.*', + # Debian's man page redirects to its current stable version + r'https://manpages.debian.org/\w+\(\d(\w+)?\)': r'https://manpages.debian.org/\w+/[\w/\-\.]*\.\d(\w+)?\.en\.html', + # Language redirects + r'https://toml.io': 'https://toml.io/en/', + r'https://www.redhat.com': 'https://www.redhat.com/en', + # pypi.org project name normalization (upper to lowercase, underscore to hyphen) + r'https://pypi.org/project/[A-Za-z\d_\-\.]+/': r'https://pypi.org/project/[a-z\d\-\.]+/', + # Discourse title name expansion (text changes when title is edited) + r'https://discuss\.python\.org/t/\d+': r'https://discuss\.python\.org/t/.*/\d+', + # Other redirects + r'https://www.boost.org/libs/.+': r'https://www.boost.org/doc/libs/\d_\d+_\d/.+', + r'https://support.microsoft.com/en-us/help/\d+': 'https://support.microsoft.com/en-us/topic/.+', + r'https://perf.wiki.kernel.org$': 'https://perf.wiki.kernel.org/index.php/Main_Page', + r'https://www.sqlite.org': 'https://www.sqlite.org/index.html', + r'https://mitpress.mit.edu/sicp$': 'https://mitpress.mit.edu/9780262510875/structure-and-interpretation-of-computer-programs/', + r'https://www.python.org/psf/': 'https://www.python.org/psf-landing/', +} + +linkcheck_anchors_ignore = [ + # ignore anchors that start with a '/', e.g. Wikipedia media files: + # https://en.wikipedia.org/wiki/Walrus#/media/File:Pacific_Walrus_-_Bull_(8247646168).jpg + r'\/.*', +] + +linkcheck_ignore = [ + # The crawler gets "Anchor not found" + r'https://developer.apple.com/documentation/.+?#.*', + r'https://devguide.python.org.+?/#.*', + r'https://github.com.+?#.*', + # Robot crawlers not allowed: "403 Client Error: Forbidden" + r'https://support.enthought.com/hc/.*', + # SSLError CertificateError, even though it is valid + r'https://unix.org/version2/whatsnew/lp64_wp.html', +] + + +# Options for sphinx.ext.extlinks +# ------------------------------- + +v = get_header_version_info() +branch = "main" if v.releaselevel == "alpha" else f"{v.major}.{v.minor}" + +# This config is a dictionary of external sites, +# mapping unique short aliases to a base URL and a prefix. +# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html +extlinks = { + "oss-fuzz": ("https://issues.oss-fuzz.com/issues/%s", "#%s"), + "pypi": ("https://pypi.org/project/%s/", "%s"), + "source": (f"https://github.com/python/cpython/tree/{branch}/%s", "%s"), +} +extlinks_detect_hardcoded_links = True + +# Options for c_annotations extension +# ----------------------------------- + +# Relative filename of the data files +refcount_file = 'data/refcounts.dat' +stable_abi_file = 'data/stable_abi.dat' +threadsafety_file = 'data/threadsafety.dat' + +# Options for notfound.extension +# ------------------------------- + +if not os.getenv("READTHEDOCS"): + if language_code: + notfound_urls_prefix = ( + f'/{language_code.replace("_", "-").lower()}/{version}/' + ) + else: + notfound_urls_prefix = f'/{version}/' + +# Options for sphinxext-opengraph +# ------------------------------- + +ogp_canonical_url = 'https://docs.python.org/3/' +ogp_site_name = 'Python documentation' +ogp_social_cards = { # Used when matplotlib is installed + 'image': '_static/og-image.png', + 'line_color': '#3776ab', +} +ogp_custom_meta_tags = ('<meta name="theme-color" content="#3776ab">',) +if 'create-social-cards' not in tags: # noqa: F821 + # Define a static preview image when not creating social cards + ogp_image = '_static/og-image.png' + ogp_custom_meta_tags += ( + '<meta property="og:image:width" content="200">', + '<meta property="og:image:height" content="200">', + ) diff --git a/stdlib/kvlang/reference/python/cpython/Doc/constraints.txt b/stdlib/kvlang/reference/python/cpython/Doc/constraints.txt new file mode 100644 index 00000000..29cd4be1 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/constraints.txt @@ -0,0 +1,24 @@ +# We have upper bounds on our transitive dependencies here +# To avoid new releases unexpectedly breaking our build. +# This file can be updated on an ad-hoc basis, +# though it will probably have to be updated +# whenever Doc/requirements.txt is updated. + +# Direct dependencies of Sphinx +babel<3 +colorama<0.5 +imagesize<2 +Jinja2<4 +packaging<25 +Pygments<3 +requests<3 +snowballstemmer<3 +sphinxcontrib-applehelp<3 +sphinxcontrib-devhelp<3 +sphinxcontrib-htmlhelp<3 +sphinxcontrib-jsmath<2 +sphinxcontrib-qthelp<3 +sphinxcontrib-serializinghtml<3 + +# Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above) +MarkupSafe<3 diff --git a/stdlib/kvlang/reference/python/cpython/Doc/contents.rst b/stdlib/kvlang/reference/python/cpython/Doc/contents.rst new file mode 100644 index 00000000..b57f4b09 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/contents.rst @@ -0,0 +1,23 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + Python Documentation contents +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +.. toctree:: + + whatsnew/index.rst + tutorial/index.rst + using/index.rst + reference/index.rst + library/index.rst + extending/index.rst + c-api/index.rst + installing/index.rst + howto/index.rst + faq/index.rst + deprecations/index.rst + glossary.rst + + about.rst + bugs.rst + copyright.rst + license.rst diff --git a/stdlib/kvlang/reference/python/cpython/Doc/copyright.rst b/stdlib/kvlang/reference/python/cpython/Doc/copyright.rst new file mode 100644 index 00000000..9210d5f5 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/copyright.rst @@ -0,0 +1,19 @@ +********* +Copyright +********* + +Python and this documentation is: + +Copyright © 2001 Python Software Foundation. All rights reserved. + +Copyright © 2000 BeOpen.com. All rights reserved. + +Copyright © 1995-2000 Corporation for National Research Initiatives. All rights +reserved. + +Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved. + +------- + +See :ref:`history-and-license` for complete license and permissions information. + diff --git a/stdlib/kvlang/reference/python/cpython/Doc/glossary.rst b/stdlib/kvlang/reference/python/cpython/Doc/glossary.rst new file mode 100644 index 00000000..cd9d38b2 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/glossary.rst @@ -0,0 +1,1732 @@ +.. _glossary: + +******** +Glossary +******** + +.. if you add new entries, keep the alphabetical sorting! + +.. glossary:: + + ``>>>`` + The default Python prompt of the :term:`interactive` shell. Often + seen for code examples which can be executed interactively in the + interpreter. + + ``...`` + Can refer to: + + * The default Python prompt of the :term:`interactive` shell when entering the + code for an indented code block, when within a pair of matching left and + right delimiters (parentheses, square brackets, curly braces or triple + quotes), or after specifying a decorator. + + .. index:: single: ...; ellipsis literal + + * The three dots form of the :ref:`Ellipsis <bltin-ellipsis-object>` object. + + abstract base class + Abstract base classes complement :term:`duck-typing` by + providing a way to define interfaces when other techniques like + :func:`hasattr` would be clumsy or subtly wrong (for example with + :ref:`magic methods <special-lookup>`). ABCs introduce virtual + subclasses, which are classes that don't inherit from a class but are + still recognized by :func:`isinstance` and :func:`issubclass`; see the + :mod:`abc` module documentation. Python comes with many built-in ABCs for + data structures (in the :mod:`collections.abc` module), numbers (in the + :mod:`numbers` module), streams (in the :mod:`io` module), import finders + and loaders (in the :mod:`importlib.abc` module). You can create your own + ABCs with the :mod:`abc` module. + + annotate function + A callable that can be called to retrieve the :term:`annotations <annotation>` of + an object. Annotate functions are usually :term:`functions <function>`, + automatically generated as the :attr:`~object.__annotate__` attribute of functions, + classes, and modules. Annotate functions are a subset of + :term:`evaluate functions <evaluate function>`. + + annotation + A label associated with a variable, a class + attribute or a function parameter or return value, + used by convention as a :term:`type hint`. + + Annotations of local variables cannot be accessed at runtime, but + annotations of global variables, class attributes, and functions + can be retrieved by calling :func:`annotationlib.get_annotations` + on modules, classes, and functions, respectively. + + See :term:`variable annotation`, :term:`function annotation`, :pep:`484`, + :pep:`526`, and :pep:`649`, which describe this functionality. + Also see :ref:`annotations-howto` + for best practices on working with annotations. + + argument + A value passed to a :term:`function` (or :term:`method`) when calling the + function. There are two kinds of argument: + + * :dfn:`keyword argument`: an argument preceded by an identifier (e.g. + ``name=``) in a function call or passed as a value in a dictionary + preceded by ``**``. For example, ``3`` and ``5`` are both keyword + arguments in the following calls to :func:`complex`:: + + complex(real=3, imag=5) + complex(**{'real': 3, 'imag': 5}) + + * :dfn:`positional argument`: an argument that is not a keyword argument. + Positional arguments can appear at the beginning of an argument list + and/or be passed as elements of an :term:`iterable` preceded by ``*``. + For example, ``3`` and ``5`` are both positional arguments in the + following calls:: + + complex(3, 5) + complex(*(3, 5)) + + Arguments are assigned to the named local variables in a function body. + See the :ref:`calls` section for the rules governing this assignment. + Syntactically, any expression can be used to represent an argument; the + evaluated value is assigned to the local variable. + + See also the :term:`parameter` glossary entry, the FAQ question on + :ref:`the difference between arguments and parameters + <faq-argument-vs-parameter>`, and :pep:`362`. + + asynchronous context manager + An object which controls the environment seen in an + :keyword:`async with` statement by defining :meth:`~object.__aenter__` and + :meth:`~object.__aexit__` methods. Introduced by :pep:`492`. + + asynchronous generator + Informally used to mean either an :term:`asynchronous generator + function` or an :term:`asynchronous generator iterator`, depending on + context. The formal terms :term:`asynchronous generator function` and + :term:`asynchronous generator iterator` are uncommon in practice; + "asynchronous generator" alone is almost always sufficient. + + asynchronous generator function + A function which returns an :term:`asynchronous generator iterator`. + It looks like a coroutine function defined with :keyword:`async def` + except that it contains :keyword:`yield` expressions for producing a + series of values usable in an :keyword:`async for` loop. See :pep:`525`. + + An asynchronous generator function may contain :keyword:`await` + expressions as well as :keyword:`async for`, and :keyword:`async with` + statements. + + asynchronous generator iterator + An object created by an :term:`asynchronous generator function`. + + This is an :term:`asynchronous iterator` which when called using the + :meth:`~object.__anext__` method returns an awaitable object which will execute + the body of the asynchronous generator function until the next + :keyword:`yield` expression. + + Each :keyword:`yield` temporarily suspends processing, remembering the + execution state (including local variables and pending + try-statements). When the *asynchronous generator iterator* effectively + resumes with another awaitable returned by :meth:`~object.__anext__`, it + picks up where it left off. See :pep:`492` and :pep:`525`. + + asynchronous iterable + An object, that can be used in an :keyword:`async for` statement. + Must return an :term:`asynchronous iterator` from its + :meth:`~object.__aiter__` method. Introduced by :pep:`492`. + + asynchronous iterator + An object that implements the :meth:`~object.__aiter__` and :meth:`~object.__anext__` + methods. :meth:`~object.__anext__` must return an :term:`awaitable` object. + :keyword:`async for` resolves the awaitables returned by an asynchronous + iterator's :meth:`~object.__anext__` method until it raises a + :exc:`StopAsyncIteration` exception. Introduced by :pep:`492`. + + atomic operation + An operation that appears to execute as a single, indivisible step: no + other thread can observe it half-done, and its effects become visible all + at once. Python does not guarantee that high-level statements are atomic + (for example, ``x += 1`` performs multiple bytecode operations and is not + atomic). Atomicity is only guaranteed where explicitly documented. See + also :term:`race condition` and :term:`data race`. + + attached thread state + + A :term:`thread state` that is active for the current OS thread. + + When a :term:`thread state` is attached, the OS thread has + access to the full Python C API and can safely invoke the + bytecode interpreter. + + Unless a function explicitly notes otherwise, attempting to call + the C API without an attached thread state will result in a fatal + error or undefined behavior. A thread state can be attached and detached + explicitly by the user through the C API, or implicitly by the runtime, + including during blocking C calls and by the bytecode interpreter in between + calls. + + On most builds of Python, having an attached thread state implies that the + caller holds the :term:`GIL` for the current interpreter, so only + one OS thread can have an attached thread state at a given moment. In + :term:`free-threaded builds <free-threaded build>` of Python, threads can + concurrently hold an attached thread state, allowing for true parallelism of + the bytecode interpreter. + + attribute + A value associated with an object which is usually referenced by name + using dotted expressions. + For example, if an object *o* has an attribute + *a* it would be referenced as *o.a*. + + It is possible to give an object an attribute whose name is not an + identifier as defined by :ref:`identifiers`, for example using + :func:`setattr`, if the object allows it. + Such an attribute will not be accessible using a dotted expression, + and would instead need to be retrieved with :func:`getattr`. + + awaitable + An object that can be used in an :keyword:`await` expression. Can be + a :term:`coroutine` or an object with an :meth:`~object.__await__` method. + See also :pep:`492`. + + BDFL + Benevolent Dictator For Life, a.k.a. `Guido van Rossum + <https://gvanrossum.github.io/>`_, Python's creator. + + binary file + A :term:`file object` able to read and write + :term:`bytes-like objects <bytes-like object>`. + Examples of binary files are files opened in binary mode (``'rb'``, + ``'wb'`` or ``'rb+'``), :data:`sys.stdin.buffer <sys.stdin>`, + :data:`sys.stdout.buffer <sys.stdout>`, and instances of + :class:`io.BytesIO` and :class:`gzip.GzipFile`. + + See also :term:`text file` for a file object able to read and write + :class:`str` objects. + + borrowed reference + In Python's C API, a borrowed reference is a reference to an object, + where the code using the object does not own the reference. + It becomes a dangling + pointer if the object is destroyed. For example, a garbage collection can + remove the last :term:`strong reference` to the object and so destroy it. + + Calling :c:func:`Py_INCREF` on the :term:`borrowed reference` is + recommended to convert it to a :term:`strong reference` in-place, except + when the object cannot be destroyed before the last usage of the borrowed + reference. The :c:func:`Py_NewRef` function can be used to create a new + :term:`strong reference`. + + bytes-like object + An object that supports the :ref:`bufferobjects` and can + export a C-:term:`contiguous` buffer. This includes all :class:`bytes`, + :class:`bytearray`, and :class:`array.array` objects, as well as many + common :class:`memoryview` objects. Bytes-like objects can + be used for various operations that work with binary data; these include + compression, saving to a binary file, and sending over a socket. + + Some operations need the binary data to be mutable. The documentation + often refers to these as "read-write bytes-like objects". Example + mutable buffer objects include :class:`bytearray` and a + :class:`memoryview` of a :class:`bytearray`. + Other operations require the binary data to be stored in + immutable objects ("read-only bytes-like objects"); examples + of these include :class:`bytes` and a :class:`memoryview` + of a :class:`bytes` object. + + bytecode + Python source code is compiled into bytecode, the internal representation + of a Python program in the CPython interpreter. The bytecode is also + cached in ``.pyc`` files so that executing the same file is + faster the second time (recompilation from source to bytecode can be + avoided). This "intermediate language" is said to run on a + :term:`virtual machine` that executes the machine code corresponding to + each bytecode. Do note that bytecodes are not expected to work between + different Python virtual machines, nor to be stable between Python + releases. + + A list of bytecode instructions can be found in the documentation for + :ref:`the dis module <bytecodes>`. + + callable + A callable is an object that can be called, possibly with a set + of arguments (see :term:`argument`), with the following syntax:: + + callable(argument1, argument2, argumentN) + + A :term:`function`, and by extension a :term:`method`, is a callable. + An instance of a class that implements the :meth:`~object.__call__` + method is also a callable. + + callback + A subroutine function which is passed as an argument to be executed at + some point in the future. + + class + A template for creating user-defined objects. Class definitions + normally contain method definitions which operate on instances of the + class. + + class variable + A variable defined in a class and intended to be modified only at + class level (i.e., not in an instance of the class). + + closure variable + A :term:`free variable` referenced from a :term:`nested scope` that is defined in an outer + scope rather than being resolved at runtime from the globals or builtin namespaces. + May be explicitly defined with the :keyword:`nonlocal` keyword to allow write access, + or implicitly defined if the variable is only being read. + + For example, in the ``inner`` function in the following code, both ``x`` and ``print`` are + :term:`free variables <free variable>`, but only ``x`` is a *closure variable*:: + + def outer(): + x = 0 + def inner(): + nonlocal x + x += 1 + print(x) + return inner + + Due to the :attr:`codeobject.co_freevars` attribute (which, despite its name, only + includes the names of closure variables rather than listing all referenced free + variables), the more general :term:`free variable` term is sometimes used even + when the intended meaning is to refer specifically to closure variables. + + complex number + An extension of the familiar real number system in which all numbers are + expressed as a sum of a real part and an imaginary part. Imaginary + numbers are real multiples of the imaginary unit (the square root of + ``-1``), often written ``i`` in mathematics or ``j`` in + engineering. Python has built-in support for complex numbers, which are + written with this latter notation; the imaginary part is written with a + ``j`` suffix, e.g., ``3+1j``. To get access to complex equivalents of the + :mod:`math` module, use :mod:`cmath`. Use of complex numbers is a fairly + advanced mathematical feature. If you're not aware of a need for them, + it's almost certain you can safely ignore them. + + concurrency + The ability of a computer program to perform multiple tasks at the same + time. Python provides libraries for writing programs that make use of + different forms of concurrency. :mod:`asyncio` is a library for dealing + with asynchronous tasks and coroutines. :mod:`threading` provides + access to operating system threads and :mod:`multiprocessing` to + operating system processes. Multi-core processors can execute threads and + processes on different CPU cores at the same time (see + :term:`parallelism`). + + concurrent modification + When multiple threads modify shared data at the same time. Concurrent + modification without proper synchronization can cause + :term:`race conditions <race condition>`, and might also trigger a + :term:`data race <data race>`, data corruption, or both. + + context + This term has different meanings depending on where and how it is used. + Some common meanings: + + * The temporary state or environment established by a :term:`context + manager` via a :keyword:`with` statement. + * The collection of key­value bindings associated with a particular + :class:`contextvars.Context` object and accessed via + :class:`~contextvars.ContextVar` objects. Also see :term:`context + variable`. + * A :class:`contextvars.Context` object. Also see :term:`current + context`. + + context management protocol + The :meth:`~object.__enter__` and :meth:`~object.__exit__` methods called + by the :keyword:`with` statement. See :pep:`343`. + + context manager + An object which implements the :term:`context management protocol` and + controls the environment seen in a :keyword:`with` statement. See + :pep:`343`. + + context variable + A variable whose value depends on which context is the :term:`current + context`. Values are accessed via :class:`contextvars.ContextVar` + objects. Context variables are primarily used to isolate state between + concurrent asynchronous tasks. + + contiguous + .. index:: C-contiguous, Fortran contiguous + + A buffer is considered contiguous exactly if it is either + *C-contiguous* or *Fortran contiguous*. Zero-dimensional buffers are + C and Fortran contiguous. In one-dimensional arrays, the items + must be laid out in memory next to each other, in order of + increasing indexes starting from zero. In multidimensional + C-contiguous arrays, the last index varies the fastest when + visiting items in order of memory address. However, in + Fortran contiguous arrays, the first index varies the fastest. + + coroutine + Coroutines are a more generalized form of subroutines. Subroutines are + entered at one point and exited at another point. Coroutines can be + entered, exited, and resumed at many different points. They can be + implemented with the :keyword:`async def` statement. See also + :pep:`492`. + + coroutine function + A function which returns a :term:`coroutine` object. A coroutine + function may be defined with the :keyword:`async def` statement, + and may contain :keyword:`await`, :keyword:`async for`, and + :keyword:`async with` keywords. These were introduced + by :pep:`492`. + + CPython + The canonical implementation of the Python programming language, as + distributed on `python.org <https://www.python.org>`_. The term "CPython" + is used when necessary to distinguish this implementation from others + such as Jython or IronPython. + + current context + The :term:`context` (:class:`contextvars.Context` object) that is + currently used by :class:`~contextvars.ContextVar` objects to access (get + or set) the values of :term:`context variables <context variable>`. Each + thread has its own current context. Frameworks for executing asynchronous + tasks (see :mod:`asyncio`) associate each task with a context which + becomes the current context whenever the task starts or resumes execution. + + cyclic isolate + A subgroup of one or more objects that reference each other in a reference + cycle, but are not referenced by objects outside the group. The goal of + the :term:`cyclic garbage collector <garbage collection>` is to identify these groups and break the reference + cycles so that the memory can be reclaimed. + + data race + A situation where multiple threads access the same memory location + concurrently, at least one of the accesses is a write, and the threads + do not use any synchronization to control their access. Data races + lead to :term:`non-deterministic` behavior and can cause data corruption. + Proper use of :term:`locks <lock>` and other :term:`synchronization primitives + <synchronization primitive>` prevents data races. Note that data races + can only happen in native code, but that :term:`native code` might be + exposed in a Python API. See also :term:`race condition` and + :term:`thread-safe`. + + deadlock + A situation in which two or more tasks (threads, processes, or coroutines) + wait indefinitely for each other to release resources or complete actions, + preventing any from making progress. For example, if thread A holds lock + 1 and waits for lock 2, while thread B holds lock 2 and waits for lock 1, + both threads will wait indefinitely. In Python this often arises from + acquiring multiple locks in conflicting orders or from circular + join/await dependencies. Deadlocks can be avoided by always acquiring + multiple :term:`locks <lock>` in a consistent order. See also + :term:`lock` and :term:`reentrant`. + + decorator + A function returning another function, usually applied as a function + transformation using the ``@wrapper`` syntax. Common examples for + decorators are :deco:`classmethod` and :deco:`staticmethod`. + + The decorator syntax is merely syntactic sugar, the following two + function definitions are semantically equivalent:: + + def f(arg): + ... + f = staticmethod(f) + + @staticmethod + def f(arg): + ... + + The same concept exists for classes, but is less commonly used there. See + the documentation for :ref:`function definitions <function>` and + :ref:`class definitions <class>` for more about decorators. + + descriptor + Any object which defines the methods :meth:`~object.__get__`, + :meth:`~object.__set__`, or :meth:`~object.__delete__`. + When a class attribute is a descriptor, its special + binding behavior is triggered upon attribute lookup. Normally, using + *a.b* to get, set or delete an attribute looks up the object named *b* in + the class dictionary for *a*, but if *b* is a descriptor, the respective + descriptor method gets called. Understanding descriptors is a key to a + deep understanding of Python because they are the basis for many features + including functions, methods, properties, class methods, static methods, + and reference to super classes. + + For more information about descriptors' methods, see :ref:`descriptors` + or the :ref:`Descriptor How To Guide <descriptorhowto>`. + + dictionary + An associative array, where arbitrary keys are mapped to values. The + keys can be any object with :meth:`~object.__hash__` and + :meth:`~object.__eq__` methods. + Called a hash in Perl. + + dictionary comprehension + A compact way to process all or part of the elements in an iterable and + return a dictionary with the results. ``results = {n: n ** 2 for n in + range(10)}`` generates a dictionary containing key ``n`` mapped to + value ``n ** 2``. See :ref:`comprehensions`. + + dictionary view + The objects returned from :meth:`dict.keys`, :meth:`dict.values`, and + :meth:`dict.items` are called dictionary views. They provide a dynamic + view on the dictionary’s entries, which means that when the dictionary + changes, the view reflects these changes. To force the + dictionary view to become a full list use ``list(dictview)``. See + :ref:`dict-views`. + + docstring + A string literal which appears as the first expression in a class, + function or module. While ignored when the suite is executed, it is + recognized by the compiler and put into the :attr:`~definition.__doc__` attribute + of the enclosing class, function or module. Since it is available via + introspection, it is the canonical place for documentation of the + object. + + duck-typing + A programming style which does not look at an object's type to determine + if it has the right interface; instead, the method or attribute is simply + called or used ("If it looks like a duck and quacks like a duck, it + must be a duck.") By emphasizing interfaces rather than specific types, + well-designed code improves its flexibility by allowing polymorphic + substitution. Duck-typing avoids tests using :func:`type` or + :func:`isinstance`. (Note, however, that duck-typing can be complemented + with :term:`abstract base classes <abstract base class>`.) Instead, it + typically employs :func:`hasattr` tests or :term:`EAFP` programming. + + dunder + An informal short-hand for "double underscore", used when talking about a + :term:`special method`. For example, ``__init__`` is often pronounced + "dunder init". + + EAFP + Easier to ask for forgiveness than permission. This common Python coding + style assumes the existence of valid keys or attributes and catches + exceptions if the assumption proves false. This clean and fast style is + characterized by the presence of many :keyword:`try` and :keyword:`except` + statements. The technique contrasts with the :term:`LBYL` style + common to many other languages such as C. + + evaluate function + A function that can be called to evaluate a lazily evaluated attribute + of an object, such as the value of type aliases created with the :keyword:`type` + statement. + + expression + A piece of syntax which can be evaluated to some value. In other words, + an expression is an accumulation of expression elements like literals, + names, attribute access, operators or function calls which all return a + value. Not all language constructs + are expressions. There are also :term:`statement`\s which cannot be used + as expressions, such as :keyword:`while`. Assignments are also statements, + not expressions. + + extension module + A module written in C or C++, using Python's C API to interact with the + core and with user code. + + f-string + f-strings + String literals prefixed with ``f`` or ``F`` are commonly called + "f-strings" which is short for + :ref:`formatted string literals <f-strings>`. See also :pep:`498`. + + file object + An object exposing a file-oriented API (with methods such as + :meth:`!read` or :meth:`!write`) to an underlying resource. Depending + on the way it was created, a file object can mediate access to a real + on-disk file or to another type of storage or communication device + (for example standard input/output, in-memory buffers, sockets, pipes, + etc.). File objects are also called :dfn:`file-like objects` or + :dfn:`streams`. + + There are actually three categories of file objects: raw + :term:`binary files <binary file>`, buffered + :term:`binary files <binary file>` and :term:`text files <text file>`. + Their interfaces are defined in the :mod:`io` module. The canonical + way to create a file object is by using the :func:`open` function. + + file-like object + A synonym for :term:`file object`. + + filesystem encoding and error handler + Encoding and error handler used by Python to decode bytes from the + operating system and encode Unicode to the operating system. + + The filesystem encoding must guarantee to successfully decode all bytes + below 128. If the file system encoding fails to provide this guarantee, + API functions can raise :exc:`UnicodeError`. + + The :func:`sys.getfilesystemencoding` and + :func:`sys.getfilesystemencodeerrors` functions can be used to get the + filesystem encoding and error handler. + + The :term:`filesystem encoding and error handler` are configured at + Python startup by the :c:func:`PyConfig_Read` function: see + :c:member:`~PyConfig.filesystem_encoding` and + :c:member:`~PyConfig.filesystem_errors` members of :c:type:`PyConfig`. + + See also the :term:`locale encoding`. + + finder + An object that tries to find the :term:`loader` for a module that is + being imported. + + There are two types of finder: :term:`meta path finders + <meta path finder>` for use with :data:`sys.meta_path`, and :term:`path + entry finders <path entry finder>` for use with :data:`sys.path_hooks`. + + See :ref:`finders-and-loaders` and :mod:`importlib` for much more detail. + + floor division + Mathematical division that rounds down to nearest integer. The floor + division operator is ``//``. For example, the expression ``11 // 4`` + evaluates to ``2`` in contrast to the ``2.75`` returned by float true + division. Note that ``(-11) // 4`` is ``-3`` because that is ``-2.75`` + rounded *downward*. See :pep:`238`. + + free threading + A threading model where multiple threads can run Python bytecode + simultaneously within the same interpreter. This is in contrast to + the :term:`global interpreter lock` which allows only one thread to + execute Python bytecode at a time. See :pep:`703`. + + free-threaded build + + A build of :term:`CPython` that supports :term:`free threading`, + configured using the :option:`--disable-gil` option before compilation. + + See :ref:`freethreading-python-howto`. + + free variable + Formally, as defined in the :ref:`language execution model <bind_names>`, a free + variable is any variable used in a namespace which is not a local variable in that + namespace. See :term:`closure variable` for an example. + Pragmatically, due to the name of the :attr:`codeobject.co_freevars` attribute, + the term is also sometimes used as a synonym for :term:`closure variable`. + + function + A series of statements which returns some value to a caller. It can also + be passed zero or more :term:`arguments <argument>` which may be used in + the execution of the body. See also :term:`parameter`, :term:`method`, + and the :ref:`function` section. + + function annotation + An :term:`annotation` of a function parameter or return value. + + Function annotations are usually used for + :term:`type hints <type hint>`: for example, this function is expected to take two + :class:`int` arguments and is also expected to have an :class:`int` + return value:: + + def sum_two_numbers(a: int, b: int) -> int: + return a + b + + Function annotation syntax is explained in section :ref:`function`. + + See :term:`variable annotation` and :pep:`484`, + which describe this functionality. + Also see :ref:`annotations-howto` + for best practices on working with annotations. + + __future__ + A :ref:`future statement <future>`, ``from __future__ import <feature>``, + directs the compiler to compile the current module using syntax or + semantics that will become standard in a future release of Python. + The :mod:`__future__` module documents the possible values of + *feature*. By importing this module and evaluating its variables, + you can see when a new feature was first added to the language and + when it will (or did) become the default:: + + >>> import __future__ + >>> __future__.division + _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192) + + garbage collection + The process of freeing memory when it is not used anymore. Python + performs garbage collection via reference counting and a cyclic garbage + collector that is able to detect and break reference cycles. The + garbage collector can be controlled using the :mod:`gc` module. + + .. index:: single: generator + + generator + Informally used to mean either a :term:`generator function` or a + :term:`generator iterator`, depending on context. The formal terms + :term:`generator function` and :term:`generator iterator` are uncommon + in practice; "generator" alone is almost always sufficient. + + .. index:: single: generator function + + generator function + A function which returns a :term:`generator` object. It looks like a + normal function except that it contains :keyword:`yield` expressions + for producing a series of values usable in a :keyword:`for`\-loop or + that can be retrieved one at a time with the :func:`next` function. + See :ref:`yieldexpr`. + + generator iterator + An object created by a :term:`generator function` or a + :term:`generator expression`. + + Each :keyword:`yield` temporarily suspends processing, remembering the + execution state (including local variables and pending try-statements). + When the *generator iterator* resumes, it picks up where it left off + (in contrast to functions which start fresh on every invocation). + + Generator iterators also implement the :meth:`~generator.send` method + to send a value into the suspended generator, and the + :meth:`~generator.throw` method to raise an exception at the point + where the generator was paused. See :ref:`generator-methods`. + + .. index:: single: generator expression + + generator expression + An :term:`expression` that returns an :term:`iterator`. It looks like a normal expression + followed by a :keyword:`!for` clause defining a loop variable, range, + and an optional :keyword:`!if` clause. The combined expression + generates values for an enclosing function:: + + >>> sum(i*i for i in range(10)) # sum of squares 0, 1, 4, ... 81 + 285 + + generic function + A function composed of multiple functions implementing the same operation + for different types. Which implementation should be used during a call is + determined by the dispatch algorithm. + + See also the :term:`single dispatch` glossary entry, the + :deco:`functools.singledispatch` decorator, and :pep:`443`. + + generic type + A :term:`type` that can be parameterized; typically a + :ref:`container class<sequence-types>` such as :class:`list` or + :class:`dict`. Used for :term:`type hints <type hint>` and + :term:`annotations <annotation>`. + + For more details, see :ref:`generic alias types<types-genericalias>`, + :pep:`483`, :pep:`484`, :pep:`585`, and the :mod:`typing` module. + + GIL + See :term:`global interpreter lock`. + + global interpreter lock + The mechanism used by the :term:`CPython` interpreter to assure that + only one thread executes Python :term:`bytecode` at a time. + This simplifies the CPython implementation by making the object model + (including critical built-in types such as :class:`dict`) implicitly + safe against concurrent access. Locking the entire interpreter + makes it easier for the interpreter to be multi-threaded, at the + expense of much of the parallelism afforded by multi-processor + machines. + + However, some extension modules, either standard or third-party, + are designed so as to release the GIL when doing computationally intensive + tasks such as compression or hashing. Also, the GIL is always released + when doing I/O. + + As of Python 3.13, the GIL can be disabled using the :option:`--disable-gil` + build configuration. After building Python with this option, code must be + run with :option:`-X gil=0 <-X>` or after setting the :envvar:`PYTHON_GIL=0 <PYTHON_GIL>` + environment variable. This feature enables improved performance for + multi-threaded applications and makes it easier to use multi-core CPUs + efficiently. For more details, see :pep:`703`. + + In prior versions of Python's C API, a function might declare that it + requires the GIL to be held in order to use it. This refers to having an + :term:`attached thread state`. + + global state + Data that is accessible throughout a program, such as module-level + variables, class variables, or C static variables in :term:`extension modules + <extension module>`. In multi-threaded programs, global state shared + between threads typically requires synchronization to avoid + :term:`race conditions <race condition>` and + :term:`data races <data race>`. + + hash-based pyc + A bytecode cache file that uses the hash rather than the last-modified + time of the corresponding source file to determine its validity. See + :ref:`pyc-invalidation`. + + hashable + An object is *hashable* if it has a hash value which never changes during + its lifetime (it needs a :meth:`~object.__hash__` method), and can be + compared to other objects (it needs an :meth:`~object.__eq__` method). + Hashable objects which + compare equal must have the same hash value. + + Hashability makes an object usable as a dictionary key and a set member, + because these data structures use the hash value internally. + + Most of Python's immutable built-in objects are hashable; mutable + containers (such as lists or dictionaries) are not; immutable + containers (such as tuples and frozensets) are only hashable if + their elements are hashable. Objects which are + instances of user-defined classes are hashable by default. They all + compare unequal (except with themselves), and their hash value is derived + from their :func:`id`. + + IDLE + An Integrated Development and Learning Environment for Python. + :ref:`idle` is a basic editor and interpreter environment + which ships with the standard distribution of Python. + + immortal + *Immortal objects* are a CPython implementation detail introduced + in :pep:`683`. + + If an object is immortal, its :term:`reference count` is never modified, + and therefore it is never deallocated while the interpreter is running. + For example, :const:`True` and :const:`None` are immortal in CPython. + + Immortal objects can be identified via :func:`sys._is_immortal`, or + via :c:func:`PyUnstable_IsImmortal` in the C API. + + immutable + An object with a fixed value. Immutable objects include numbers, strings and + tuples. Such an object cannot be altered. A new object has to + be created if a different value has to be stored. They play an important + role in places where a constant hash value is needed, for example as a key + in a dictionary. Immutable objects are inherently :term:`thread-safe` + because their state cannot be modified after creation, eliminating concerns + about improperly synchronized :term:`concurrent modification`. + + import path + A list of locations (or :term:`path entries <path entry>`) that are + searched by the :term:`path based finder` for modules to import. During + import, this list of locations usually comes from :data:`sys.path`, but + for subpackages it may also come from the parent package's ``__path__`` + attribute. + + importing + The process by which Python code in one module is made available to + Python code in another module. + + importer + An object that both finds and loads a module; both a + :term:`finder` and :term:`loader` object. + + index + A numeric value that represents the position of an element in + a :term:`sequence`. + + In Python, indexing starts at zero. + For example, ``things[0]`` names the *first* element of ``things``; + ``things[1]`` names the second one. + + In some contexts, Python allows negative indexes for counting from the + end of a sequence, and indexing using :term:`slices <slice>`. + + See also :term:`subscript`. + + interactive + Python has an interactive interpreter which means you can enter + statements and expressions at the interpreter prompt, immediately + execute them and see their results. Just launch ``python`` with no + arguments (possibly by selecting it from your computer's main + menu). It is a very powerful way to test out new ideas or inspect + modules and packages (remember ``help(x)``). For more on interactive + mode, see :ref:`tut-interac`. + + interpreted + Python is an interpreted language, as opposed to a compiled one, + though the distinction can be blurry because of the presence of the + bytecode compiler. This means that source files can be run directly + without explicitly creating an executable which is then run. + Interpreted languages typically have a shorter development/debug cycle + than compiled ones, though their programs generally also run more + slowly. See also :term:`interactive`. + + interpreter shutdown + When asked to shut down, the Python interpreter enters a special phase + where it gradually releases all allocated resources, such as modules + and various critical internal structures. It also makes several calls + to the :term:`garbage collector <garbage collection>`. This can trigger + the execution of code in user-defined destructors or weakref callbacks. + Code executed during the shutdown phase can encounter various + exceptions as the resources it relies on may not function anymore + (common examples are library modules or the warnings machinery). + + The main reason for interpreter shutdown is that the ``__main__`` module + or the script being run has finished executing. + + iterable + An object capable of returning its members one at a time. Examples of + iterables include all sequence types (such as :class:`list`, :class:`str`, + and :class:`tuple`) and some non-sequence types like :class:`dict`, + :term:`file objects <file object>`, and objects of any classes you define + with an :meth:`~object.__iter__` method or with a + :meth:`~object.__getitem__` method + that implements :term:`sequence` semantics. + + Iterables can be + used in a :keyword:`for` loop and in many other places where a sequence is + needed (:func:`zip`, :func:`map`, ...). When an iterable object is passed + as an argument to the built-in function :func:`iter`, it returns an + iterator for the object. This iterator is good for one pass over the set + of values. When using iterables, it is usually not necessary to call + :func:`iter` or deal with iterator objects yourself. The :keyword:`for` + statement does that automatically for you, creating a temporary unnamed + variable to hold the iterator for the duration of the loop. See also + :term:`iterator`, :term:`sequence`, and :term:`generator`. + + iterator + An object representing a stream of data. Repeated calls to the iterator's + :meth:`~iterator.__next__` method (or passing it to the built-in function + :func:`next`) return successive items in the stream. When no more data + are available a :exc:`StopIteration` exception is raised instead. At this + point, the iterator object is exhausted and any further calls to its + :meth:`!__next__` method just raise :exc:`StopIteration` again. Iterators + are required to have an :meth:`~iterator.__iter__` method that returns the iterator + object itself so every iterator is also iterable and may be used in most + places where other iterables are accepted. One notable exception is code + which attempts multiple iteration passes. A container object (such as a + :class:`list`) produces a fresh new iterator each time you pass it to the + :func:`iter` function or use it in a :keyword:`for` loop. Attempting this + with an iterator will just return the same exhausted iterator object used + in the previous iteration pass, making it appear like an empty container. + + More information can be found in :ref:`typeiter`. + + .. impl-detail:: + + CPython does not consistently apply the requirement that an iterator + define :meth:`~iterator.__iter__`. + And also please note that :term:`free-threaded <free threading>` + CPython does not guarantee :term:`thread-safe` behavior of iterator + operations. + + key + A value that identifies an entry in a :term:`mapping`. + See also :term:`subscript`. + + key function + A key function or collation function is a callable that returns a value + used for sorting or ordering. For example, :func:`locale.strxfrm` is + used to produce a sort key that is aware of locale specific sort + conventions. + + A number of tools in Python accept key functions to control how elements + are ordered or grouped. They include :func:`min`, :func:`max`, + :func:`sorted`, :meth:`list.sort`, :func:`heapq.merge`, + :func:`heapq.nsmallest`, :func:`heapq.nlargest`, and + :func:`itertools.groupby`. + + There are several ways to create a key function. For example. the + :meth:`str.casefold` method can serve as a key function for case insensitive + sorts. Alternatively, a key function can be built from a + :keyword:`lambda` expression such as ``lambda r: (r[0], r[2])``. Also, + :func:`operator.attrgetter`, :func:`operator.itemgetter`, and + :func:`operator.methodcaller` are three key function constructors. See the :ref:`Sorting HOW TO + <sortinghowto>` for examples of how to create and use key functions. + + keyword argument + See :term:`argument`. + + lambda + An anonymous inline function consisting of a single :term:`expression` + which is evaluated when the function is called. The syntax to create + a lambda function is ``lambda [parameters]: expression`` + + LBYL + Look before you leap. This coding style explicitly tests for + pre-conditions before making calls or lookups. This style contrasts with + the :term:`EAFP` approach and is characterized by the presence of many + :keyword:`if` statements. + + In a multi-threaded environment, the LBYL approach can risk introducing a + :term:`race condition` between "the looking" and "the leaping". For example, + the code, ``if key in mapping: return mapping[key]`` can fail if another + thread removes *key* from *mapping* after the test, but before the lookup. + This issue can be solved with :term:`locks <lock>` or by using the + :term:`EAFP` approach. See also :term:`thread-safe`. + + lexical analyzer + + Formal name for the *tokenizer*; see :term:`token`. + + list + A built-in Python :term:`sequence`. Despite its name it is more akin + to an array in other languages than to a linked list since access to + elements is *O*\ (1). See :ref:`time-complexity`. + + list comprehension + A compact way to process all or part of the elements in a sequence and + return a list with the results. ``result = ['{:#04x}'.format(x) for x in + range(256) if x % 2 == 0]`` generates a list of strings containing + even hex numbers (0x..) in the range from 0 to 255. The :keyword:`if` + clause is optional. If omitted, all elements in ``range(256)`` are + processed. + + lock + A :term:`synchronization primitive` that allows only one thread at a + time to access a shared resource. A thread must acquire a lock before + accessing the protected resource and release it afterward. If a thread + attempts to acquire a lock that is already held by another thread, it + will block until the lock becomes available. Python's :mod:`threading` + module provides :class:`~threading.Lock` (a basic lock) and + :class:`~threading.RLock` (a :term:`reentrant` lock). Locks are used + to prevent :term:`race conditions <race condition>` and ensure + :term:`thread-safe` access to shared data. Alternative design patterns + to locks exist such as queues, producer/consumer patterns, and + thread-local state. See also :term:`deadlock`, and :term:`reentrant`. + + lock-free + An operation that does not acquire any :term:`lock` and uses atomic CPU + instructions to ensure correctness. Lock-free operations can execute + concurrently without blocking each other and cannot be blocked by + operations that hold locks. In :term:`free-threaded <free threading>` + Python, built-in types like :class:`dict` and :class:`list` provide + lock-free read operations, which means other threads may observe + intermediate states during multi-step modifications even when those + modifications hold the :term:`per-object lock`. + + loader + An object that loads a module. + It must define the :meth:`!exec_module` and :meth:`!create_module` methods + to implement the :class:`~importlib.abc.Loader` interface. + A loader is typically returned by a :term:`finder`. + See also: + + * :ref:`finders-and-loaders` + * :class:`importlib.abc.Loader` + * :pep:`302` + + locale encoding + On Unix, it is the encoding of the LC_CTYPE locale. It can be set with + :func:`locale.setlocale(locale.LC_CTYPE, new_locale) <locale.setlocale>`. + + On Windows, it is the ANSI code page (ex: ``"cp1252"``). + + On Android and VxWorks, Python uses ``"utf-8"`` as the locale encoding. + + :func:`locale.getencoding` can be used to get the locale encoding. + + See also the :term:`filesystem encoding and error handler`. + + magic method + .. index:: pair: magic; method + + An informal synonym for :term:`special method`. + + mapping + A container object that supports arbitrary key lookups and implements the + methods specified in the :class:`collections.abc.Mapping` or + :class:`collections.abc.MutableMapping` + :ref:`abstract base classes <collections-abstract-base-classes>`. Examples + include :class:`dict`, :class:`collections.defaultdict`, + :class:`collections.OrderedDict` and :class:`collections.Counter`. + + meta path finder + A :term:`finder` returned by a search of :data:`sys.meta_path`. Meta path + finders are related to, but different from :term:`path entry finders + <path entry finder>`. + + See :class:`importlib.abc.MetaPathFinder` for the methods that meta path + finders implement. + + metaclass + The class of a class. Class definitions create a class name, a class + dictionary, and a list of base classes. The metaclass is responsible for + taking those three arguments and creating the class. Most object oriented + programming languages provide a default implementation. What makes Python + special is that it is possible to create custom metaclasses. Most users + never need this tool, but when the need arises, metaclasses can provide + powerful, elegant solutions. They have been used for logging attribute + access, adding thread-safety, tracking object creation, implementing + singletons, and many other tasks. + + More information can be found in :ref:`metaclasses`. + + method + A function which is defined inside a class body. If called as an attribute + of an instance of that class, the method will get the instance object as + its first :term:`argument` (which is usually called ``self``). + See :term:`function` and :term:`nested scope`. + + method resolution order + Method Resolution Order is the order in which base classes are searched + for a member during lookup. See :ref:`python_2.3_mro` for details of the + algorithm used by the Python interpreter since the 2.3 release. + + module + An object that serves as an organizational unit of Python code. Modules + have a namespace containing arbitrary Python objects. Modules are loaded + into Python by the process of :term:`importing`. + + See also :term:`package`. + + module spec + A namespace containing the import-related information used to load a + module. An instance of :class:`importlib.machinery.ModuleSpec`. + + See also :ref:`module-specs`. + + MRO + See :term:`method resolution order`. + + mutable + An :term:`object` with state that is allowed to change during the course + of the program. In multi-threaded programs, mutable objects that are + shared between threads require careful synchronization to avoid + :term:`race conditions <race condition>`. See also :term:`immutable`, + :term:`thread-safe`, and :term:`concurrent modification`. + + named tuple + The term "named tuple" applies to any type or class that inherits from + tuple and whose indexable elements are also accessible using named + attributes. The type or class may have other features as well. + + Several built-in types are named tuples, including the values returned + by :func:`time.localtime` and :func:`os.stat`. Another example is + :data:`sys.float_info`:: + + >>> sys.float_info[1] # indexed access + 1024 + >>> sys.float_info.max_exp # named field access + 1024 + >>> isinstance(sys.float_info, tuple) # kind of tuple + True + + Some named tuples are built-in types (such as the above examples). + Alternatively, a named tuple can be created from a regular class + definition that inherits from :class:`tuple` and that defines named + fields. Such a class can be written by hand, or it can be created by + inheriting :class:`typing.NamedTuple`, or with the factory function + :func:`collections.namedtuple`. The latter techniques also add some + extra methods that may not be found in hand-written or built-in named + tuples. + + namespace + The place where a variable is stored. Namespaces are implemented as + dictionaries. There are the local, global and built-in namespaces as well + as nested namespaces in objects (in methods). Namespaces support + modularity by preventing naming conflicts. For instance, the functions + :func:`builtins.open <.open>` and :func:`os.open` are distinguished by + their namespaces. Namespaces also aid readability and maintainability by + making it clear which module implements a function. For instance, writing + :func:`random.seed` or :func:`itertools.islice` makes it clear that those + functions are implemented by the :mod:`random` and :mod:`itertools` + modules, respectively. + + namespace package + A :term:`package` which serves only as a container for subpackages. + Namespace packages may have no physical representation, + and specifically are not like a :term:`regular package` because they + have no ``__init__.py`` file. + + Namespace packages allow several individually installable packages to have a common parent package. + Otherwise, it is recommended to use a :term:`regular package`. + + For more information, see :pep:`420` and :ref:`reference-namespace-package`. + + See also :term:`module`. + + native code + Code that is compiled to machine instructions and runs directly on the + processor, as opposed to code that is interpreted or runs in a virtual + machine. In the context of Python, native code typically refers to + C, C++, Rust or Fortran code in :term:`extension modules <extension module>` + that can be called from Python. See also :term:`extension module`. + + nested scope + The ability to refer to a variable in an enclosing definition. For + instance, a function defined inside another function can refer to + variables in the outer function. Note that nested scopes by default work + only for reference and not for assignment. Local variables both read and + write in the innermost scope. Likewise, global variables read and write + to the global namespace. The :keyword:`nonlocal` allows writing to outer + scopes. + + new-style class + Old name for the flavor of classes now used for all class objects. In + earlier Python versions, only new-style classes could use Python's newer, + versatile features like :attr:`~object.__slots__`, descriptors, + properties, :meth:`~object.__getattribute__`, class methods, and static + methods. + + non-deterministic + Behavior where the outcome of a program can vary between executions with + the same inputs. In multi-threaded programs, non-deterministic behavior + often results from :term:`race conditions <race condition>` where the + relative timing or interleaving of threads affects the result. + Proper synchronization using :term:`locks <lock>` and other + :term:`synchronization primitives <synchronization primitive>` helps + ensure deterministic behavior. + + object + Any data with state (attributes or value) and defined behavior + (methods). Also the ultimate base class of any :term:`new-style + class`. + + optimized scope + A scope where target local variable names are reliably known to the + compiler when the code is compiled, allowing optimization of read and + write access to these names. The local namespaces for functions, + generators, coroutines, comprehensions, and generator expressions are + optimized in this fashion. Note: most interpreter optimizations are + applied to all scopes, only those relying on a known set of local + and nonlocal variable names are restricted to optimized scopes. + + optional module + An :term:`extension module` that is part of the :term:`standard library`, + but may be absent in some builds of :term:`CPython`, + usually due to missing third-party libraries or because the module + is not available for a given platform. + + See :ref:`optional-module-requirements` for a list of optional modules + that require third-party libraries. + + package + A Python :term:`module` which can contain submodules or recursively, + subpackages. Technically, a package is a Python module with a + ``__path__`` attribute. + + See also :term:`regular package` and :term:`namespace package`. + + parallelism + Executing multiple operations at the same time (e.g. on multiple CPU + cores). In Python builds with the + :term:`global interpreter lock (GIL) <global interpreter lock>`, only one + thread runs Python bytecode at a time, so taking advantage of multiple + CPU cores typically involves multiple processes + (e.g. :mod:`multiprocessing`) or native extensions that release the GIL. + In :term:`free-threaded <free threading>` Python, multiple Python threads + can run Python code simultaneously on different cores. + + parameter + A named entity in a :term:`function` (or method) definition that + specifies an :term:`argument` (or in some cases, arguments) that the + function can accept. There are five kinds of parameter: + + * :dfn:`positional-or-keyword`: specifies an argument that can be passed + either :term:`positionally <argument>` or as a :term:`keyword argument + <argument>`. This is the default kind of parameter, for example *foo* + and *bar* in the following:: + + def func(foo, bar=None): ... + + .. _positional-only_parameter: + + * :dfn:`positional-only`: specifies an argument that can be supplied only + by position. Positional-only parameters can be defined by including a + ``/`` character in the parameter list of the function definition after + them, for example *posonly1* and *posonly2* in the following:: + + def func(posonly1, posonly2, /, positional_or_keyword): ... + + .. _keyword-only_parameter: + + * :dfn:`keyword-only`: specifies an argument that can be supplied only + by keyword. Keyword-only parameters can be defined by including a + single var-positional parameter or bare ``*`` in the parameter list + of the function definition before them, for example *kw_only1* and + *kw_only2* in the following:: + + def func(arg, *, kw_only1, kw_only2): ... + + * :dfn:`var-positional`: specifies that an arbitrary sequence of + positional arguments can be provided (in addition to any positional + arguments already accepted by other parameters). Such a parameter can + be defined by prepending the parameter name with ``*``, for example + *args* in the following:: + + def func(*args, **kwargs): ... + + * :dfn:`var-keyword`: specifies that arbitrarily many keyword arguments + can be provided (in addition to any keyword arguments already accepted + by other parameters). Such a parameter can be defined by prepending + the parameter name with ``**``, for example *kwargs* in the example + above. + + Parameters can specify both optional and required arguments, as well as + default values for some optional arguments. + + See also the :term:`argument` glossary entry, the FAQ question on + :ref:`the difference between arguments and parameters + <faq-argument-vs-parameter>`, the :class:`inspect.Parameter` class, the + :ref:`function` section, and :pep:`362`. + + per-object lock + A :term:`lock` associated with an individual object instance rather than + a global lock shared across all objects. In :term:`free-threaded + <free threading>` Python, built-in types like :class:`dict` and + :class:`list` use per-object locks to allow concurrent operations on + different objects while serializing operations on the same object. + Operations that hold the per-object lock prevent other locking operations + on the same object from proceeding, but do not block :term:`lock-free` + operations. + + path entry + A single location on the :term:`import path` which the :term:`path + based finder` consults to find modules for importing. + + path entry finder + A :term:`finder` returned by a callable on :data:`sys.path_hooks` + (i.e. a :term:`path entry hook`) which knows how to locate modules given + a :term:`path entry`. + + See :class:`importlib.abc.PathEntryFinder` for the methods that path entry + finders implement. + + path entry hook + A callable on the :data:`sys.path_hooks` list which returns a :term:`path + entry finder` if it knows how to find modules on a specific :term:`path + entry`. + + path based finder + One of the default :term:`meta path finders <meta path finder>` which + searches an :term:`import path` for modules. + + path-like object + An object representing a file system path. A path-like object is either + a :class:`str` or :class:`bytes` object representing a path, or an object + implementing the :class:`os.PathLike` protocol. An object that supports + the :class:`os.PathLike` protocol can be converted to a :class:`str` or + :class:`bytes` file system path by calling the :func:`os.fspath` function; + :func:`os.fsdecode` and :func:`os.fsencode` can be used to guarantee a + :class:`str` or :class:`bytes` result instead, respectively. Introduced + by :pep:`519`. + + PEP + Python Enhancement Proposal. A PEP is a design document + providing information to the Python community, or describing a new + feature for Python or its processes or environment. PEPs should + provide a concise technical specification and a rationale for proposed + features. + + PEPs are intended to be the primary mechanisms for proposing major new + features, for collecting community input on an issue, and for documenting + the design decisions that have gone into Python. The PEP author is + responsible for building consensus within the community and documenting + dissenting opinions. + + See :pep:`1`. + + portion + A set of files in a single directory (possibly stored in a zip file) + that contribute to a namespace package, as defined in :pep:`420`. + + positional argument + See :term:`argument`. + + provisional API + A provisional API is one which has been deliberately excluded from + the standard library's backwards compatibility guarantees. While major + changes to such interfaces are not expected, as long as they are marked + provisional, backwards incompatible changes (up to and including removal + of the interface) may occur if deemed necessary by core developers. Such + changes will not be made gratuitously -- they will occur only if serious + fundamental flaws are uncovered that were missed prior to the inclusion + of the API. + + Even for provisional APIs, backwards incompatible changes are seen as + a "solution of last resort" - every attempt will still be made to find + a backwards compatible resolution to any identified problems. + + This process allows the standard library to continue to evolve over + time, without locking in problematic design errors for extended periods + of time. See :pep:`411` for more details. + + provisional package + See :term:`provisional API`. + + Python 3000 + Nickname for the Python 3.x release line (coined long ago when the + release of version 3 was something in the distant future.) This is also + abbreviated "Py3k". + + Pythonic + An idea or piece of code which closely follows the most common idioms + of the Python language, rather than implementing code using concepts + common to other languages. For example, a common idiom in Python is + to loop over all elements of an iterable using a :keyword:`for` + statement. Many other languages don't have this type of construct, so + people unfamiliar with Python sometimes use a numerical counter instead:: + + for i in range(len(food)): + print(food[i]) + + As opposed to the cleaner, Pythonic method:: + + for piece in food: + print(piece) + + qualified name + A dotted name showing the "path" from a module's global scope to a + class, function or method defined in that module, as defined in + :pep:`3155`. For top-level functions and classes, the qualified name + is the same as the object's name:: + + >>> class C: + ... class D: + ... def meth(self): + ... pass + ... + >>> C.__qualname__ + 'C' + >>> C.D.__qualname__ + 'C.D' + >>> C.D.meth.__qualname__ + 'C.D.meth' + + When used to refer to modules, the *fully qualified name* means the + entire dotted path to the module, including any parent packages, + e.g. ``email.mime.text``:: + + >>> import email.mime.text + >>> email.mime.text.__name__ + 'email.mime.text' + + race condition + A condition of a program where the behavior + depends on the relative timing or ordering of events, particularly in + multi-threaded programs. Race conditions can lead to + :term:`non-deterministic` behavior and bugs that are difficult to + reproduce. A :term:`data race` is a specific type of race condition + involving unsynchronized access to shared memory. The :term:`LBYL` + coding style is particularly susceptible to race conditions in + multi-threaded code. Using :term:`locks <lock>` and other + :term:`synchronization primitives <synchronization primitive>` + helps prevent race conditions. + + reference count + The number of references to an object. When the reference count of an + object drops to zero, it is deallocated. Some objects are + :term:`immortal` and have reference counts that are never modified, and + therefore the objects are never deallocated. Reference counting is + generally not visible to Python code, but it is a key element of the + :term:`CPython` implementation. Programmers can call the + :func:`sys.getrefcount` function to return the + reference count for a particular object. + + In :term:`CPython`, reference counts are not considered to be stable + or well-defined values; the number of references to an object, and how + that number is affected by Python code, may be different between + versions. + + regular package + A traditional :term:`package`, such as a directory containing an + ``__init__.py`` file. + + See also :term:`namespace package`. + + reentrant + A property of a function or :term:`lock` that allows it to be called or + acquired multiple times by the same thread without causing errors or a + :term:`deadlock`. + + For functions, reentrancy means the function can be safely called again + before a previous invocation has completed, which is important when + functions may be called recursively or from signal handlers. Thread-unsafe + functions may be :term:`non-deterministic` if they're called reentrantly in a + multithreaded program. + + For locks, Python's :class:`threading.RLock` (reentrant lock) is + reentrant, meaning a thread that already holds the lock can acquire it + again without blocking. In contrast, :class:`threading.Lock` is not + reentrant - attempting to acquire it twice from the same thread will cause + a deadlock. + + See also :term:`lock` and :term:`deadlock`. + + REPL + An acronym for the "read–eval–print loop", another name for the + :term:`interactive` interpreter shell. + + __slots__ + A declaration inside a class that saves memory by pre-declaring space for + instance attributes and eliminating instance dictionaries. Though + popular, the technique is somewhat tricky to get right and is best + reserved for rare cases where there are large numbers of instances in a + memory-critical application. + + sequence + An :term:`iterable` which supports efficient element access using integer + indices via the :meth:`~object.__getitem__` special method and defines a + :meth:`~object.__len__` method that returns the length of the sequence. + Some built-in sequence types are :class:`list`, :class:`str`, + :class:`tuple`, and :class:`bytes`. Note that :class:`dict` also + supports :meth:`~object.__getitem__` and :meth:`!__len__`, but is considered a + mapping rather than a sequence because the lookups use arbitrary + :term:`hashable` keys rather than integers. + + The :class:`collections.abc.Sequence` abstract base class + defines a much richer interface that goes beyond just + :meth:`~object.__getitem__` and :meth:`~object.__len__`, adding + :meth:`~sequence.count`, :meth:`~sequence.index`, + :meth:`~object.__contains__`, and :meth:`~object.__reversed__`. + Types that implement this expanded + interface can be registered explicitly using + :func:`~abc.ABCMeta.register`. For more documentation on sequence + methods generally, see + :ref:`Common Sequence Operations <typesseq-common>`. + + set comprehension + A compact way to process all or part of the elements in an iterable and + return a set with the results. ``results = {c for c in 'abracadabra' if + c not in 'abc'}`` generates the set of strings ``{'r', 'd'}``. See + :ref:`comprehensions`. + + single dispatch + A form of :term:`generic function` dispatch where the implementation is + chosen based on the type of a single argument. + + slice + An object of type :class:`slice`, used to describe a portion of + a :term:`sequence`. + A slice object is created when using the :ref:`slicing <slicings>` form + of :ref:`subscript notation <subscriptions>`, with colons inside square + brackets, such as in ``variable_name[1:3:5]``. + + soft deprecated + A soft deprecated API should not be used in new code, + but it is safe for already existing code to use it. + The API remains documented and tested, but will not be enhanced further. + + Soft deprecation, unlike normal deprecation, does not plan on removing the API + and will not emit warnings. + + See `PEP 387: Soft Deprecation + <https://peps.python.org/pep-0387/#soft-deprecation>`_. + + special method + .. index:: pair: special; method + + A method that is called implicitly by Python to execute a certain + operation on a type, such as addition. Such methods have names starting + and ending with double underscores. Special methods are documented in + :ref:`specialnames`. + + standard library + The collection of :term:`packages <package>`, :term:`modules <module>` + and :term:`extension modules <extension module>` distributed as a part + of the official Python interpreter package. The exact membership of the + collection may vary based on platform, available system libraries, or + other criteria. Documentation can be found at :ref:`library-index`. + + See also :data:`sys.stdlib_module_names` for a list of all possible + standard library module names. + + statement + A statement is part of a suite (a "block" of code). A statement is either + an :term:`expression` or one of several constructs with a keyword, such + as :keyword:`if`, :keyword:`while` or :keyword:`for`. + + static type checker + An external tool that reads Python code and analyzes it, looking for + issues such as incorrect types. See also :term:`type hints <type hint>` + and the :mod:`typing` module. + + stdlib + An abbreviation of :term:`standard library`. + + steal + In Python's C API, "*stealing*" an argument means that ownership of the + argument is transferred to the called function. + The caller must not use that reference after the call. + Generally, functions that "steal" an argument do so even if they fail. + + See :ref:`api-refcountdetails` for a full explanation. + + strong reference + In Python's C API, a strong reference is a reference to an object + which is owned by the code holding the reference. The strong + reference is taken by calling :c:func:`Py_INCREF` when the + reference is created and released with :c:func:`Py_DECREF` + when the reference is deleted. + + The :c:func:`Py_NewRef` function can be used to create a strong reference + to an object. Usually, the :c:func:`Py_DECREF` function must be called on + the strong reference before exiting the scope of the strong reference, to + avoid leaking one reference. + + See also :term:`borrowed reference`. + + subscript + The expression in square brackets of a + :ref:`subscription expression <subscriptions>`, for example, + the ``3`` in ``items[3]``. + Usually used to select an element of a container. + Also called a :term:`key` when subscripting a :term:`mapping`, + or an :term:`index` when subscripting a :term:`sequence`. + + synchronization primitive + A basic building block for coordinating (synchronizing) the execution of + multiple threads to ensure :term:`thread-safe` access to shared resources. + Python's :mod:`threading` module provides several synchronization primitives + including :class:`~threading.Lock`, :class:`~threading.RLock`, + :class:`~threading.Semaphore`, :class:`~threading.Condition`, + :class:`~threading.Event`, and :class:`~threading.Barrier`. Additionally, + the :mod:`queue` module provides multi-producer, multi-consumer queues + that are especially useful in multithreaded programs. These + primitives help prevent :term:`race conditions <race condition>` and + coordinate thread execution. See also :term:`lock`. + + t-string + t-strings + String literals prefixed with ``t`` or ``T`` are commonly called + "t-strings" which is short for + :ref:`template string literals <t-strings>`. + + text encoding + A string in Python is a sequence of Unicode code points (in range + ``U+0000``--``U+10FFFF``). To store or transfer a string, it needs to be + serialized as a sequence of bytes. + + Serializing a string into a sequence of bytes is known as "encoding", and + recreating the string from the sequence of bytes is known as "decoding". + + There are a variety of different text serialization + :ref:`codecs <standard-encodings>`, which are collectively referred to as + "text encodings". + + text file + A :term:`file object` able to read and write :class:`str` objects. + Often, a text file actually accesses a byte-oriented datastream + and handles the :term:`text encoding` automatically. + Examples of text files are files opened in text mode (``'r'`` or ``'w'``), + :data:`sys.stdin`, :data:`sys.stdout`, and instances of + :class:`io.StringIO`. + + See also :term:`binary file` for a file object able to read and write + :term:`bytes-like objects <bytes-like object>`. + + thread state + + The information used by the :term:`CPython` runtime to run in an OS thread. + For example, this includes the current exception, if any, and the + state of the bytecode interpreter. + + Each thread state is bound to a single OS thread, but threads may have + many thread states available. At most, one of them may be + :term:`attached <attached thread state>` at once. + + An :term:`attached thread state` is required to call most + of Python's C API, unless a function explicitly documents otherwise. + The bytecode interpreter only runs under an attached thread state. + + Each thread state belongs to a single interpreter, but each interpreter + may have many thread states, including multiple for the same OS thread. + Thread states from multiple interpreters may be bound to the same + thread, but only one can be :term:`attached <attached thread state>` in + that thread at any given moment. + + See :ref:`Thread State and the Global Interpreter Lock <threads>` for more + information. + + thread-safe + A module, function, or class that behaves correctly when used by multiple + threads concurrently. Thread-safe code uses appropriate + :term:`synchronization primitives <synchronization primitive>` like + :term:`locks <lock>` to protect shared mutable state, or is designed + to avoid shared mutable state entirely. In the + :term:`free-threaded <free threading>` build, built-in types like + :class:`dict`, :class:`list`, and :class:`set` use internal locking + to make many operations thread-safe, although thread safety is not + necessarily guaranteed. Code that is not thread-safe may experience + :term:`race conditions <race condition>` and :term:`data races <data race>` + when used in multi-threaded programs. + + token + + A small unit of source code, generated by the + :ref:`lexical analyzer <lexical>` (also called the *tokenizer*). + Names, numbers, strings, operators, + newlines and similar are represented by tokens. + + The :mod:`tokenize` module exposes Python's lexical analyzer. + The :mod:`token` module contains information on the various types + of tokens. + + triple-quoted string + A string which is bound by three instances of either a quotation mark + (") or an apostrophe ('). While they don't provide any functionality + not available with single-quoted strings, they are useful for a number + of reasons. They allow you to include unescaped single and double + quotes within a string and they can span multiple lines without the + use of the continuation character, making them especially useful when + writing docstrings. + + type + The type of a Python object determines what kind of object it is; every + object has a type. An object's type is accessible as its + :attr:`~object.__class__` attribute or can be retrieved with + ``type(obj)``. + + type alias + A synonym for a type, created by assigning the type to an identifier. + + Type aliases are useful for simplifying :term:`type hints <type hint>`. + For example:: + + def remove_gray_shades( + colors: list[tuple[int, int, int]]) -> list[tuple[int, int, int]]: + pass + + could be made more readable like this:: + + Color = tuple[int, int, int] + + def remove_gray_shades(colors: list[Color]) -> list[Color]: + pass + + See :mod:`typing` and :pep:`484`, which describe this functionality. + + type hint + An :term:`annotation` that specifies the expected type for a variable, a class + attribute, or a function parameter or return value. + + Type hints are optional and are not enforced by Python but + they are useful to :term:`static type checkers <static type checker>`. + They can also aid IDEs with code completion and refactoring. + + Type hints of global variables, class attributes, and functions, + but not local variables, can be accessed using + :func:`typing.get_type_hints`. + + See :mod:`typing` and :pep:`484`, which describe this functionality. + + universal newlines + A manner of interpreting text streams in which all of the following are + recognized as ending a line: the Unix end-of-line convention ``'\n'``, + the Windows convention ``'\r\n'``, and the old Macintosh convention + ``'\r'``. See :pep:`278` and :pep:`3116`, as well as + :func:`bytes.splitlines` for an additional use. + + variable annotation + An :term:`annotation` of a variable or a class attribute. + + When annotating a variable or a class attribute, assignment is optional:: + + class C: + field: 'annotation' + + Variable annotations are usually used for + :term:`type hints <type hint>`: for example this variable is expected to take + :class:`int` values:: + + count: int = 0 + + Variable annotation syntax is explained in section :ref:`annassign`. + + See :term:`function annotation`, :pep:`484` + and :pep:`526`, which describe this functionality. + Also see :ref:`annotations-howto` + for best practices on working with annotations. + + virtual environment + A cooperatively isolated runtime environment that allows Python users + and applications to install and upgrade Python distribution packages + without interfering with the behaviour of other Python applications + running on the same system. + + See also :mod:`venv`. + + virtual machine + A computer defined entirely in software. Python's virtual machine + executes the :term:`bytecode` emitted by the bytecode compiler. + + walrus operator + A light-hearted way to refer to the :ref:`assignment expression + <assignment-expressions>` operator ``:=`` because it looks a bit like a + walrus if you turn your head. + + Zen of Python + Listing of Python design principles and philosophies that are helpful in + understanding and using the language. The listing can be found by typing + "``import this``" at the interactive prompt. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/improve-page-nojs.rst b/stdlib/kvlang/reference/python/cpython/Doc/improve-page-nojs.rst new file mode 100644 index 00000000..91b3a88b --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/improve-page-nojs.rst @@ -0,0 +1,29 @@ +:orphan: + +**************************** +Improve a documentation page +**************************** + +.. This is the no-javascript version of this page. The one most people + will see (with JavaScript enabled) is improve-page.rst. If you edit + this page, please also edit that one, and vice versa. + +.. only:: html and not epub + +We are always interested to hear ideas about improvements to the documentation. + +.. only:: translation + + If the bug or suggested improvement concerns the translation of this + documentation, open an issue or edit the page in + `translation's repository <TRANSLATION_REPO_>`_ instead. + +You have a few ways to ask questions or suggest changes: + +- You can start a discussion about the page on the Python discussion forum. + This link will start a topic in the Documentation category: + `New Documentation topic <https://discuss.python.org/new-topic?category=documentation>`_. + +- You can open an issue on the Python GitHub issue tracker. This link will + create a new issue with the "docs" label: + `New docs issue <https://github.com/python/cpython/issues/new?template=documentation.yml>`_. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/improve-page.rst b/stdlib/kvlang/reference/python/cpython/Doc/improve-page.rst new file mode 100644 index 00000000..dc89fcb2 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/improve-page.rst @@ -0,0 +1,65 @@ +:orphan: + +**************************** +Improve a documentation page +**************************** + +.. This is the JavaScript-enabled version of this page. Another version + (for those with JavaScript disabled) is improve-page-nojs.rst. If you + edit this page, please also edit that one, and vice versa. + +.. only:: html and not epub + + .. raw:: html + + <script> + function applyReplacements(text, params) { + return text + .replace(/PAGETITLE/g, params.get('pagetitle')) + .replace(/PAGEURL/g, params.get('pageurl')) + .replace(/PAGESOURCE/g, params.get('pagesource')); + } + + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search); + const walker = document.createTreeWalker( + document.body, + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, + null + ); + + while (walker.nextNode()) { + const node = walker.currentNode; + + if (node.nodeType === Node.TEXT_NODE) { + node.textContent = applyReplacements(node.textContent, params) + } else if (node.nodeName === 'A' && node.href) { + node.setAttribute('href', applyReplacements(node.getAttribute('href'), params)); + } + } + }); + </script> + +We are always interested to hear ideas about improvements to the documentation. + +You were reading "PAGETITLE" at `<PAGEURL>`_. The source for that page is on +`GitHub <https://github.com/python/cpython/blob/main/Doc/PAGESOURCE?plain=1>`_. + +.. only:: translation + + If the bug or suggested improvement concerns the translation of this + documentation, open an issue or edit the page in + `translation's repository <TRANSLATION_REPO_>`_ instead. + +You have a few ways to ask questions or suggest changes: + +- You can start a discussion about the page on the Python discussion forum. + This link will start a pre-populated topic: + `Question about page "PAGETITLE" <https://discuss.python.org/new-topic?category=documentation&title=Question+about+page+%22PAGETITLE%22&body=About+the+page+at+PAGEURL%3A>`_. + +- You can open an issue on the Python GitHub issue tracker. This link will + create a new pre-populated issue: + `Docs: problem with page "PAGETITLE" <https://github.com/python/cpython/issues/new?template=documentation.yml&title=Docs%3A+problem+with+page+%22PAGETITLE%22&description=The+page+at+PAGEURL+has+a+problem%3A>`_. + +- You can `edit the page on GitHub <https://github.com/python/cpython/blob/main/Doc/PAGESOURCE?plain=1>`_ + to open a pull request and begin the contribution process. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/license.rst b/stdlib/kvlang/reference/python/cpython/Doc/license.rst new file mode 100644 index 00000000..47c4fa9d --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/license.rst @@ -0,0 +1,1267 @@ +.. highlight:: none + +.. _history-and-license: + +******************* +History and License +******************* + + +History of the software +======================= + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands as a +successor of a language called ABC. Guido remains Python's principal author, +although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for National +Research Initiatives (CNRI, see https://www.cnri.reston.va.us) in Reston, +Virginia where he released several versions of the software. + +In May 2000, Guido and the Python core development team moved to BeOpen.com to +form the BeOpen PythonLabs team. In October of the same year, the PythonLabs +team moved to Digital Creations, which became +Zope Corporation. In 2001, the Python Software Foundation (PSF, see +https://www.python.org/psf/) was formed, a non-profit organization created +specifically to own Python-related Intellectual Property. Zope Corporation was a +sponsoring member of the PSF. + +All Python releases are Open Source (see https://opensource.org for the Open +Source Definition). Historically, most, but not all, Python releases have also +been GPL-compatible; the table below summarizes the various releases. + ++----------------+--------------+------------+------------+---------------------+ +| Release | Derived from | Year | Owner | GPL-compatible? (1) | ++================+==============+============+============+=====================+ +| 0.9.0 thru 1.2 | n/a | 1991-1995 | CWI | yes | ++----------------+--------------+------------+------------+---------------------+ +| 1.3 thru 1.5.2 | 1.2 | 1995-1999 | CNRI | yes | ++----------------+--------------+------------+------------+---------------------+ +| 1.6 | 1.5.2 | 2000 | CNRI | no | ++----------------+--------------+------------+------------+---------------------+ +| 2.0 | 1.6 | 2000 | BeOpen.com | no | ++----------------+--------------+------------+------------+---------------------+ +| 1.6.1 | 1.6 | 2001 | CNRI | yes (2) | ++----------------+--------------+------------+------------+---------------------+ +| 2.1 | 2.0+1.6.1 | 2001 | PSF | no | ++----------------+--------------+------------+------------+---------------------+ +| 2.0.1 | 2.0+1.6.1 | 2001 | PSF | yes | ++----------------+--------------+------------+------------+---------------------+ +| 2.1.1 | 2.1+2.0.1 | 2001 | PSF | yes | ++----------------+--------------+------------+------------+---------------------+ +| 2.1.2 | 2.1.1 | 2002 | PSF | yes | ++----------------+--------------+------------+------------+---------------------+ +| 2.1.3 | 2.1.2 | 2002 | PSF | yes | ++----------------+--------------+------------+------------+---------------------+ +| 2.2 and above | 2.1.1 | 2001-now | PSF | yes | ++----------------+--------------+------------+------------+---------------------+ + +.. note:: + + (1) GPL-compatible doesn't mean that we're distributing Python under the GPL. + All Python licenses, unlike the GPL, let you distribute a modified version + without making your changes open source. The GPL-compatible licenses make + it possible to combine Python with other software that is released under + the GPL; the others don't. + + (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, because its license + has a choice of law clause. According to CNRI, however, Stallman's lawyer has + told CNRI's lawyer that 1.6.1 is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's direction to +make these releases possible. + + +Terms and conditions for accessing or otherwise using Python +============================================================ + +Python software and documentation are licensed under the +Python Software Foundation License Version 2. + +Starting with Python 3.8.6, examples, recipes, and other code in +the documentation are dual licensed under the PSF License Version 2 +and the :ref:`Zero-Clause BSD license <BSD0>`. + +Some software incorporated into Python is under different licenses. +The licenses are listed with code falling under that license. +See :ref:`OtherLicenses` for an incomplete list of these licenses. + + +.. _PSF-license: + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +.. parsed-literal:: + + 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and + the Individual or Organization ("Licensee") accessing and otherwise using this + software ("Python") in source or binary form and its associated documentation. + + 2. Subject to the terms and conditions of this License Agreement, PSF hereby + grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, + analyze, test, perform and/or display publicly, prepare derivative works, + distribute, and otherwise use Python alone or in any derivative + version, provided, however, that PSF's License Agreement and PSF's notice of + copyright, i.e., "Copyright © 2001 Python Software Foundation; All Rights + Reserved" are retained in Python alone or in any derivative version + prepared by Licensee. + + 3. In the event Licensee prepares a derivative work that is based on or + incorporates Python or any part thereof, and wants to make the + derivative work available to others as provided herein, then Licensee hereby + agrees to include in any such work a brief summary of the changes made to Python. + + 4. PSF is making Python available to Licensee on an "AS IS" basis. + PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF + EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR + WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE + USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. + + 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON + FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF + MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE + THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + + 6. This License Agreement will automatically terminate upon a material breach of + its terms and conditions. + + 7. Nothing in this License Agreement shall be deemed to create any relationship + of agency, partnership, or joint venture between PSF and Licensee. This License + Agreement does not grant permission to use PSF trademarks or trade name in a + trademark sense to endorse or promote products or services of Licensee, or any + third party. + + 8. By copying, installing or otherwise using Python, Licensee agrees + to be bound by the terms and conditions of this License Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +.. parsed-literal:: + + 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at + 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization + ("Licensee") accessing and otherwise using this software in source or binary + form and its associated documentation ("the Software"). + + 2. Subject to the terms and conditions of this BeOpen Python License Agreement, + BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license + to reproduce, analyze, test, perform and/or display publicly, prepare derivative + works, distribute, and otherwise use the Software alone or in any derivative + version, provided, however, that the BeOpen Python License is retained in the + Software, alone or in any derivative version prepared by Licensee. + + 3. BeOpen is making the Software available to Licensee on an "AS IS" basis. + BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF + EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR + WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE + USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. + + 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR + ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, + MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF + ADVISED OF THE POSSIBILITY THEREOF. + + 5. This License Agreement will automatically terminate upon a material breach of + its terms and conditions. + + 6. This License Agreement shall be governed by and interpreted in all respects + by the law of the State of California, excluding conflict of law provisions. + Nothing in this License Agreement shall be deemed to create any relationship of + agency, partnership, or joint venture between BeOpen and Licensee. This License + Agreement does not grant permission to use BeOpen trademarks or trade names in a + trademark sense to endorse or promote products or services of Licensee, or any + third party. As an exception, the "BeOpen Python" logos available at + http://www.pythonlabs.com/logos.html may be used according to the permissions + granted on that web page. + + 7. By copying, installing or otherwise using the software, Licensee agrees to be + bound by the terms and conditions of this License Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +.. parsed-literal:: + + 1. This LICENSE AGREEMENT is between the Corporation for National Research + Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 + ("CNRI"), and the Individual or Organization ("Licensee") accessing and + otherwise using Python 1.6.1 software in source or binary form and its + associated documentation. + + 2. Subject to the terms and conditions of this License Agreement, CNRI hereby + grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, + analyze, test, perform and/or display publicly, prepare derivative works, + distribute, and otherwise use Python 1.6.1 alone or in any derivative version, + provided, however, that CNRI's License Agreement and CNRI's notice of copyright, + i.e., "Copyright © 1995-2001 Corporation for National Research Initiatives; All + Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version + prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, + Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 + is made available subject to the terms and conditions in CNRI's License + Agreement. This Agreement together with Python 1.6.1 may be located on the + internet using the following unique, persistent identifier (known as a handle): + 1895.22/1013. This Agreement may also be obtained from a proxy server on the + internet using the following URL: http://hdl.handle.net/1895.22/1013". + + 3. In the event Licensee prepares a derivative work that is based on or + incorporates Python 1.6.1 or any part thereof, and wants to make the derivative + work available to others as provided herein, then Licensee hereby agrees to + include in any such work a brief summary of the changes made to Python 1.6.1. + + 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI + MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, + BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY + OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF + PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. + + 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR + ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF + MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE + THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + + 6. This License Agreement will automatically terminate upon a material breach of + its terms and conditions. + + 7. This License Agreement shall be governed by the federal intellectual property + law of the United States, including without limitation the federal copyright + law, and, to the extent such U.S. federal law does not apply, by the law of the + Commonwealth of Virginia, excluding Virginia's conflict of law provisions. + Notwithstanding the foregoing, with regard to derivative works based on Python + 1.6.1 that incorporate non-separable material that was previously distributed + under the GNU General Public License (GPL), the law of the Commonwealth of + Virginia shall govern this License Agreement only as to issues arising under or + with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in + this License Agreement shall be deemed to create any relationship of agency, + partnership, or joint venture between CNRI and Licensee. This License Agreement + does not grant permission to use CNRI trademarks or trade name in a trademark + sense to endorse or promote products or services of Licensee, or any third + party. + + 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing + or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and + conditions of this License Agreement. + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +.. parsed-literal:: + + Copyright © 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The + Netherlands. All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided that + the above copyright notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting documentation, and that + the name of Stichting Mathematisch Centrum or CWI not be used in advertising or + publicity pertaining to distribution of the software without specific, written + prior permission. + + STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT + OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + + +.. _BSD0: + +ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION +------------------------------------------------------------ + +.. parsed-literal:: + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + + +.. _OtherLicenses: + +Licenses and Acknowledgements for Incorporated Software +======================================================= + +This section is an incomplete, but growing list of licenses and acknowledgements +for third-party software incorporated in the Python distribution. + + +Mersenne Twister +---------------- + +The :mod:`!_random` C extension underlying the :mod:`random` module +includes code based on a download from +http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html. The following are +the verbatim comments from the original code:: + + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) + + +Sockets +------- + +The :mod:`socket` module uses the functions, :c:func:`!getaddrinfo`, and +:c:func:`!getnameinfo`, which are coded in separate source files from the WIDE +Project, https://www.wide.ad.jp/. :: + + Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + +Asynchronous socket services +---------------------------- + +The :mod:`!test.support.asynchat` and :mod:`!test.support.asyncore` +modules contain the following notice:: + + Copyright 1996 by Sam Rushing + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of Sam + Rushing not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior + permission. + + SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +Cookie management +----------------- + +The :mod:`http.cookies` module contains the following notice:: + + Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu> + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software + and its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + Timothy O'Malley not be used in advertising or publicity + pertaining to distribution of the software without specific, written + prior permission. + + Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR + ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + + +Execution tracing +----------------- + +The :mod:`trace` module contains the following notice:: + + portions copyright 2001, Autonomous Zones Industries, Inc., all rights... + err... reserved and offered to the public under the terms of the + Python 2.2 license. + Author: Zooko O'Whielacronx + http://zooko.com/ + mailto:zooko@zooko.com + + Copyright 2000, Mojam Media, Inc., all rights reserved. + Author: Skip Montanaro + + Copyright 1999, Bioreason, Inc., all rights reserved. + Author: Andrew Dalke + + Copyright 1995-1997, Automatrix, Inc., all rights reserved. + Author: Skip Montanaro + + Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved. + + + Permission to use, copy, modify, and distribute this Python software and + its associated documentation for any purpose without fee is hereby + granted, provided that the above copyright notice appears in all copies, + and that both that copyright notice and this permission notice appear in + supporting documentation, and that the name of neither Automatrix, + Bioreason or Mojam Media be used in advertising or publicity pertaining to + distribution of the software without specific, written prior permission. + + +UUencode and UUdecode functions +------------------------------- + +The ``uu`` codec contains the following notice:: + + Copyright 1994 by Lance Ellinghouse + Cathedral City, California Republic, United States of America. + All Rights Reserved + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of Lance Ellinghouse + not be used in advertising or publicity pertaining to distribution + of the software without specific, written prior permission. + LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO + THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE + FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Modified by Jack Jansen, CWI, July 1995: + - Use binascii module to do the actual line-by-line conversion + between ascii and binary. This results in a 1000-fold speedup. The C + version is still 5 times faster, though. + - Arguments more compliant with Python standard + + +XML Remote Procedure Calls +-------------------------- + +The :mod:`xmlrpc.client` module contains the following notice:: + + The XML-RPC client interface is + + Copyright (c) 1999-2002 by Secret Labs AB + Copyright (c) 1999-2002 by Fredrik Lundh + + By obtaining, using, and/or copying this software and/or its + associated documentation, you agree that you have read, understood, + and will comply with the following terms and conditions: + + Permission to use, copy, modify, and distribute this software and + its associated documentation for any purpose and without fee is + hereby granted, provided that the above copyright notice appears in + all copies, and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + Secret Labs AB or the author not be used in advertising or publicity + pertaining to distribution of the software without specific, written + prior permission. + + SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- + ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR + BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. + + +test_epoll +---------- + +The :mod:`!test.test_epoll` module contains the following notice:: + + Copyright (c) 2001-2006 Twisted Matrix Laboratories. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Select kqueue +------------- + +The :mod:`select` module contains the following notice for the kqueue +interface:: + + Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + +SipHash24 +--------- + +The file :file:`Python/pyhash.c` contains Marek Majkowski' implementation of +Dan Bernstein's SipHash24 algorithm. It contains the following note:: + + <MIT License> + Copyright (c) 2013 Marek Majkowski <marek@popcount.org> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + </MIT License> + + Original location: + https://github.com/majek/csiphash/ + + Solution inspired by code from: + Samuel Neves (supercop/crypto_auth/siphash24/little) + djb (supercop/crypto_auth/siphash24/little2) + Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c) + + +strtod and dtoa +--------------- + +The file :file:`Python/dtoa.c`, which supplies C functions dtoa and +strtod for conversion of C doubles to and from strings, is derived +from the file of the same name by David M. Gay, currently available +from https://web.archive.org/web/20220517033456/http://www.netlib.org/fp/dtoa.c. +The original file, as retrieved on March 16, 2009, contains the following +copyright and licensing notice:: + + /**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + + +OpenSSL +------- + +The modules :mod:`hashlib`, :mod:`posix` and :mod:`ssl` use +the OpenSSL library for added performance if made available by the +operating system. Additionally, the Windows and macOS installers for +Python may include a copy of the OpenSSL libraries, so we include a copy +of the OpenSSL license here. For the OpenSSL 3.0 release, +and later releases derived from that, the Apache License v2 applies:: + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +expat +----- + +The :mod:`pyexpat <xml.parsers.expat>` extension is built using an included copy of the expat +sources unless the build is configured :option:`--with-system-expat`: + +.. literalinclude:: ../Modules/expat/COPYING + :language: text + + +libffi +------ + +The :mod:`!_ctypes` C extension underlying the :mod:`ctypes` module +is built using an included copy of the libffi +sources unless the build is configured ``--with-system-libffi``:: + + Copyright (c) 1996-2008 Red Hat, Inc and others. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + +zlib +---- + +The :mod:`zlib` extension is built using an included copy of the zlib +sources if the zlib version found on the system is too old to be +used for the build:: + + Copyright (C) 1995-2011 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + +cfuhash +------- + +The implementation of the hash table used by the :mod:`tracemalloc` is based +on the cfuhash project:: + + Copyright (c) 2005 Don Owens + All rights reserved. + + This code is released under the BSD license: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + + +libmpdec +-------- + +The :mod:`!_decimal` C extension underlying the :mod:`decimal` module +is built using an included copy of the libmpdec +library unless the build is configured ``--with-system-libmpdec``:: + + Copyright (c) 2008-2020 Stefan Krah. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + +W3C C14N test suite +------------------- + +The C14N 2.0 test suite in the :mod:`test` package +(``Lib/test/xmltestdata/c14n-20/``) was retrieved from the W3C website at +https://www.w3.org/TR/xml-c14n2-testcases/ and is distributed under the +3-clause BSD license:: + + Copyright (c) 2013 W3C(R) (MIT, ERCIM, Keio, Beihang), + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of works must retain the original copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the original copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the W3C nor the names of its contributors may be + used to endorse or promote products derived from this work without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +.. _mimalloc-license: + +mimalloc +-------- + +MIT License:: + + Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + +asyncio +---------- + +Parts of the :mod:`asyncio` module are incorporated from +`uvloop 0.16 <https://github.com/MagicStack/uvloop/tree/v0.16.0>`_, +which is distributed under the MIT license:: + + Copyright (c) 2015-2021 MagicStack Inc. http://magic.io + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Global Unbounded Sequences (GUS) +-------------------------------- + +The file :file:`Python/qsbr.c` is adapted from FreeBSD's "Global Unbounded +Sequences" safe memory reclamation scheme in +`subr_smr.c <https://github.com/freebsd/freebsd-src/blob/main/sys/kern/subr_smr.c>`_. +The file is distributed under the 2-Clause BSD License:: + + Copyright (c) 2019,2020 Jeffrey Roberson <jeff@FreeBSD.org> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice unmodified, this list of conditions, and the following + disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Zstandard bindings +------------------ + +Zstandard bindings in :file:`Modules/_zstd` and :file:`Lib/compression/zstd` +are based on code from the +`pyzstd library <https://github.com/Rogdham/pyzstd/>`_, copyright Ma Lin and +contributors. The pyzstd code is distributed under the 3-Clause BSD License:: + + Copyright (c) 2020-present, Ma Lin and contributors. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Profiling module +---------------- + +The :mod:`!profiling` module includes vendored third-party libraries in +:file:`Lib/profiling/sampling/_vendor/` with the following licenses: + +**d3-flamegraph** + +The d3-flamegraph library is distributed under the Apache License, Version 2.0. +See the OpenSSL section above for the full text of the Apache License Version 2.0. + +**d3.js** + +The d3.js library contains the following notice:: + + Copyright 2010-2021 Mike Bostock + + Permission to use, copy, modify, and/or distribute this software for any purpose + with or without fee is hereby granted, provided that the above copyright notice + and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + +Pixi packages +------------- + +The Pixi package definitions found in :file:`Tools/pixi-packages` are derived +from https://github.com/conda-forge/python-feedstock which contains the following +license:: + + BSD-3-Clause license + Copyright (c) 2015-2026, conda-forge contributors + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + + +Unicode Character Database +-------------------------- + +An extract of the `Unicode Character Database <https://www.unicode.org/ucd/>`__, +converted to an internal format, is used by the :mod:`unicodedata` module and +for the Unicode support of the :class:`str` type. The original Unicode data +files are distributed under the `Unicode License <https://www.unicode.org/license.txt>`__:: + + UNICODE LICENSE V3 + + COPYRIGHT AND PERMISSION NOTICE + + Copyright © 1991-2026 Unicode, Inc. + + NOTICE TO USER: Carefully read the following legal agreement. BY + DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR + SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE + TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT + DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of data files and any associated documentation (the "Data Files") or + software and any associated documentation (the "Software") to deal in the + Data Files or Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, and/or sell + copies of the Data Files or Software, and to permit persons to whom the + Data Files or Software are furnished to do so, provided that either (a) + this copyright and permission notice appear with all copies of the Data + Files or Software, or (b) this copyright and permission notice appear in + associated Documentation. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + THIRD PARTY RIGHTS. + + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE + BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA + FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder shall + not be used in advertising or otherwise to promote the sale, use or other + dealings in these Data Files or Software without prior written + authorization of the copyright holder. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/make.bat b/stdlib/kvlang/reference/python/cpython/Doc/make.bat new file mode 100644 index 00000000..e94743f7 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/make.bat @@ -0,0 +1,192 @@ +@echo off +setlocal + +pushd %~dp0 + +set this=%~n0 + +call ..\PCbuild\find_python.bat %PYTHON% + +if not defined PYTHON set PYTHON=py + +if not defined SPHINXBUILD ( + %PYTHON% -c "import sphinx" > nul 2> nul + if errorlevel 1 ( + echo Installing sphinx with %PYTHON% + %PYTHON% -m pip install -r requirements.txt + if errorlevel 1 exit /B + ) + set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" +) + +%PYTHON% -c "import python_docs_theme" > nul 2> nul +if errorlevel 1 ( + echo Installing python-docs-theme with %PYTHON% + %PYTHON% -m pip install python-docs-theme + if errorlevel 1 exit /B +) + +if not defined BLURB ( + %PYTHON% -c "import blurb" > nul 2> nul + if errorlevel 1 ( + echo Installing blurb with %PYTHON% + rem Should have been installed with Sphinx earlier + %PYTHON% -m pip install blurb + if errorlevel 1 exit /B + ) + set BLURB=%PYTHON% -m blurb +) + +if not defined SPHINXLINT ( + %PYTHON% -c "import sphinxlint" > nul 2> nul + if errorlevel 1 ( + echo Installing sphinx-lint with %PYTHON% + rem Should have been installed with Sphinx earlier + %PYTHON% -m pip install sphinx-lint + if errorlevel 1 exit /B + ) + set SPHINXLINT=%PYTHON% -m sphinxlint +) + +if "%1" NEQ "htmlhelp" goto :skiphhcsearch +if exist "%HTMLHELP%" goto :skiphhcsearch + +rem Search for HHC in likely places +set HTMLHELP= +where hhc /q && set "HTMLHELP=hhc" && goto :skiphhcsearch +where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" ( + echo. + echo.The HTML Help Workshop was not found. Set the HTMLHELP variable + echo.to the path to hhc.exe or download and install it from + echo.http://msdn.microsoft.com/en-us/library/ms669985 + exit /B 1 +) +:skiphhcsearch + +if not defined DISTVERSION for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v + +if not defined BUILDDIR set BUILDDIR=build + +rem Targets that don't require sphinx-build +if "%1" EQU "" goto help +if "%1" EQU "help" goto help +if "%1" EQU "check" goto check +if "%1" EQU "serve" goto serve +if "%1" == "clean" ( + rmdir /q /s "%BUILDDIR%" + goto end +) + +%SPHINXBUILD% >nul 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + popd + exit /B 1 +) + +rem Targets that do require sphinx-build and have their own label +if "%1" EQU "htmlview" goto htmlview + +rem Everything else +goto build + +:help +echo.usage: %this% BUILDER [filename ...] +echo. +echo.Call %this% with the desired Sphinx builder as the first argument, e.g. +echo.``%this% html`` or ``%this% doctest``. Interesting targets that are +echo.always available include: +echo. +echo. Provided by Sphinx: +echo. html, htmlhelp, latex, text +echo. linkcheck, changes, doctest +echo. Provided by this script: +echo. clean, check, htmlview +echo. +echo.All arguments past the first one are passed through to sphinx-build as +echo.filenames to build or are ignored. See README.rst in this directory or +echo.the documentation for your version of Sphinx for more exhaustive lists +echo.of available targets and descriptions of each. +echo. +echo.This script assumes that the SPHINXBUILD environment variable contains +echo.a legitimate command for calling sphinx-build, or that sphinx-build is +echo.on your PATH if SPHINXBUILD is not set. Options for sphinx-build can +echo.be passed by setting the SPHINXOPTS environment variable. +goto end + +:build +if not exist "%BUILDDIR%" mkdir "%BUILDDIR%" + +if not exist build mkdir build +if exist ..\Misc\NEWS ( + echo.Copying existing Misc\NEWS file to Doc\build\NEWS + copy ..\Misc\NEWS build\NEWS > nul +) else if exist ..\Misc\NEWS.D ( + if defined BLURB ( + echo.Merging Misc/NEWS with %BLURB% + %BLURB% merge -f build\NEWS + ) else ( + echo.No Misc/NEWS file and Blurb is not available. + exit /B 1 + ) +) + +if defined PAPER ( + set SPHINXOPTS=--define latex_elements.papersize=%PAPER% %SPHINXOPTS% +) +if "%1" EQU "htmlhelp" ( + set SPHINXOPTS=--define html_theme_options.body_max_width=none %SPHINXOPTS% +) +cmd /S /C "%SPHINXBUILD% %SPHINXOPTS% --builder %1 --doctree-dir build\doctrees . "%BUILDDIR%\%1" %2 %3 %4 %5 %6 %7 %8 %9" + +if "%1" EQU "htmlhelp" ( + "%HTMLHELP%" "%BUILDDIR%\htmlhelp\python%DISTVERSION:.=%.hhp" + rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2 + if not errorlevel 2 cmd /C exit /b 0 +) + +echo. +if errorlevel 1 ( + echo.Build failed (exit code %ERRORLEVEL%^), check for error messages + echo.above. Any output will be found in %BUILDDIR%\%1 +) else ( + echo.Build succeeded. All output should be in %BUILDDIR%\%1 +) +goto end + +:htmlview +if NOT "%2" EQU "" ( + echo.Can't specify filenames to build with htmlview target, ignoring. +) +cmd /C %this% html + +if EXIST "%BUILDDIR%\html\index.html" ( + echo.Opening "%BUILDDIR%\html\index.html" in the default web browser... + start "" "%BUILDDIR%\html\index.html" +) + +goto end + +:check +rem Check the docs and NEWS files with sphinx-lint. +rem Ignore the tools dir and check that the default role is not used. +cmd /S /C "%SPHINXLINT% -i tools --enable default-role" +cmd /S /C "%SPHINXLINT% --enable default-role ..\Misc\NEWS.d\next\ " +goto end + +:serve +echo.The serve target was removed, use htmlview instead (see bpo-36329) +goto end + +:end +popd diff --git a/stdlib/kvlang/reference/python/cpython/Doc/pylock.toml b/stdlib/kvlang/reference/python/cpython/Doc/pylock.toml new file mode 100644 index 00000000..94b7d9d4 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/pylock.toml @@ -0,0 +1,245 @@ +# This file was autogenerated by uv via the following command: +# make lock +lock-version = "1.0" +created-by = "uv" +requires-python = ">=3.12" + +[[packages]] +name = "alabaster" +version = "1.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", upload-time = 2024-07-26T18:15:03Z, size = 24210, hashes = { sha256 = "c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", upload-time = 2024-07-26T18:15:02Z, size = 13929, hashes = { sha256 = "fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b" } }] + +[[packages]] +name = "babel" +version = "2.18.0" +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", upload-time = 2026-02-01T12:30:56Z, size = 9959554, hashes = { sha256 = "b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", upload-time = 2026-02-01T12:30:53Z, size = 10196845, hashes = { sha256 = "e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35" } }] + +[[packages]] +name = "blurb" +version = "2.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/d7/82/8597d891f4b03f3eaefcb4213a811643d558350cac9a69864d127832cc4f/blurb-2.0.0.tar.gz", upload-time = 2025-01-15T12:48:53Z, size = 24666, hashes = { sha256 = "c78d8114294225a4f7a2eabba6e05d36a6a50e45ba9f5a41afabc198350038e0" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/b4/03/374bd9e31b58e8a8e5dc65cc3f68ca7cdd716c32b5e5dcb0e1b76bb75b4a/blurb-2.0.0-py3-none-any.whl", upload-time = 2025-01-15T12:48:49Z, size = 18924, hashes = { sha256 = "f6d0e858dbe94765f6a89b8228217ffdb9c19cff08fc8f2c3153954846d31aa1" } }] + +[[packages]] +name = "certifi" +version = "2026.7.22" +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", upload-time = 2026-07-22T03:35:12Z, size = 138112, hashes = { sha256 = "741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", upload-time = 2026-07-22T03:35:11Z, size = 136983, hashes = { sha256 = "62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775" } }] + +[[packages]] +name = "charset-normalizer" +version = "3.4.9" +sdist = { url = "https://files.pythonhosted.org/packages/bd/2a/23f34ec9d04624958e137efdc394888716353190e75f25dd22c7a2c7a8aa/charset_normalizer-3.4.9.tar.gz", upload-time = 2026-07-07T14:34:58Z, size = 152439, hashes = { sha256 = "673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b" } } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/4a/ecbd131485c07fcdfad54e28946d513e3da22ef3b4bd854dcafae54ec739/charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl", upload-time = 2026-07-07T14:33:15Z, size = 319300, hashes = { sha256 = "45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0" } }, + { url = "https://files.pythonhosted.org/packages/ec/96/5d9364e3342d69f3a045e1777bc47c85c383e6e9466d561b33fdb419d1f9/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:33:17Z, size = 215802, hashes = { sha256 = "9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9" } }, + { url = "https://files.pythonhosted.org/packages/4b/4c/5361f9aa7f2cb58d94f2ab831b3d493f69efb1d239654b4744e3c09527cb/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:33:18Z, size = 237171, hashes = { sha256 = "9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44" } }, + { url = "https://files.pythonhosted.org/packages/50/78/ce342ca4ff30b2eb49fe6d9578df85974f90c67d294113e94efdd9664cbd/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:33:20Z, size = 233075, hashes = { sha256 = "7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9" } }, + { url = "https://files.pythonhosted.org/packages/01/c4/4fa4c8b3097a11f3c5f09a35b72ed6855fb1d332469504962ab7bafcc702/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:33:21Z, size = 224256, hashes = { sha256 = "5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd" } }, + { url = "https://files.pythonhosted.org/packages/87/3a/ad914516df7e358a81aae018caa5e0470ba827fa6d763b1d2e87d920a5f6/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:33:23Z, size = 208784, hashes = { sha256 = "90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84" } }, + { url = "https://files.pythonhosted.org/packages/d7/74/3c12f9755717dfe5c5c87da63f35d765fa0c00382ec26bf23f7fae34f2ba/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:33:24Z, size = 219928, hashes = { sha256 = "9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b" } }, + { url = "https://files.pythonhosted.org/packages/33/9a/895095b83e7907abd6d3d99aad3a38ad0d9686cc186cb0c94c24320fe63e/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:33:26Z, size = 218489, hashes = { sha256 = "60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde" } }, + { url = "https://files.pythonhosted.org/packages/a1/34/ef5c05f412f42520d7709b7d3784d19640839eb7366ded1755511585429f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:33:27Z, size = 210267, hashes = { sha256 = "a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39" } }, + { url = "https://files.pythonhosted.org/packages/83/dc/9b29fa4412b318bf3bfea985c35d67eb55e04b59a7c3f2237168b0e0be6f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:33:29Z, size = 226030, hashes = { sha256 = "03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62" } }, + { url = "https://files.pythonhosted.org/packages/0e/42/6dbc00b8cd16011691203e33570fa42ed5746599a2e878112d16eab403a3/charset_normalizer-3.4.9-cp312-cp312-win32.whl", upload-time = 2026-07-07T14:33:30Z, size = 151185, hashes = { sha256 = "78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642" } }, + { url = "https://files.pythonhosted.org/packages/80/cc/f920afd1a23c58ccd53c1d36085a71893a4737ff5e66e0371efab6809850/charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl", upload-time = 2026-07-07T14:33:32Z, size = 162557, hashes = { sha256 = "4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0" } }, + { url = "https://files.pythonhosted.org/packages/f0/e6/0386d43a261ff4e4b30c5857af7df877254b46bec7b9d1b74b6bf969a90b/charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl", upload-time = 2026-07-07T14:33:33Z, size = 152665, hashes = { sha256 = "78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2" } }, + { url = "https://files.pythonhosted.org/packages/b2/06/97ec2aeae780b31d742b6352218b43841a6871e2564578ca522dce4a45c3/charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", upload-time = 2026-07-07T14:33:35Z, size = 317688, hashes = { sha256 = "440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614" } }, + { url = "https://files.pythonhosted.org/packages/d0/39/8ff066c672434225f8d25f8b739f992af250944392173dcc88362681c9bf/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:33:36Z, size = 214982, hashes = { sha256 = "21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698" } }, + { url = "https://files.pythonhosted.org/packages/92/8f/3a47a3667c83c2df9483d91644c6c107de3bf8874aa1793da9d3012eb986/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:33:38Z, size = 236460, hashes = { sha256 = "e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b" } }, + { url = "https://files.pythonhosted.org/packages/f1/60/b22cdbee7e4013dab8b0d7647fc6181120fbbbc8f7025c226d15bd5a47fc/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:33:40Z, size = 232003, hashes = { sha256 = "bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9" } }, + { url = "https://files.pythonhosted.org/packages/ea/f8/72eb13dcabe7257035cea8aefd922caad2f110d252bf9f67c4c2ca763aee/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:33:41Z, size = 223149, hashes = { sha256 = "84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33" } }, + { url = "https://files.pythonhosted.org/packages/b0/3e/faee8f9de92b14ee1198e9163252bb15efee7301b31256a3b6d9ebfdd0dd/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:33:43Z, size = 207901, hashes = { sha256 = "5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63" } }, + { url = "https://files.pythonhosted.org/packages/3a/25/45f30093ae27dd7b92a793b61882a38685f993700113ca36e0c9c14965e1/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:33:44Z, size = 219176, hashes = { sha256 = "a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0" } }, + { url = "https://files.pythonhosted.org/packages/48/18/c8f397329c35e32f6a837e488986f4ae03bd2abebc453b48714991630c2f/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:33:46Z, size = 217356, hashes = { sha256 = "416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe" } }, + { url = "https://files.pythonhosted.org/packages/86/7e/5ce0bba863470fd1902d5e5843968951bddf38abe4742fc97116ef4598b3/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:33:47Z, size = 209614, hashes = { sha256 = "75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35" } }, + { url = "https://files.pythonhosted.org/packages/6c/ef/2473d3c4d869155be4af1191111d59c4d5c4e0173026f7e85b176e23bf65/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:33:49Z, size = 224991, hashes = { sha256 = "69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8" } }, + { url = "https://files.pythonhosted.org/packages/d0/a3/53ddae3db108a088156aa8ddfafd411ebbc1340f48c5573f697b27f69a39/charset_normalizer-3.4.9-cp313-cp313-win32.whl", upload-time = 2026-07-07T14:33:50Z, size = 150622, hashes = { sha256 = "51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9" } }, + { url = "https://files.pythonhosted.org/packages/e8/ef/6953a77c7cf2c2ff9998e6f575ab3e380119f100223381565a4f94c1f836/charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", upload-time = 2026-07-07T14:33:52Z, size = 161947, hashes = { sha256 = "fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115" } }, + { url = "https://files.pythonhosted.org/packages/6e/fb/d560d1d1555debbfe7849d9cac6145c1b537709d79576bf22557ed803b82/charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", upload-time = 2026-07-07T14:33:53Z, size = 152594, hashes = { sha256 = "611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012" } }, + { url = "https://files.pythonhosted.org/packages/7e/8d/496817fa0944239ecae662dd57ea765cfeaec6a735f9f025d4b7b72e7143/charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", upload-time = 2026-07-07T14:33:54Z, size = 317253, hashes = { sha256 = "0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380" } }, + { url = "https://files.pythonhosted.org/packages/2b/f9/ef4a69ea338ad3c0deceea0f5f7d2380ae8b52132b06d652cb0d2cd86706/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:33:56Z, size = 215898, hashes = { sha256 = "8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9" } }, + { url = "https://files.pythonhosted.org/packages/8c/e7/5ddfd76fc061eb52de219658a4aa431cbacadf0a0219c8854f00da50d289/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:33:57Z, size = 236718, hashes = { sha256 = "33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4" } }, + { url = "https://files.pythonhosted.org/packages/49/ba/768fa3f36048d81c477a0ce61f813bc1454d80917ccfe550abd9f44f5e24/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:33:59Z, size = 232519, hashes = { sha256 = "f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a" } }, + { url = "https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:34:01Z, size = 223143, hashes = { sha256 = "c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046" } }, + { url = "https://files.pythonhosted.org/packages/19/79/55c32d06d76ae4feafe053f061f3e3ab70bcf19f4007797ce8c3efda7830/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:34:03Z, size = 206742, hashes = { sha256 = "f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81" } }, + { url = "https://files.pythonhosted.org/packages/10/e0/47c079dd82d217c807479cd59ffd30af56307ea31c108b75758970459ad3/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:34:04Z, size = 219191, hashes = { sha256 = "4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917" } }, + { url = "https://files.pythonhosted.org/packages/42/ab/b9bc2e77d6b44a7e46ef62ec5cac1c9a6ba7b9135a5d560f002696ec9995/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:34:06Z, size = 218328, hashes = { sha256 = "a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41" } }, + { url = "https://files.pythonhosted.org/packages/f1/78/c9c71d599f5aa2d42bcdd35cbbd46d7f535351a57e40ff7d8e5a7e219401/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:34:07Z, size = 207406, hashes = { sha256 = "d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1" } }, + { url = "https://files.pythonhosted.org/packages/f6/39/c914445c321a845097ce4f6ac7de9a18228a77b766272125a1ce00d851eb/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:34:09Z, size = 225157, hashes = { sha256 = "898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf" } }, + { url = "https://files.pythonhosted.org/packages/9b/f2/c0d4b8508565a36bc5c624e88ed297f5b0b1095011034d7f5b83a69908b5/charset_normalizer-3.4.9-cp314-cp314-win32.whl", upload-time = 2026-07-07T14:34:10Z, size = 151095, hashes = { sha256 = "c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48" } }, + { url = "https://files.pythonhosted.org/packages/49/fd/a1d26144398c67486422a72bf5812cda22cb4ccfcd95a290fb41ceb4b8e2/charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", upload-time = 2026-07-07T14:34:12Z, size = 162796, hashes = { sha256 = "16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b" } }, + { url = "https://files.pythonhosted.org/packages/20/95/d75e82f8ce9fd323ebf059c16c9aadefb22a1ecde13b7840b35835e4886c/charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", upload-time = 2026-07-07T14:34:14Z, size = 153334, hashes = { sha256 = "40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519" } }, + { url = "https://files.pythonhosted.org/packages/00/5e/17398df3a139985ba9d11ed072531986f408c8fca952835ef1ab1820c02b/charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", upload-time = 2026-07-07T14:34:15Z, size = 338848, hashes = { sha256 = "609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198" } }, + { url = "https://files.pythonhosted.org/packages/cd/91/7253a32e86b7e1d1239b1b36ba6dd0f021a21107ab33054b53119cc083b9/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:34:17Z, size = 223022, hashes = { sha256 = "51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32" } }, + { url = "https://files.pythonhosted.org/packages/cb/32/2e64bd2be10e89c61e57ebe6a93fd98ae88eb7ebe414b5121f22c96c69eb/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:34:18Z, size = 241590, hashes = { sha256 = "cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632" } }, + { url = "https://files.pythonhosted.org/packages/3d/ef/d96ec496cfea0c21db43b0ad03891308b02388d054cc902cf0e5a1ad6a88/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:34:20Z, size = 239584, hashes = { sha256 = "fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf" } }, + { url = "https://files.pythonhosted.org/packages/d4/ce/9af95f7876194bd7a14e3dfe4a4de2e0bff02666a3910d72beafd06cc297/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:34:22Z, size = 230224, hashes = { sha256 = "df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990" } }, + { url = "https://files.pythonhosted.org/packages/52/94/af74dde74a3996bd959c350709bfe50e297823d70a8c1cbd54b838880863/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:34:23Z, size = 212667, hashes = { sha256 = "f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d" } }, + { url = "https://files.pythonhosted.org/packages/ee/f0/f1c4fe746c395922961b5916ed1d7d6e7d4c84851d19ed43cc89980ec953/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:34:25Z, size = 227179, hashes = { sha256 = "32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e" } }, + { url = "https://files.pythonhosted.org/packages/e4/56/6c745619ac397e8871e2bcd3cea1eec86b877488f33888b3aef5c3ed506e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:34:27Z, size = 225372, hashes = { sha256 = "83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c" } }, + { url = "https://files.pythonhosted.org/packages/78/ad/98aae8630ac71f16711968e38a5acfecce41b778bf2f0312851020f565a8/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:34:28Z, size = 215222, hashes = { sha256 = "cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2" } }, + { url = "https://files.pythonhosted.org/packages/f7/40/9593d54209765207a7f11073c06494c1721e4ca4a0a426c597679bf7f91e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:34:30Z, size = 231958, hashes = { sha256 = "ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534" } }, + { url = "https://files.pythonhosted.org/packages/b1/27/693ee5e8a18191eb38647360c51cd505013e2bd3b366aa43fd5344c21e3c/charset_normalizer-3.4.9-cp314-cp314t-win32.whl", upload-time = 2026-07-07T14:34:31Z, size = 155580, hashes = { sha256 = "0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226" } }, + { url = "https://files.pythonhosted.org/packages/80/3f/bd97d3d9c613013d07cb7733d299385b41df37f0471310f5a73dc359f0b8/charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", upload-time = 2026-07-07T14:34:33Z, size = 167620, hashes = { sha256 = "9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177" } }, + { url = "https://files.pythonhosted.org/packages/3d/c6/eee9dca4439b1061f76373f06ea855678cc4a64c1c3c90b50e479edbb8eb/charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", upload-time = 2026-07-07T14:34:35Z, size = 158037, hashes = { sha256 = "19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501" } }, + { url = "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl", upload-time = 2026-07-07T14:34:56Z, size = 64538, hashes = { sha256 = "68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5" } }, +] + +[[packages]] +name = "colorama" +version = "0.4.6" +marker = "sys_platform == 'win32'" +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }] + +[[packages]] +name = "docutils" +version = "0.21.2" +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", upload-time = 2024-04-23T18:57:18Z, size = 2204444, hashes = { sha256 = "3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", upload-time = 2024-04-23T18:57:14Z, size = 587408, hashes = { sha256 = "dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2" } }] + +[[packages]] +name = "idna" +version = "3.18" +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", upload-time = 2026-06-02T14:34:07Z, size = 196711, hashes = { sha256 = "ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", upload-time = 2026-06-02T14:34:06Z, size = 65455, hashes = { sha256 = "7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2" } }] + +[[packages]] +name = "imagesize" +version = "1.5.0" +sdist = { url = "https://files.pythonhosted.org/packages/cf/59/4b0dd64676aa6fb4986a755790cb6fc558559cf0084effad516820208ec3/imagesize-1.5.0.tar.gz", upload-time = 2026-03-03T01:59:54Z, size = 1281127, hashes = { sha256 = "8bfc5363a7f2133a89f0098451e0bcb1cd71aba4dc02bbcecb39d99d40e1b94f" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/1e/b1/a0662b03103c66cf77101a187f396ea91167cd9b7d5d3a2e465ad2c7ee9b/imagesize-1.5.0-py2.py3-none-any.whl", upload-time = 2026-03-03T01:59:52Z, size = 5763, hashes = { sha256 = "32677681b3f434c2cb496f00e89c5a291247b35b1f527589909e008057da5899" } }] + +[[packages]] +name = "jinja2" +version = "3.1.6" +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", upload-time = 2025-03-05T20:05:02Z, size = 245115, hashes = { sha256 = "0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", upload-time = 2025-03-05T20:05:00Z, size = 134899, hashes = { sha256 = "85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" } }] + +[[packages]] +name = "markupsafe" +version = "2.1.5" +sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", upload-time = 2024-02-02T16:31:22Z, size = 19384, hashes = { sha256 = "d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b" } } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", upload-time = 2024-02-02T16:30:33Z, size = 18215, hashes = { sha256 = "8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1" } }, + { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", upload-time = 2024-02-02T16:30:34Z, size = 14069, hashes = { sha256 = "3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4" } }, + { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2024-02-02T16:30:35Z, size = 29452, hashes = { sha256 = "ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee" } }, + { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-02-02T16:30:36Z, size = 28462, hashes = { sha256 = "f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5" } }, + { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2024-02-02T16:30:37Z, size = 27869, hashes = { sha256 = "ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b" } }, + { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", upload-time = 2024-02-02T16:30:39Z, size = 33906, hashes = { sha256 = "d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a" } }, + { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", upload-time = 2024-02-02T16:30:40Z, size = 32296, hashes = { sha256 = "bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f" } }, + { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", upload-time = 2024-02-02T16:30:42Z, size = 33038, hashes = { sha256 = "58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169" } }, + { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", upload-time = 2024-02-02T16:30:43Z, size = 16572, hashes = { sha256 = "8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad" } }, + { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", upload-time = 2024-02-02T16:30:44Z, size = 17127, hashes = { sha256 = "823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb" } }, +] + +[[packages]] +name = "packaging" +version = "24.2" +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", upload-time = 2024-11-08T09:47:47Z, size = 163950, hashes = { sha256 = "c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", upload-time = 2024-11-08T09:47:44Z, size = 65451, hashes = { sha256 = "09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759" } }] + +[[packages]] +name = "pygments" +version = "2.21.0" +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", upload-time = 2026-08-17T08:02:48Z, size = 5005329, hashes = { sha256 = "610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", upload-time = 2026-08-17T08:02:44Z, size = 1250147, hashes = { sha256 = "2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9" } }] + +[[packages]] +name = "python-docs-theme" +version = "2026.7" +sdist = { url = "https://files.pythonhosted.org/packages/54/ba/6de432a297e933eeee26a950298254061d3738b183b0d4c01d512a6a2575/python_docs_theme-2026.7.tar.gz", upload-time = 2026-07-27T20:12:04Z, size = 38838, hashes = { sha256 = "465431be2ebc5239e8f41b0acfae0cf8d842b50ec2fea549f61d9e6a3802432d" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/28/11/4dcaea01fd7bb557159f16b8015906b7a002327704972facac4af706307d/python_docs_theme-2026.7-py3-none-any.whl", upload-time = 2026-07-27T20:12:03Z, size = 47030, hashes = { sha256 = "6099e550bdce042d709db29375228a4fd51bfb238b7fad413782f2b402190c9e" } }] + +[[packages]] +name = "requests" +version = "2.34.2" +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", upload-time = 2026-05-14T19:25:27Z, size = 142856, hashes = { sha256 = "f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", upload-time = 2026-05-14T19:25:26Z, size = 73075, hashes = { sha256 = "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" } }] + +[[packages]] +name = "roman-numerals" +version = "4.1.0" +sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/41dc953bbeb056c17d5f7a519f50fdf010bd0553be2d630bc69d1e022703/roman_numerals-4.1.0.tar.gz", upload-time = 2025-12-17T18:25:34Z, size = 9077, hashes = { sha256 = "1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", upload-time = 2025-12-17T18:25:33Z, size = 7676, hashes = { sha256 = "647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7" } }] + +[[packages]] +name = "roman-numerals-py" +version = "4.1.0" +sdist = { url = "https://files.pythonhosted.org/packages/cb/b5/de96fca640f4f656eb79bbee0e79aeec52e3e0e359f8a3e6a0d366378b64/roman_numerals_py-4.1.0.tar.gz", upload-time = 2025-12-17T18:25:41Z, size = 4274, hashes = { sha256 = "f5d7b2b4ca52dd855ef7ab8eb3590f428c0b1ea480736ce32b01fef2a5f8daf9" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/27/2c/daca29684cbe9fd4bc711f8246da3c10adca1ccc4d24436b17572eb2590e/roman_numerals_py-4.1.0-py3-none-any.whl", upload-time = 2025-12-17T18:25:40Z, size = 4547, hashes = { sha256 = "553114c1167141c1283a51743759723ecd05604a1b6b507225e91dc1a6df0780" } }] + +[[packages]] +name = "snowballstemmer" +version = "2.2.0" +sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", upload-time = 2021-11-16T18:38:38Z, size = 86699, hashes = { sha256 = "09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", upload-time = 2021-11-16T18:38:34Z, size = 93002, hashes = { sha256 = "c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a" } }] + +[[packages]] +name = "sphinx" +version = "8.2.3" +sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", upload-time = 2025-03-02T22:31:59Z, size = 8321876, hashes = { sha256 = "398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", upload-time = 2025-03-02T22:31:56Z, size = 3589741, hashes = { sha256 = "4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3" } }] + +[[packages]] +name = "sphinx-linklint" +version = "2.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/f6/99/f9947b30fd11e782855a13de1aac7d08634edba1c193a0ee01bf5338531c/sphinx_linklint-2.0.0.tar.gz", upload-time = 2026-08-25T12:47:33Z, size = 23297, hashes = { sha256 = "e7ea4d3b1bd83665e9c2ab9fd92c6c645c805956d2e8ca6b0f528f3a9638910d" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/d7/3d/6b96af48e139357e1e041a710d943c4bb79ad149c7aab074df784b4395ec/sphinx_linklint-2.0.0-py3-none-any.whl", upload-time = 2026-08-25T12:47:32Z, size = 13390, hashes = { sha256 = "12aa64f3b3faaa6e8a979a7d1f2c38617866652b670e3d19fa0f60a6ce3657ef" } }] + +[[packages]] +name = "sphinx-notfound-page" +version = "1.0.4" +sdist = { url = "https://files.pythonhosted.org/packages/73/7d/c545883c714319380325a52c9f80d093c97e718d812fd8090e42b1a08508/sphinx_notfound_page-1.0.4.tar.gz", upload-time = 2024-07-31T12:29:21Z, size = 519228, hashes = { sha256 = "2a52f49cd367b5c4e64072de1591cc367714098500abf4ecb9a3ecb4fec25aae" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/87/c4/877a5beffb8dcaf35e919c4c3cad56732c76370d106126394f4ca211ad7f/sphinx_notfound_page-1.0.4-py3-none-any.whl", upload-time = 2024-07-31T12:29:18Z, size = 8170, hashes = { sha256 = "f7c26ae0df3cf3d6f38f56b068762e6203d0ebb7e1c804de1059598d7dd8b9d8" } }] + +[[packages]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", upload-time = 2024-07-29T01:09:00Z, size = 20053, hashes = { sha256 = "2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", upload-time = 2024-07-29T01:08:58Z, size = 119300, hashes = { sha256 = "4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5" } }] + +[[packages]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", upload-time = 2024-07-29T01:09:23Z, size = 12967, hashes = { sha256 = "411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", upload-time = 2024-07-29T01:09:21Z, size = 82530, hashes = { sha256 = "aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2" } }] + +[[packages]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", upload-time = 2024-07-29T01:09:37Z, size = 22617, hashes = { sha256 = "c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", upload-time = 2024-07-29T01:09:36Z, size = 98705, hashes = { sha256 = "166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8" } }] + +[[packages]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", upload-time = 2019-01-21T16:10:16Z, size = 5787, hashes = { sha256 = "a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", upload-time = 2019-01-21T16:10:14Z, size = 5071, hashes = { sha256 = "2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178" } }] + +[[packages]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", upload-time = 2024-07-29T01:09:56Z, size = 17165, hashes = { sha256 = "4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", upload-time = 2024-07-29T01:09:54Z, size = 88743, hashes = { sha256 = "b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb" } }] + +[[packages]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", upload-time = 2024-07-29T01:10:09Z, size = 16080, hashes = { sha256 = "e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", upload-time = 2024-07-29T01:10:08Z, size = 92072, hashes = { sha256 = "6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331" } }] + +[[packages]] +name = "sphinxext-opengraph" +version = "0.13.0" +sdist = { url = "https://files.pythonhosted.org/packages/f6/c0/eb6838e3bae624ce6c8b90b245d17e84252863150e95efdb88f92c8aa3fb/sphinxext_opengraph-0.13.0.tar.gz", upload-time = 2025-08-29T12:20:31Z, size = 1026875, hashes = { sha256 = "103335d08567ad8468faf1425f575e3b698e9621f9323949a6c8b96d9793e80b" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/bf/a4/66c1fd4f8fab88faf71cee04a945f9806ba0fef753f2cfc8be6353f64508/sphinxext_opengraph-0.13.0-py3-none-any.whl", upload-time = 2025-08-29T12:20:29Z, size = 1004152, hashes = { sha256 = "936c07828edc9ad9a7b07908b29596dc84ed0b3ceaa77acdf51282d232d4d80e" } }] + +[[packages]] +name = "urllib3" +version = "2.7.0" +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", upload-time = 2026-05-07T16:13:18Z, size = 433602, hashes = { sha256 = "231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", upload-time = 2026-05-07T16:13:17Z, size = 131087, hashes = { sha256 = "9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" } }] diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/compound_stmts.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/compound_stmts.rst new file mode 100644 index 00000000..28850ba8 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/compound_stmts.rst @@ -0,0 +1,2077 @@ +.. _compound: + +******************* +Compound statements +******************* + +.. index:: pair: compound; statement + +Compound statements contain (groups of) other statements; they affect or control +the execution of those other statements in some way. In general, compound +statements span multiple lines, although in simple incarnations a whole compound +statement may be contained in one line. + +The :keyword:`if`, :keyword:`while` and :keyword:`for` statements implement +traditional control flow constructs. :keyword:`try` specifies exception +handlers and/or cleanup code for a group of statements, while the +:keyword:`with` statement allows the execution of initialization and +finalization code around a block of code. Function and class definitions are +also syntactically compound statements. + +.. index:: + single: clause + single: suite + single: ; (semicolon) + +A compound statement consists of one or more 'clauses.' A clause consists of a +header and a 'suite.' The clause headers of a particular compound statement are +all at the same indentation level. Each clause header begins with a uniquely +identifying keyword and ends with a colon. A suite is a group of statements +controlled by a clause. A suite can be one or more semicolon-separated simple +statements on the same line as the header, following the header's colon, or it +can be one or more indented statements on subsequent lines. Only the latter +form of a suite can contain nested compound statements; the following is illegal, +mostly because it wouldn't be clear to which :keyword:`if` clause a following +:keyword:`else` clause would belong:: + + if test1: if test2: print(x) + +Also note that the semicolon binds tighter than the colon in this context, so +that in the following example, either all or none of the :func:`print` calls are +executed:: + + if x < y < z: print(x); print(y); print(z) + +Summarizing: + + +.. productionlist:: python-grammar + compound_stmt: `if_stmt` + : | `while_stmt` + : | `for_stmt` + : | `try_stmt` + : | `with_stmt` + : | `match_stmt` + : | `funcdef` + : | `classdef` + : | `async_with_stmt` + : | `async_for_stmt` + : | `async_funcdef` + suite: `stmt_list` NEWLINE | NEWLINE INDENT `statement`+ DEDENT + statement: `stmt_list` NEWLINE | `compound_stmt` + stmt_list: `simple_stmt` (";" `simple_stmt`)* [";"] + +.. index:: + single: NEWLINE token + single: DEDENT token + pair: dangling; else + +Note that statements always end in a ``NEWLINE`` possibly followed by a +``DEDENT``. Also note that optional continuation clauses always begin with a +keyword that cannot start a statement, thus there are no ambiguities (the +'dangling :keyword:`else`' problem is solved in Python by requiring nested +:keyword:`if` statements to be indented). + +The formatting of the grammar rules in the following sections places each clause +on a separate line for clarity. + + +.. _if: +.. _elif: +.. _else: + +The :keyword:`!if` statement +============================ + +.. index:: + ! pair: statement; if + pair: keyword; elif + pair: keyword; else + single: : (colon); compound statement + +The :keyword:`if` statement is used for conditional execution: + +.. productionlist:: python-grammar + if_stmt: "if" `assignment_expression` ":" `suite` + : ("elif" `assignment_expression` ":" `suite`)* + : ["else" ":" `suite`] + +It selects exactly one of the suites by evaluating the expressions one by one +until one is found to be true (see section :ref:`booleans` for the definition of +true and false); then that suite is executed (and no other part of the +:keyword:`if` statement is executed or evaluated). If all expressions are +false, the suite of the :keyword:`else` clause, if present, is executed. + + +.. _while: + +The :keyword:`!while` statement +=============================== + +.. index:: + ! pair: statement; while + pair: keyword; else + pair: loop; statement + single: : (colon); compound statement + +The :keyword:`while` statement is used for repeated execution as long as an +expression is true: + +.. productionlist:: python-grammar + while_stmt: "while" `assignment_expression` ":" `suite` + : ["else" ":" `suite`] + +This repeatedly tests the expression and, if it is true, executes the first +suite; if the expression is false (which may be the first time it is tested) the +suite of the :keyword:`!else` clause, if present, is executed and the loop +terminates. + +.. index:: + pair: statement; break + pair: statement; continue + +A :keyword:`break` statement executed in the first suite terminates the loop +without executing the :keyword:`!else` clause's suite. A :keyword:`continue` +statement executed in the first suite skips the rest of the suite and goes back +to testing the expression. + + +.. _for: + +The :keyword:`!for` statement +============================= + +.. index:: + ! pair: statement; for + pair: keyword; in + pair: keyword; else + pair: target; list + pair: loop; statement + pair: object; sequence + single: : (colon); compound statement + +The :keyword:`for` statement is used to iterate over the elements of a sequence +(such as a string, tuple or list) or other iterable object: + +.. productionlist:: python-grammar + for_stmt: "for" `target_list` "in" `starred_expression_list` ":" `suite` + : ["else" ":" `suite`] + +The :token:`~python-grammar:starred_expression_list` expression is evaluated +once; it should yield an :term:`iterable` object. An :term:`iterator` is +created for that iterable. The first item provided by the iterator is then +assigned to the target list using the standard rules for assignments +(see :ref:`assignment`), and the suite is executed. This repeats for each +item provided by the iterator. When the iterator is exhausted, +the suite in the :keyword:`!else` clause, +if present, is executed, and the loop terminates. + +.. index:: + pair: statement; break + pair: statement; continue + +A :keyword:`break` statement executed in the first suite terminates the loop +without executing the :keyword:`!else` clause's suite. A :keyword:`continue` +statement executed in the first suite skips the rest of the suite and continues +with the next item, or with the :keyword:`!else` clause if there is no next +item. + +The for-loop makes assignments to the variables in the target list. +This overwrites all previous assignments to those variables including +those made in the suite of the for-loop:: + + for i in range(10): + print(i) + i = 5 # this will not affect the for-loop + # because i will be overwritten with the next + # index in the range + + +.. index:: + pair: built-in function; range + +Names in the target list are not deleted when the loop is finished, but if the +sequence is empty, they will not have been assigned to at all by the loop. Hint: +the built-in type :func:`range` represents immutable arithmetic sequences of integers. +For instance, iterating ``range(3)`` successively yields 0, 1, and then 2. + +.. versionchanged:: 3.11 + Starred elements are now allowed in the expression list. + + +.. _try: + +The :keyword:`!try` statement +============================= + +.. index:: + ! pair: statement; try + pair: keyword; except + pair: keyword; finally + pair: keyword; else + pair: keyword; as + single: : (colon); compound statement + +The :keyword:`!try` statement specifies exception handlers and/or cleanup code +for a group of statements: + +.. productionlist:: python-grammar + try_stmt: `try1_stmt` | `try2_stmt` | `try3_stmt` + try1_stmt: "try" ":" `suite` + : ("except" [`expression` ["as" `identifier`]] ":" `suite`)+ + : ["else" ":" `suite`] + : ["finally" ":" `suite`] + try2_stmt: "try" ":" `suite` + : ("except" "*" `expression` ["as" `identifier`] ":" `suite`)+ + : ["else" ":" `suite`] + : ["finally" ":" `suite`] + try3_stmt: "try" ":" `suite` + : "finally" ":" `suite` + +Additional information on exceptions can be found in section :ref:`exceptions`, +and information on using the :keyword:`raise` statement to generate exceptions +may be found in section :ref:`raise`. + +.. versionchanged:: 3.14 + Support for optionally dropping grouping parentheses when using multiple exception types. See :pep:`758`. + +.. _except: + +:keyword:`!except` clause +------------------------- + +The :keyword:`!except` clause(s) specify one or more exception handlers. When no +exception occurs in the :keyword:`try` clause, no exception handler is executed. +When an exception occurs in the :keyword:`!try` suite, a search for an exception +handler is started. This search inspects the :keyword:`!except` clauses in turn +until one is found that matches the exception. +An expression-less :keyword:`!except` clause, if present, must be last; +it matches any exception. + +For an :keyword:`!except` clause with an expression, the +expression must evaluate to an exception type or a tuple of exception types. Parentheses +can be dropped if multiple exception types are provided and the ``as`` clause is not used. +The raised exception matches an :keyword:`!except` clause whose expression evaluates +to the class or a :term:`non-virtual base class <abstract base class>` of the exception object, +or to a tuple that contains such a class. + +If no :keyword:`!except` clause matches the exception, +the search for an exception handler +continues in the surrounding code and on the invocation stack. [#]_ + +If the evaluation of an expression +in the header of an :keyword:`!except` clause raises an exception, +the original search for a handler is canceled and a search starts for +the new exception in the surrounding code and on the call stack (it is treated +as if the entire :keyword:`try` statement raised the exception). + +.. index:: single: as; except clause + +When a matching :keyword:`!except` clause is found, +the exception is assigned to the target +specified after the :keyword:`!as` keyword in that :keyword:`!except` clause, +if present, and the :keyword:`!except` clause's suite is executed. +All :keyword:`!except` clauses must have an executable block. +When the end of this block is reached, execution continues +normally after the entire :keyword:`try` statement. +(This means that if two nested handlers exist for the same exception, +and the exception occurs in the :keyword:`!try` clause of the inner handler, +the outer handler will not handle the exception.) + +When an exception has been assigned using ``as target``, it is cleared at the +end of the :keyword:`!except` clause. This is as if:: + + except E as N: + foo + +was translated to:: + + except E as N: + try: + foo + finally: + del N + +This means the exception must be assigned to a different name to be able to +refer to it after the :keyword:`!except` clause. +Exceptions are cleared because with the +traceback attached to them, they form a reference cycle with the stack frame, +keeping all locals in that frame alive until the next garbage collection occurs. + +.. index:: + pair: module; sys + pair: object; traceback + +Before an :keyword:`!except` clause's suite is executed, +the exception is stored in the :mod:`sys` module, where it can be accessed +from within the body of the :keyword:`!except` clause by calling +:func:`sys.exception`. When leaving an exception handler, the exception +stored in the :mod:`sys` module is reset to its previous value:: + + >>> print(sys.exception()) + None + >>> try: + ... raise TypeError + ... except: + ... print(repr(sys.exception())) + ... try: + ... raise ValueError + ... except: + ... print(repr(sys.exception())) + ... print(repr(sys.exception())) + ... + TypeError() + ValueError() + TypeError() + >>> print(sys.exception()) + None + + +.. index:: + pair: keyword; except_star + +.. _except_star: + +:keyword:`!except*` clause +-------------------------- + +The :keyword:`!except*` clause(s) specify one or more handlers for groups of +exceptions (:exc:`BaseExceptionGroup` instances). A :keyword:`try` statement +can have either :keyword:`except` or :keyword:`!except*` clauses, but not both. +The exception type for matching is mandatory in the case of :keyword:`!except*`, +so ``except*:`` is a syntax error. The type is interpreted as in the case of +:keyword:`!except`, but matching is performed on the exceptions contained in the +group that is being handled. A :exc:`TypeError` is raised if a matching +type is a subclass of :exc:`!BaseExceptionGroup`, because that would have +ambiguous semantics. + +When an exception group is raised in the try block, each :keyword:`!except*` +clause splits (see :meth:`~BaseExceptionGroup.split`) it into the subgroups +of matching and non-matching exceptions. If the matching subgroup is not empty, +it becomes the handled exception (the value returned from :func:`sys.exception`) +and assigned to the target of the :keyword:`!except*` clause (if there is one). +Then, the body of the :keyword:`!except*` clause executes. If the non-matching +subgroup is not empty, it is processed by the next :keyword:`!except*` in the +same manner. This continues until all exceptions in the group have been matched, +or the last :keyword:`!except*` clause has run. + +After all :keyword:`!except*` clauses execute, the group of unhandled exceptions +is merged with any exceptions that were raised or re-raised from within +:keyword:`!except*` clauses. This merged exception group propagates on:: + + >>> try: + ... raise ExceptionGroup("eg", + ... [ValueError(1), TypeError(2), OSError(3), OSError(4)]) + ... except* TypeError as e: + ... print(f'caught {type(e)} with nested {e.exceptions}') + ... except* OSError as e: + ... print(f'caught {type(e)} with nested {e.exceptions}') + ... + caught <class 'ExceptionGroup'> with nested (TypeError(2),) + caught <class 'ExceptionGroup'> with nested (OSError(3), OSError(4)) + + Exception Group Traceback (most recent call last): + | File "<doctest default[0]>", line 2, in <module> + | raise ExceptionGroup("eg", + | [ValueError(1), TypeError(2), OSError(3), OSError(4)]) + | ExceptionGroup: eg (1 sub-exception) + +-+---------------- 1 ---------------- + | ValueError: 1 + +------------------------------------ + +If the exception raised from the :keyword:`try` block is not an exception group +and its type matches one of the :keyword:`!except*` clauses, it is caught and +wrapped by an exception group with an empty message string. This ensures that the +type of the target ``e`` is consistently :exc:`BaseExceptionGroup`:: + + >>> try: + ... raise BlockingIOError + ... except* BlockingIOError as e: + ... print(repr(e)) + ... + ExceptionGroup('', (BlockingIOError(),)) + +:keyword:`break`, :keyword:`continue` and :keyword:`return` +cannot appear in an :keyword:`!except*` clause. + + +.. index:: + pair: keyword; else + pair: statement; return + pair: statement; break + pair: statement; continue + +.. _except_else: + +:keyword:`!else` clause +----------------------- + +The optional :keyword:`!else` clause is executed if the control flow leaves the +:keyword:`try` suite, no exception was raised, and no :keyword:`return`, +:keyword:`continue`, or :keyword:`break` statement was executed. Exceptions in +the :keyword:`!else` clause are not handled by the preceding :keyword:`except` +clauses. + + +.. index:: pair: keyword; finally + +.. _finally: + +:keyword:`!finally` clause +-------------------------- + +If :keyword:`!finally` is present, it specifies a 'cleanup' handler. The +:keyword:`try` clause is executed, including any :keyword:`except` +and :keyword:`else <except_else>` clauses. +If an exception occurs in any of the clauses and is not handled, +the exception is temporarily saved. +The :keyword:`!finally` clause is executed. If there is a saved exception +it is re-raised at the end of the :keyword:`!finally` clause. +If the :keyword:`!finally` clause raises another exception, the saved exception +is set as the context of the new exception. +If the :keyword:`!finally` clause executes a :keyword:`return`, :keyword:`break` +or :keyword:`continue` statement, the saved exception is discarded. For example, +this function returns 42. + +.. code-block:: + + def f(): + try: + 1/0 + finally: + return 42 + +The exception information is not available to the program during execution of +the :keyword:`!finally` clause. + +.. index:: + pair: statement; return + pair: statement; break + pair: statement; continue + +When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is +executed in the :keyword:`try` suite of a :keyword:`!try`...\ :keyword:`!finally` +statement, the :keyword:`!finally` clause is also executed 'on the way out.' + +The return value of a function is determined by the last :keyword:`return` +statement executed. Since the :keyword:`!finally` clause always executes, a +:keyword:`!return` statement executed in the :keyword:`!finally` clause will +always be the last one executed. The following function returns 'finally'. + +.. code-block:: + + def foo(): + try: + return 'try' + finally: + return 'finally' + +.. versionchanged:: 3.8 + Prior to Python 3.8, a :keyword:`continue` statement was illegal in the + :keyword:`!finally` clause due to a problem with the implementation. + +.. versionchanged:: 3.14 + The compiler emits a :exc:`SyntaxWarning` when a :keyword:`return`, + :keyword:`break` or :keyword:`continue` appears in a :keyword:`!finally` + block (see :pep:`765`). + + +.. _with: +.. _as: + +The :keyword:`!with` statement +============================== + +.. index:: + ! pair: statement; with + pair: keyword; as + single: as; with statement + single: , (comma); with statement + single: : (colon); compound statement + +The :keyword:`with` statement is used to wrap the execution of a block with +methods defined by a context manager (see section :ref:`context-managers`). +This allows common :keyword:`try`...\ :keyword:`except`...\ :keyword:`finally` +usage patterns to be encapsulated for convenient reuse. + +.. productionlist:: python-grammar + with_stmt: "with" ( "(" `with_stmt_contents` ","? ")" | `with_stmt_contents` ) ":" `suite` + with_stmt_contents: `with_item` ("," `with_item`)* + with_item: `expression` ["as" `target`] + +The execution of the :keyword:`with` statement with one "item" proceeds as follows: + +#. The context expression (the expression given in the + :token:`~python-grammar:with_item`) is evaluated to obtain a context manager. + +#. The context manager's :meth:`~object.__enter__` is loaded for later use. + +#. The context manager's :meth:`~object.__exit__` is loaded for later use. + +#. The context manager's :meth:`~object.__enter__` method is invoked. + +#. If a target was included in the :keyword:`with` statement, the return value + from :meth:`~object.__enter__` is assigned to it. + + .. note:: + + The :keyword:`with` statement guarantees that if the :meth:`~object.__enter__` + method returns without an error, then :meth:`~object.__exit__` will always be + called. Thus, if an error occurs during the assignment to the target list, + it will be treated the same as an error occurring within the suite would + be. See step 7 below. + +#. The suite is executed. + +#. The context manager's :meth:`~object.__exit__` method is invoked. If an exception + caused the suite to be exited, its type, value, and traceback are passed as + arguments to :meth:`~object.__exit__`. Otherwise, three :const:`None` arguments are + supplied. + + If the suite was exited due to an exception, and the return value from the + :meth:`~object.__exit__` method was false, the exception is reraised. If the return + value was true, the exception is suppressed, and execution continues with the + statement following the :keyword:`with` statement. + + If the suite was exited for any reason other than an exception, the return + value from :meth:`~object.__exit__` is ignored, and execution proceeds at the normal + location for the kind of exit that was taken. + +The following code:: + + with EXPRESSION as TARGET: + SUITE + +is semantically equivalent to:: + + manager = (EXPRESSION) + enter = manager.__enter__ + exit = manager.__exit__ + value = enter() + hit_except = False + + try: + TARGET = value + SUITE + except: + hit_except = True + if not exit(*sys.exc_info()): + raise + finally: + if not hit_except: + exit(None, None, None) + +except that implicit :ref:`special method lookup <special-lookup>` is used +for :meth:`~object.__enter__` and :meth:`~object.__exit__`. + +With more than one item, the context managers are processed as if multiple +:keyword:`with` statements were nested:: + + with A() as a, B() as b: + SUITE + +is semantically equivalent to:: + + with A() as a: + with B() as b: + SUITE + +You can also write multi-item context managers in multiple lines if +the items are surrounded by parentheses. For example:: + + with ( + A() as a, + B() as b, + ): + SUITE + +.. versionchanged:: 3.1 + Support for multiple context expressions. + +.. versionchanged:: 3.10 + Support for using grouping parentheses to break the statement in multiple lines. + +.. seealso:: + + :pep:`343` - The "with" statement + The specification, background, and examples for the Python :keyword:`with` + statement. + +.. _match: +.. _case: + +The :keyword:`!match` statement +=============================== + +.. index:: + ! pair: statement; match + ! pair: keyword; case + ! single: pattern matching + pair: keyword; if + pair: keyword; as + pair: match; case + single: as; match statement + single: : (colon); compound statement + +.. versionadded:: 3.10 + +The match statement is used for pattern matching. Syntax: + +.. productionlist:: python-grammar + match_stmt: 'match' `subject_expr` ":" NEWLINE INDENT `case_block`+ DEDENT + subject_expr: `flexible_expression` "," [`flexible_expression_list` [',']] + : | `assignment_expression` + case_block: 'case' `patterns` [`guard`] ":" `suite` + +.. note:: + This section uses single quotes to denote + :ref:`soft keywords <soft-keywords>`. + +Pattern matching takes a pattern as input (following ``case``) and a subject +value (following ``match``). The pattern (which may contain subpatterns) is +matched against the subject value. The outcomes are: + +* A match success or failure (also termed a pattern success or failure). + +* Possible binding of matched values to a name. The prerequisites for this are + further discussed below. + +The ``match`` and ``case`` keywords are :ref:`soft keywords <soft-keywords>`. + +.. seealso:: + + * :pep:`634` -- Structural Pattern Matching: Specification + * :pep:`636` -- Structural Pattern Matching: Tutorial + + +Overview +-------- + +Here's an overview of the logical flow of a match statement: + + +#. The subject expression ``subject_expr`` is evaluated and a resulting subject + value obtained. If the subject expression contains a comma, a tuple is + constructed using :ref:`the standard rules <typesseq-tuple>`. + +#. Each pattern in a ``case_block`` is attempted to match with the subject value. The + specific rules for success or failure are described below. The match attempt can also + bind some or all of the standalone names within the pattern. The precise + pattern binding rules vary per pattern type and are + specified below. **Name bindings made during a successful pattern match + outlive the executed block and can be used after the match statement**. + + .. note:: + + During failed pattern matches, some subpatterns may succeed. Do not + rely on bindings being made for a failed match. Conversely, do not + rely on variables remaining unchanged after a failed match. The exact + behavior is dependent on implementation and may vary. This is an + intentional decision made to allow different implementations to add + optimizations. + +#. If the pattern succeeds, the corresponding guard (if present) is evaluated. In + this case all name bindings are guaranteed to have happened. + + * If the guard evaluates as true or is missing, the ``block`` inside + ``case_block`` is executed. + + * Otherwise, the next ``case_block`` is attempted as described above. + + * If there are no further case blocks, the match statement is completed. + +.. note:: + + Users should generally never rely on a pattern being evaluated. Depending on + implementation, the interpreter may cache values or use other optimizations + which skip repeated evaluations. + +A sample match statement:: + + >>> flag = False + >>> match (100, 200): + ... case (100, 300): # Mismatch: 200 != 300 + ... print('Case 1') + ... case (100, 200) if flag: # Successful match, but guard fails + ... print('Case 2') + ... case (100, y): # Matches and binds y to 200 + ... print(f'Case 3, y: {y}') + ... case _: # Pattern not attempted + ... print('Case 4, I match anything!') + ... + Case 3, y: 200 + + +In this case, ``if flag`` is a guard. Read more about that in the next section. + +Guards +------ + +.. index:: ! guard + +.. productionlist:: python-grammar + guard: "if" `assignment_expression` + +A ``guard`` (which is part of the ``case``) must succeed for code inside +the ``case`` block to execute. It takes the form: :keyword:`if` followed by an +expression. + + +The logical flow of a ``case`` block with a ``guard`` follows: + +#. Check that the pattern in the ``case`` block succeeded. If the pattern + failed, the ``guard`` is not evaluated and the next ``case`` block is + checked. + +#. If the pattern succeeded, evaluate the ``guard``. + + * If the ``guard`` condition evaluates as true, the case block is + selected. + + * If the ``guard`` condition evaluates as false, the case block is not + selected. + + * If the ``guard`` raises an exception during evaluation, the exception + bubbles up. + +Guards are allowed to have side effects as they are expressions. Guard +evaluation must proceed from the first to the last case block, one at a time, +skipping case blocks whose pattern(s) don't all succeed. (I.e., +guard evaluation must happen in order.) Guard evaluation must stop once a case +block is selected. + + +.. _irrefutable_case: + +Irrefutable Case Blocks +----------------------- + +.. index:: irrefutable case block, case block + +An irrefutable case block is a match-all case block. A match statement may have +at most one irrefutable case block, and it must be last. + +A case block is considered irrefutable if it has no guard and its pattern is +irrefutable. A pattern is considered irrefutable if we can prove from its +syntax alone that it will always succeed. Only the following patterns are +irrefutable: + +* :ref:`as-patterns` whose left-hand side is irrefutable + +* :ref:`or-patterns` containing at least one irrefutable pattern + +* :ref:`capture-patterns` + +* :ref:`wildcard-patterns` + +* parenthesized irrefutable patterns + + +Patterns +-------- + +.. index:: + single: ! patterns + single: AS pattern, OR pattern, capture pattern, wildcard pattern + +.. note:: + This section uses grammar notations beyond standard EBNF: + + * the notation ``SEP.RULE+`` is shorthand for ``RULE (SEP RULE)*`` + + * the notation ``!RULE`` is shorthand for a negative lookahead assertion + + +The top-level syntax for ``patterns`` is: + +.. productionlist:: python-grammar + patterns: `open_sequence_pattern` | `pattern` + pattern: `as_pattern` | `or_pattern` + closed_pattern: | `literal_pattern` + : | `capture_pattern` + : | `wildcard_pattern` + : | `value_pattern` + : | `group_pattern` + : | `sequence_pattern` + : | `mapping_pattern` + : | `class_pattern` + +The descriptions below will include a description "in simple terms" of what a pattern +does for illustration purposes (credits to Raymond Hettinger for a document that +inspired most of the descriptions). Note that these descriptions are purely for +illustration purposes and **may not** reflect +the underlying implementation. Furthermore, they do not cover all valid forms. + + +.. _or-patterns: + +OR Patterns +^^^^^^^^^^^ + +An OR pattern is two or more patterns separated by vertical +bars ``|``. Syntax: + +.. productionlist:: python-grammar + or_pattern: "|".`closed_pattern`+ + +Only the final subpattern may be :ref:`irrefutable <irrefutable_case>`, and each +subpattern must bind the same set of names to avoid ambiguity. + +An OR pattern matches each of its subpatterns in turn to the subject value, +until one succeeds. The OR pattern is then considered successful. Otherwise, +if none of the subpatterns succeed, the OR pattern fails. + +In simple terms, ``P1 | P2 | ...`` will try to match ``P1``, if it fails it will try to +match ``P2``, succeeding immediately if any succeeds, failing otherwise. + +.. _as-patterns: + +AS Patterns +^^^^^^^^^^^ + +An AS pattern matches an OR pattern on the left of the :keyword:`as` +keyword against a subject. Syntax: + +.. productionlist:: python-grammar + as_pattern: `or_pattern` "as" `capture_pattern` + +If the OR pattern fails, the AS pattern fails. Otherwise, the AS pattern binds +the subject to the name on the right of the as keyword and succeeds. +``capture_pattern`` cannot be a ``_``. + +In simple terms ``P as NAME`` will match with ``P``, and on success it will +set ``NAME = <subject>``. + + +.. _literal-patterns: + +Literal Patterns +^^^^^^^^^^^^^^^^ + +A literal pattern corresponds to most +:ref:`literals <literals>` in Python. Syntax: + +.. productionlist:: python-grammar + literal_pattern: `signed_number` + : | `signed_number` "+" NUMBER + : | `signed_number` "-" NUMBER + : | `strings` + : | "None" + : | "True" + : | "False" + signed_number: ["+" | "-"] NUMBER + +The rule ``strings`` and the token ``NUMBER`` are defined in the +:doc:`standard Python grammar <./grammar>`. Triple-quoted strings are +supported. Raw strings and byte strings are supported. :ref:`f-strings` +and :ref:`t-strings` are not supported. + +The forms ``signed_number '+' NUMBER`` and ``signed_number '-' NUMBER`` are +for expressing :ref:`complex numbers <imaginary>`; they require a real number +on the left and an imaginary number on the right. E.g. ``3 + 4j``. + +In simple terms, ``LITERAL`` will succeed only if ``<subject> == LITERAL``. For +the singletons ``None``, ``True`` and ``False``, the :keyword:`is` operator is used. + +.. _capture-patterns: + +Capture Patterns +^^^^^^^^^^^^^^^^ + +A capture pattern binds the subject value to a name. +Syntax: + +.. productionlist:: python-grammar + capture_pattern: !'_' NAME + +A single underscore ``_`` is not a capture pattern (this is what ``!'_'`` +expresses). It is instead treated as a +:token:`~python-grammar:wildcard_pattern`. + +In a given pattern, a given name can only be bound once. E.g. +``case x, x: ...`` is invalid while ``case [x] | x: ...`` is allowed. + +Capture patterns always succeed. The binding follows scoping rules +established by the assignment expression operator in :pep:`572`; the +name becomes a local variable in the closest containing function scope unless +there's an applicable :keyword:`global` or :keyword:`nonlocal` statement. + +In simple terms ``NAME`` will always succeed and it will set ``NAME = <subject>``. + +.. _wildcard-patterns: + +Wildcard Patterns +^^^^^^^^^^^^^^^^^ + +A wildcard pattern always succeeds (matches anything) +and binds no name. Syntax: + +.. productionlist:: python-grammar + wildcard_pattern: '_' + +``_`` is a :ref:`soft keyword <soft-keywords>` within any pattern, +but only within patterns. It is an identifier, as usual, even within +``match`` subject expressions, ``guard``\ s, and ``case`` blocks. + +In simple terms, ``_`` will always succeed. + +.. _value-patterns: + +Value Patterns +^^^^^^^^^^^^^^ + +A value pattern represents a named value in Python. +Syntax: + +.. productionlist:: python-grammar + value_pattern: `attr` + attr: `name_or_attr` "." NAME + name_or_attr: `attr` | NAME + +The dotted name in the pattern is looked up using standard Python +:ref:`name resolution rules <resolve_names>`. The pattern succeeds if the +value found compares equal to the subject value (using the ``==`` equality +operator). + +In simple terms ``NAME1.NAME2`` will succeed only if ``<subject> == NAME1.NAME2`` + +.. note:: + + If the same value occurs multiple times in the same match statement, the + interpreter may cache the first value found and reuse it rather than repeat + the same lookup. This cache is strictly tied to a given execution of a + given match statement. + +.. _group-patterns: + +Group Patterns +^^^^^^^^^^^^^^ + +A group pattern allows users to add parentheses around patterns to +emphasize the intended grouping. Otherwise, it has no additional syntax. +Syntax: + +.. productionlist:: python-grammar + group_pattern: "(" `pattern` ")" + +In simple terms ``(P)`` has the same effect as ``P``. + +.. _sequence-patterns: + +Sequence Patterns +^^^^^^^^^^^^^^^^^ + +A sequence pattern contains several subpatterns to be matched against sequence elements. +The syntax is similar to the unpacking of a list or tuple. + +.. productionlist:: python-grammar + sequence_pattern: "[" [`maybe_sequence_pattern`] "]" + : | "(" [`open_sequence_pattern`] ")" + open_sequence_pattern: `maybe_star_pattern` "," [`maybe_sequence_pattern`] + maybe_sequence_pattern: ",".`maybe_star_pattern`+ ","? + maybe_star_pattern: `star_pattern` | `pattern` + star_pattern: "*" (`capture_pattern` | `wildcard_pattern`) + +There is no difference if parentheses or square brackets +are used for sequence patterns (i.e. ``(...)`` vs ``[...]`` ). + +.. note:: + A single pattern enclosed in parentheses without a trailing comma + (e.g. ``(3 | 4)``) is a :ref:`group pattern <group-patterns>`. + While a single pattern enclosed in square brackets (e.g. ``[3 | 4]``) is + still a sequence pattern. + +At most one star subpattern may be in a sequence pattern. The star subpattern +may occur in any position. If no star subpattern is present, the sequence +pattern is a fixed-length sequence pattern; otherwise it is a variable-length +sequence pattern. + +The following is the logical flow for matching a sequence pattern against a +subject value: + +#. If the subject value is not a sequence [#]_, the sequence pattern + fails. + +#. If the subject value is an instance of ``str``, ``bytes`` or ``bytearray`` + the sequence pattern fails. + +#. The subsequent steps depend on whether the sequence pattern is fixed or + variable-length. + + If the sequence pattern is fixed-length: + + #. If the length of the subject sequence is not equal to the number of + subpatterns, the sequence pattern fails + + #. Subpatterns in the sequence pattern are matched to their corresponding + items in the subject sequence from left to right. Matching stops as soon + as a subpattern fails. If all subpatterns succeed in matching their + corresponding item, the sequence pattern succeeds. + + Otherwise, if the sequence pattern is variable-length: + + #. If the length of the subject sequence is less than the number of non-star + subpatterns, the sequence pattern fails. + + #. The leading non-star subpatterns are matched to their corresponding items + as for fixed-length sequences. + + #. If the previous step succeeds, the star subpattern matches a list formed + of the remaining subject items, excluding the remaining items + corresponding to non-star subpatterns following the star subpattern. + + #. Remaining non-star subpatterns are matched to their corresponding subject + items, as for a fixed-length sequence. + + .. note:: The length of the subject sequence is obtained via + :func:`len` (i.e. via the :meth:`~object.__len__` protocol). + This length may be cached by the interpreter in a similar manner as + :ref:`value patterns <value-patterns>`. + + +In simple terms ``[P1, P2, P3,`` ... ``, P<N>]`` matches only if all the following +happens: + +* check ``<subject>`` is a sequence +* ``len(subject) == <N>`` +* ``P1`` matches ``<subject>[0]`` (note that this match can also bind names) +* ``P2`` matches ``<subject>[1]`` (note that this match can also bind names) +* ... and so on for the corresponding pattern/element. + +.. _mapping-patterns: + +Mapping Patterns +^^^^^^^^^^^^^^^^ + +A mapping pattern contains one or more key-value patterns. The syntax is +similar to the construction of a dictionary. +Syntax: + +.. productionlist:: python-grammar + mapping_pattern: "{" [`items_pattern`] "}" + items_pattern: ",".`key_value_pattern`+ ","? + key_value_pattern: (`literal_pattern` | `value_pattern`) ":" `pattern` + : | `double_star_pattern` + double_star_pattern: "**" `capture_pattern` + +At most one double star pattern may be in a mapping pattern. The double star +pattern must be the last subpattern in the mapping pattern. + +Duplicate keys in mapping patterns are disallowed. Duplicate literal keys will +raise a :exc:`SyntaxError`. Two keys that otherwise have the same value will +raise a :exc:`ValueError` at runtime. + +The following is the logical flow for matching a mapping pattern against a +subject value: + +#. If the subject value is not a mapping [#]_,the mapping pattern fails. + +#. If every key given in the mapping pattern is present in the subject mapping, + and the pattern for each key matches the corresponding item of the subject + mapping, the mapping pattern succeeds. + +#. If duplicate keys are detected in the mapping pattern, the pattern is + considered invalid. A :exc:`SyntaxError` is raised for duplicate literal + values; or a :exc:`ValueError` for named keys of the same value. + +.. note:: Key-value pairs are matched using the two-argument form of the mapping + subject's ``get()`` method. Matched key-value pairs must already be present + in the mapping, and not created on-the-fly via :meth:`~object.__missing__` + or :meth:`~object.__getitem__`. + +In simple terms ``{KEY1: P1, KEY2: P2, ... }`` matches only if all the following +happens: + +* check ``<subject>`` is a mapping +* ``KEY1 in <subject>`` +* ``P1`` matches ``<subject>[KEY1]`` +* ... and so on for the corresponding KEY/pattern pair. + + +.. _class-patterns: + +Class Patterns +^^^^^^^^^^^^^^ + +A class pattern represents a class and its positional and keyword arguments +(if any). Syntax: + +.. productionlist:: python-grammar + class_pattern: `name_or_attr` "(" [`pattern_arguments` ","?] ")" + pattern_arguments: `positional_patterns` ["," `keyword_patterns`] + : | `keyword_patterns` + positional_patterns: ",".`pattern`+ + keyword_patterns: ",".`keyword_pattern`+ + keyword_pattern: NAME "=" `pattern` + +The same keyword should not be repeated in class patterns. + +The following is the logical flow for matching a class pattern against a +subject value: + +#. If ``name_or_attr`` is not an instance of the builtin :class:`type` , raise + :exc:`TypeError`. + +#. If the subject value is not an instance of ``name_or_attr`` (tested via + :func:`isinstance`), the class pattern fails. + +#. If no pattern arguments are present, the pattern succeeds. Otherwise, + the subsequent steps depend on whether keyword or positional argument patterns + are present. + + For a number of built-in types (specified below), a single positional + subpattern is accepted which will match the entire subject; for these types + keyword patterns also work as for other types. + + If only keyword patterns are present, they are processed as follows, + one by one: + + I. The keyword is looked up as an attribute on the subject. + + * If this raises an exception other than :exc:`AttributeError`, the + exception bubbles up. + + * If this raises :exc:`AttributeError`, the class pattern has failed. + + * Else, the subpattern associated with the keyword pattern is matched + against the subject's attribute value. If this fails, the class + pattern fails; if this succeeds, the match proceeds to the next keyword. + + + II. If all keyword patterns succeed, the class pattern succeeds. + + If any positional patterns are present, they are converted to keyword + patterns using the :data:`~object.__match_args__` attribute on the class + ``name_or_attr`` before matching: + + I. The equivalent of ``getattr(cls, "__match_args__", ())`` is called. + + * If this raises an exception, the exception bubbles up. + + * If the returned value is not a tuple, the conversion fails and + :exc:`TypeError` is raised. + + * If there are more positional patterns than ``len(cls.__match_args__)``, + :exc:`TypeError` is raised. + + * Otherwise, positional pattern ``i`` is converted to a keyword pattern + using ``__match_args__[i]`` as the keyword. ``__match_args__[i]`` must + be a string; if not :exc:`TypeError` is raised. + + * If there are duplicate keywords, :exc:`TypeError` is raised. + + .. seealso:: :ref:`class-pattern-matching` + + II. Once all positional patterns have been converted to keyword patterns, + the match proceeds as if there were only keyword patterns. + + For the following built-in types the handling of positional subpatterns is + different: + + * :class:`bool` + * :class:`bytearray` + * :class:`bytes` + * :class:`dict` + * :class:`float` + * :class:`frozendict` + * :class:`frozenset` + * :class:`int` + * :class:`list` + * :class:`set` + * :class:`str` + * :class:`tuple` + + These classes accept a single positional argument, and the pattern there is matched + against the whole object rather than an attribute. For example ``int(0|1)`` matches + the value ``0``, but not the value ``0.0``. + +In simple terms ``CLS(P1, attr=P2)`` matches only if the following happens: + +* ``isinstance(<subject>, CLS)`` +* convert ``P1`` to a keyword pattern using ``CLS.__match_args__`` +* For each keyword argument ``attr=P2``: + + * ``hasattr(<subject>, "attr")`` + * ``P2`` matches ``<subject>.attr`` + +* ... and so on for the corresponding keyword argument/pattern pair. + +.. seealso:: + + * :pep:`634` -- Structural Pattern Matching: Specification + * :pep:`636` -- Structural Pattern Matching: Tutorial + + +.. index:: + single: parameter; function definition + +.. _function: +.. _def: + +Function definitions +==================== + +.. index:: + pair: statement; def + pair: function; definition + pair: function; name + pair: name; binding + pair: object; user-defined function + pair: object; function + pair: function; name + pair: name; binding + single: () (parentheses); function definition + single: , (comma); parameter list + single: : (colon); compound statement + +A function definition defines a user-defined function object (see section +:ref:`types`): + +.. productionlist:: python-grammar + funcdef: [`decorators`] "def" `funcname` [`type_params`] "(" [`parameter_list`] ")" + : ["->" `expression`] ":" `suite` + decorators: `decorator`+ + decorator: "@" `assignment_expression` NEWLINE + parameter_list: `defparameter` ("," `defparameter`)* "," "/" ["," [`parameter_list_no_posonly`]] + : | `parameter_list_no_posonly` + parameter_list_no_posonly: `defparameter` ("," `defparameter`)* ["," [`parameter_list_starargs`]] + : | `parameter_list_starargs` + parameter_list_starargs: "*" `star_parameter` ("," `defparameter`)* ["," [`parameter_star_kwargs`]] + : | "*" ("," `defparameter`)+ ["," [`parameter_star_kwargs`]] + : | `parameter_star_kwargs` + parameter_star_kwargs: "**" `parameter` [","] + parameter: `identifier` [":" `expression`] + star_parameter: `identifier` [":" ["*"] `expression`] + defparameter: `parameter` ["=" `expression`] + funcname: `identifier` + + +A function definition is an executable statement. Its execution binds the +function name in the current local namespace to a function object (a wrapper +around the executable code for the function). This function object contains a +reference to the current global namespace as the global namespace to be used +when the function is called. + +The function definition does not execute the function body; this gets executed +only when the function is called. [#]_ + +.. index:: + single: @ (at); function definition + +A function definition may be wrapped by one or more :term:`decorator` expressions. +Decorator expressions are evaluated when the function is defined, in the scope +that contains the function definition. The result must be a callable, which is +invoked with the function object as the only argument. The returned value is +bound to the function name instead of the function object. Multiple decorators +are applied in nested fashion. For example, the following code :: + + @f1(arg) + @f2 + def func(): pass + +is roughly equivalent to :: + + def func(): pass + func = f1(arg)(f2(func)) + +except that the original function is not temporarily bound to the name ``func``. + +.. versionchanged:: 3.9 + Functions may be decorated with any valid + :token:`~python-grammar:assignment_expression`. Previously, the grammar was + much more restrictive; see :pep:`614` for details. + +A list of :ref:`type parameters <type-params>` may be given in square brackets +between the function's name and the opening parenthesis for its parameter list. +This indicates to static type checkers that the function is generic. At runtime, +the type parameters can be retrieved from the function's +:attr:`~function.__type_params__` +attribute. See :ref:`generic-functions` for more. + +.. versionchanged:: 3.12 + Type parameter lists are new in Python 3.12. + +.. index:: + triple: default; parameter; value + single: argument; function definition + single: = (equals); function definition + +When one or more :term:`parameters <parameter>` have the form *parameter* ``=`` +*expression*, the function is said to have "default parameter values." For a +parameter with a default value, the corresponding :term:`argument` may be +omitted from a call, in which +case the parameter's default value is substituted. If a parameter has a default +value, all following parameters up until the "``*``" must also have a default +value --- this is a syntactic restriction that is not expressed by the grammar. + +**Default parameter values are evaluated from left to right when the function +definition is executed.** This means that the expression is evaluated once, when +the function is defined, and that the same "pre-computed" value is used for each +call. This is especially important to understand when a default parameter value is a +mutable object, such as a list or a dictionary: if the function modifies the +object (e.g. by appending an item to a list), the default parameter value is in effect +modified. This is generally not what was intended. A way around this is to use +``None`` as the default, and explicitly test for it in the body of the function, +for example:: + + def whats_on_the_telly(penguin=None): + if penguin is None: + penguin = [] + penguin.append("property of the zoo") + return penguin + +.. index:: + single: / (slash); function definition + single: * (asterisk); function definition + single: **; function definition + +Function call semantics are described in more detail in section :ref:`calls`. A +function call always assigns values to all parameters mentioned in the parameter +list, either from positional arguments, from keyword arguments, or from default +values. If the form "``*identifier``" is present, it is initialized to a tuple +receiving any excess positional parameters, defaulting to the empty tuple. +If the form "``**identifier``" is present, it is initialized to a new +ordered mapping receiving any excess keyword arguments, defaulting to a +new empty mapping of the same type. Parameters after "``*``" or +"``*identifier``" are keyword-only parameters and may only be passed +by keyword arguments. Parameters before "``/``" are positional-only parameters +and may only be passed by positional arguments. + +.. versionchanged:: 3.8 + The ``/`` function parameter syntax may be used to indicate positional-only + parameters. See :pep:`570` for details. + +.. index:: + pair: function; annotations + single: ->; function annotations + single: : (colon); function annotations + +Parameters may have an :term:`annotation <function annotation>` of the form "``: expression``" +following the parameter name. Any parameter may have an annotation, even those of the form +``*identifier`` or ``**identifier``. (As a special case, parameters of the form +``*identifier`` may have an annotation "``: *expression``".) Functions may have "return" annotation of +the form "``-> expression``" after the parameter list. These annotations can be +any valid Python expression. The presence of annotations does not change the +semantics of a function. See :ref:`annotations` for more information on annotations. + +.. versionchanged:: 3.11 + Parameters of the form "``*identifier``" may have an annotation + "``: *expression``". See :pep:`646`. + +.. index:: pair: lambda; expression + +It is also possible to create anonymous functions (functions not bound to a +name), for immediate use in expressions. This uses lambda expressions, described in +section :ref:`lambda`. Note that the lambda expression is merely a shorthand for a +simplified function definition; a function defined in a ":keyword:`def`" +statement can be passed around or assigned to another name just like a function +defined by a lambda expression. The ":keyword:`!def`" form is actually more powerful +since it allows the execution of multiple statements and annotations. + +**Programmer's note:** Functions are first-class objects. A "``def``" statement +executed inside a function definition defines a local function that can be +returned or passed around. Free variables used in the nested function can +access the local variables of the function containing the def. See section +:ref:`naming` for details. + +.. seealso:: + + :pep:`3107` - Function Annotations + The original specification for function annotations. + + :pep:`484` - Type Hints + Definition of a standard meaning for annotations: type hints. + + :pep:`526` - Syntax for Variable Annotations + Ability to type hint variable declarations, including class + variables and instance variables. + + :pep:`563` - Postponed Evaluation of Annotations + Support for forward references within annotations by preserving + annotations in a string form at runtime instead of eager evaluation. + + :pep:`318` - Decorators for Functions and Methods + Function and method decorators were introduced. + Class decorators were introduced in :pep:`3129`. + +.. _class: + +Class definitions +================= + +.. index:: + pair: object; class + pair: statement; class + pair: class; definition + pair: class; name + pair: name; binding + pair: execution; frame + single: inheritance + single: docstring + single: () (parentheses); class definition + single: , (comma); expression list + single: : (colon); compound statement + +A class definition defines a class object (see section :ref:`types`): + +.. productionlist:: python-grammar + classdef: [`decorators`] "class" `classname` [`type_params`] [`inheritance`] ":" `suite` + inheritance: "(" [`argument_list`] ")" + classname: `identifier` + +A class definition is an executable statement. The inheritance list usually +gives a list of base classes (see :ref:`metaclasses` for more advanced uses), so +each item in the list should evaluate to a class object which allows +subclassing. Classes without an inheritance list inherit, by default, from the +base class :class:`object`; hence, :: + + class Foo: + pass + +is equivalent to :: + + class Foo(object): + pass + +There may be one or more base classes; see :ref:`multiple-inheritance` below for more +information. + +The class's suite is then executed in a new execution frame (see :ref:`naming`), +using a newly created local namespace and the original global namespace. +(Usually, the suite contains mostly function definitions.) When the class's +suite finishes execution, its execution frame is discarded but its local +namespace is saved. [#]_ A class object is then created using the inheritance +list for the base classes and the saved local namespace for the attribute +dictionary. The class name is bound to this class object in the original local +namespace. + +The order in which attributes are defined in the class body is preserved +in the new class's :attr:`~type.__dict__`. Note that this is reliable only right +after the class is created and only for classes that were defined using +the definition syntax. + +Class creation can be customized heavily using :ref:`metaclasses <metaclasses>`. + +.. index:: + single: @ (at); class definition + +Classes can also be decorated: just like when decorating functions, :: + + @f1(arg) + @f2 + class Foo: pass + +is roughly equivalent to :: + + class Foo: pass + Foo = f1(arg)(f2(Foo)) + +The evaluation rules for the decorator expressions are the same as for function +decorators. The result is then bound to the class name. + +.. versionchanged:: 3.9 + Classes may be decorated with any valid + :token:`~python-grammar:assignment_expression`. Previously, the grammar was + much more restrictive; see :pep:`614` for details. + +A list of :ref:`type parameters <type-params>` may be given in square brackets +immediately after the class's name. +This indicates to static type checkers that the class is generic. At runtime, +the type parameters can be retrieved from the class's +:attr:`~type.__type_params__` attribute. See :ref:`generic-classes` for more. + +.. versionchanged:: 3.12 + Type parameter lists are new in Python 3.12. + +**Programmer's note:** Variables defined in the class definition are class +attributes; they are shared by instances. Instance attributes can be set in a +method with ``self.name = value``. Both class and instance attributes are +accessible through the notation "``self.name``", and an instance attribute hides +a class attribute with the same name when accessed in this way. Class +attributes can be used as defaults for instance attributes, but using mutable +values there can lead to unexpected results. :ref:`Descriptors <descriptors>` +can be used to create instance variables with different implementation details. + + +.. seealso:: + + :pep:`3115` - Metaclasses in Python 3000 + The proposal that changed the declaration of metaclasses to the current + syntax, and the semantics for how classes with metaclasses are + constructed. + + :pep:`3129` - Class Decorators + The proposal that added class decorators. Function and method decorators + were introduced in :pep:`318`. + + +.. _multiple-inheritance: + +Multiple inheritance +-------------------- + +Python classes may have multiple base classes, a technique known as +*multiple inheritance*. The base classes are specified in the class definition +by listing them in parentheses after the class name, separated by commas. +For example, the following class definition: + +.. doctest:: + + >>> class A: pass + >>> class B: pass + >>> class C(A, B): pass + +defines a class ``C`` that inherits from classes ``A`` and ``B``. + +The :term:`method resolution order` (MRO) is the order in which base classes are +searched when looking up an attribute on a class. See :ref:`python_2.3_mro` for a +description of how Python determines the MRO for a class. + +Multiple inheritance is not always allowed. Attempting to define a class with multiple +inheritance will raise an error if one of the bases does not allow subclassing, if a consistent MRO +cannot be created, if no valid metaclass can be determined, or if there is an instance +layout conflict. We'll discuss each of these in turn. + +First, all base classes must allow subclassing. While most classes allow subclassing, +some built-in classes do not, such as :class:`bool`: + +.. doctest:: + + >>> class SubBool(bool): # TypeError + ... pass + Traceback (most recent call last): + ... + TypeError: type 'bool' is not an acceptable base type + +In the resolved MRO of a class, the class's bases appear in the order they were +specified in the class's bases list. Additionally, the MRO always lists a child +class before any of its bases. A class definition will fail if it is impossible to +resolve a consistent MRO that satisfies these rules from the list of bases provided: + +.. doctest:: + + >>> class Base: pass + >>> class Child(Base): pass + >>> class Grandchild(Base, Child): pass # TypeError + Traceback (most recent call last): + ... + TypeError: Cannot create a consistent method resolution order (MRO) for bases Base, Child + +In the MRO of ``Grandchild``, ``Base`` must appear before ``Child`` because it is first +in the base class list, but it must also appear after ``Child`` because it is a parent of +``Child``. This is a contradiction, so the class cannot be defined. + +If some of the bases have a custom :term:`metaclass`, the metaclass of the resulting class +is chosen among the metaclasses of the bases and the explicitly specified metaclass of the +child class. It must be a metaclass that is a subclass of +all other candidate metaclasses. If no such metaclass exists among the candidates, +the class cannot be created, as explained in :ref:`metaclass-determination`. + +Finally, the instance layouts of the bases must be compatible. This means that it must be +possible to compute a *solid base* for the class. Exactly which classes are solid bases +depends on the Python implementation. + +.. impl-detail:: + + In CPython, a class is a solid base if it has a + nonempty :attr:`~object.__slots__` definition. + Many but not all classes defined in C are also solid bases, including most + builtins (such as :class:`int` or :class:`BaseException`) + but excluding most concrete :class:`Exception` classes. Generally, a C class + is a solid base if its underlying struct is different in size from its base class. + +Every class has a solid base. :class:`object`, the base class, has itself as its solid base. +If there is a single base, the child class's solid base is that class if it is a solid base, +or else the base class's solid base. If there are multiple bases, we first find the solid base +for each base class to produce a list of candidate solid bases. If there is a unique solid base +that is a subclass of all others, then that class is the solid base. Otherwise, class creation +fails. + +Example: + +.. doctest:: + + >>> class Solid1: + ... __slots__ = ("solid1",) + >>> + >>> class Solid2: + ... __slots__ = ("solid2",) + >>> + >>> class SolidChild(Solid1): + ... __slots__ = ("solid_child",) + >>> + >>> class C1: # solid base is `object` + ... pass + >>> + >>> # OK: solid bases are `Solid1` and `object`, and `Solid1` is a subclass of `object`. + >>> class C2(Solid1, C1): # solid base is `Solid1` + ... pass + >>> + >>> # OK: solid bases are `SolidChild` and `Solid1`, and `SolidChild` is a subclass of `Solid1`. + >>> class C3(SolidChild, Solid1): # solid base is `SolidChild` + ... pass + >>> + >>> # Error: solid bases are `Solid1` and `Solid2`, but neither is a subclass of the other. + >>> class C4(Solid1, Solid2): # error: no single solid base + ... pass + Traceback (most recent call last): + ... + TypeError: multiple bases have instance lay-out conflict + +.. _async: + +Coroutines +========== + +.. versionadded:: 3.5 + +.. index:: pair: statement; async def +.. _`async def`: + +Coroutine function definition +----------------------------- + +.. productionlist:: python-grammar + async_funcdef: [`decorators`] "async" "def" `funcname` "(" [`parameter_list`] ")" + : ["->" `expression`] ":" `suite` + +.. index:: + pair: keyword; async + pair: keyword; await + +Execution of Python coroutines can be suspended and resumed at many points +(see :term:`coroutine`). :keyword:`await` expressions, :keyword:`async for` and +:keyword:`async with` can only be used in the body of a coroutine function. + +Functions defined with ``async def`` syntax are always coroutine functions, +even if they do not contain ``await`` or ``async`` keywords. + +It is a :exc:`SyntaxError` to use a ``yield from`` expression inside the body +of a coroutine function. + +An example of a coroutine function:: + + async def func(param1, param2): + do_stuff() + await some_coroutine() + +.. versionchanged:: 3.7 + ``await`` and ``async`` are now keywords; previously they were only + treated as such inside the body of a coroutine function. + +.. index:: pair: statement; async for +.. _`async for`: + +The :keyword:`!async for` statement +----------------------------------- + +.. productionlist:: python-grammar + async_for_stmt: "async" `for_stmt` + +An :term:`asynchronous iterable` provides an ``__aiter__`` method that directly +returns an :term:`asynchronous iterator`, which can call asynchronous code in +its ``__anext__`` method. + +The ``async for`` statement allows convenient iteration over asynchronous +iterables. + +The following code:: + + async for TARGET in ITER: + SUITE + else: + SUITE2 + +Is semantically equivalent to:: + + iter = (ITER).__aiter__() + running = True + + while running: + try: + TARGET = await iter.__anext__() + except StopAsyncIteration: + running = False + else: + SUITE + else: + SUITE2 + +except that implicit :ref:`special method lookup <special-lookup>` is used +for :meth:`~object.__aiter__` and :meth:`~object.__anext__`. + +It is a :exc:`SyntaxError` to use an ``async for`` statement outside the +body of a coroutine function. + + +.. index:: pair: statement; async with +.. _`async with`: + +The :keyword:`!async with` statement +------------------------------------ + +.. productionlist:: python-grammar + async_with_stmt: "async" `with_stmt` + +An :term:`asynchronous context manager` is a :term:`context manager` that is +able to suspend execution in its *enter* and *exit* methods. + +The following code:: + + async with EXPRESSION as TARGET: + SUITE + +is semantically equivalent to:: + + manager = (EXPRESSION) + aenter = manager.__aenter__ + aexit = manager.__aexit__ + value = await aenter() + hit_except = False + + try: + TARGET = value + SUITE + except: + hit_except = True + if not await aexit(*sys.exc_info()): + raise + finally: + if not hit_except: + await aexit(None, None, None) + +except that implicit :ref:`special method lookup <special-lookup>` is used +for :meth:`~object.__aenter__` and :meth:`~object.__aexit__`. + +It is a :exc:`SyntaxError` to use an ``async with`` statement outside the +body of a coroutine function. + +.. seealso:: + + :pep:`492` - Coroutines with async and await syntax + The proposal that made coroutines a proper standalone concept in Python, + and added supporting syntax. + +.. _type-params: + +Type parameter lists +==================== + +.. versionadded:: 3.12 + +.. versionchanged:: 3.13 + Support for default values was added (see :pep:`696`). + +.. index:: + single: type parameters + +.. productionlist:: python-grammar + type_params: "[" `type_param` ("," `type_param`)* "]" + type_param: `typevar` | `typevartuple` | `paramspec` + typevar: `identifier` (":" `expression`)? ("=" `expression`)? + typevartuple: "*" `identifier` ("=" `expression`)? + paramspec: "**" `identifier` ("=" `expression`)? + +:ref:`Functions <def>` (including :ref:`coroutines <async def>`), +:ref:`classes <class>` and :ref:`type aliases <type>` may +contain a type parameter list:: + + def max[T](args: list[T]) -> T: + ... + + async def amax[T](args: list[T]) -> T: + ... + + class Bag[T]: + def __iter__(self) -> Iterator[T]: + ... + + def add(self, arg: T) -> None: + ... + + type ListOrSet[T] = list[T] | set[T] + +Semantically, this indicates that the function, class, or type alias is +generic over a type variable. This information is primarily used by static +type checkers, and at runtime, generic objects behave much like their +non-generic counterparts. + +Type parameters are declared in square brackets (``[]``) immediately +after the name of the function, class, or type alias. The type parameters +are accessible within the scope of the generic object, but not elsewhere. +Thus, after a declaration ``def func[T](): pass``, the name ``T`` is not available in +the module scope. Below, the semantics of generic objects are described +with more precision. The scope of type parameters is modeled with a special +function (technically, an :ref:`annotation scope <annotation-scopes>`) that +wraps the creation of the generic object. + +Generic functions, classes, and type aliases have a +:attr:`~definition.__type_params__` attribute listing their type parameters. + +Type parameters come in three kinds: + +* :data:`typing.TypeVar`, introduced by a plain name (e.g., ``T``). Semantically, this + represents a single type to a type checker. +* :data:`typing.TypeVarTuple`, introduced by a name prefixed with a single + asterisk (e.g., ``*Ts``). Semantically, this stands for a tuple of any + number of types. +* :data:`typing.ParamSpec`, introduced by a name prefixed with two asterisks + (e.g., ``**P``). Semantically, this stands for the parameters of a callable. + +:data:`typing.TypeVar` declarations can define *bounds* and *constraints* with +a colon (``:``) followed by an expression. A single expression after the colon +indicates a bound (e.g. ``T: int``). Semantically, this means +that the :data:`!typing.TypeVar` can only represent types that are a subtype of +this bound. A parenthesized tuple of expressions after the colon indicates a +set of constraints (e.g. ``T: (str, bytes)``). Each member of the tuple should be a +type (again, this is not enforced at runtime). Constrained type variables can only +take on one of the types in the list of constraints. + +For :data:`!typing.TypeVar`\ s declared using the type parameter list syntax, +the bound and constraints are not evaluated when the generic object is created, +but only when the value is explicitly accessed through the attributes ``__bound__`` +and ``__constraints__``. To accomplish this, the bounds or constraints are +evaluated in a separate :ref:`annotation scope <annotation-scopes>`. + +:data:`typing.TypeVarTuple`\ s and :data:`typing.ParamSpec`\ s cannot have bounds +or constraints. + +All three flavors of type parameters can also have a *default value*, which is used +when the type parameter is not explicitly provided. This is added by appending +a single equals sign (``=``) followed by an expression. Like the bounds and +constraints of type variables, the default value is not evaluated when the +object is created, but only when the type parameter's ``__default__`` attribute +is accessed. To this end, the default value is evaluated in a separate +:ref:`annotation scope <annotation-scopes>`. If no default value is specified +for a type parameter, the ``__default__`` attribute is set to the special +sentinel object :data:`typing.NoDefault`. + +The following example indicates the full set of allowed type parameter declarations:: + + def overly_generic[ + SimpleTypeVar, + TypeVarWithDefault = int, + TypeVarWithBound: int, + TypeVarWithConstraints: (str, bytes), + *SimpleTypeVarTuple = (int, float), + **SimpleParamSpec = (str, bytearray), + ]( + a: SimpleTypeVar, + b: TypeVarWithDefault, + c: TypeVarWithBound, + d: Callable[SimpleParamSpec, TypeVarWithConstraints], + *e: SimpleTypeVarTuple, + ): ... + +.. _generic-functions: + +Generic functions +----------------- + +Generic functions are declared as follows:: + + def func[T](arg: T): ... + +This syntax is equivalent to:: + + annotation-def TYPE_PARAMS_OF_func(): + T = typing.TypeVar("T") + def func(arg: T): ... + func.__type_params__ = (T,) + return func + func = TYPE_PARAMS_OF_func() + +Here ``annotation-def`` indicates an :ref:`annotation scope <annotation-scopes>`, +which is not actually bound to any name at runtime. (One +other liberty is taken in the translation: the syntax does not go through +attribute access on the :mod:`typing` module, but creates an instance of +:data:`typing.TypeVar` directly.) + +The annotations of generic functions are evaluated within the annotation scope +used for declaring the type parameters, but the function's defaults and +decorators are not. + +The following example illustrates the scoping rules for these cases, +as well as for additional flavors of type parameters:: + + @decorator + def func[T: int, *Ts, **P](*args: *Ts, arg: Callable[P, T] = some_default): + ... + +Except for the :ref:`lazy evaluation <lazy-evaluation>` of the +:class:`~typing.TypeVar` bound, this is equivalent to:: + + DEFAULT_OF_arg = some_default + + annotation-def TYPE_PARAMS_OF_func(): + + annotation-def BOUND_OF_T(): + return int + # In reality, BOUND_OF_T() is evaluated only on demand. + T = typing.TypeVar("T", bound=BOUND_OF_T()) + + Ts = typing.TypeVarTuple("Ts") + P = typing.ParamSpec("P") + + def func(*args: *Ts, arg: Callable[P, T] = DEFAULT_OF_arg): + ... + + func.__type_params__ = (T, Ts, P) + return func + func = decorator(TYPE_PARAMS_OF_func()) + +The capitalized names like ``DEFAULT_OF_arg`` are not actually +bound at runtime. + +.. _generic-classes: + +Generic classes +--------------- + +Generic classes are declared as follows:: + + class Bag[T]: ... + +This syntax is equivalent to:: + + annotation-def TYPE_PARAMS_OF_Bag(): + T = typing.TypeVar("T") + class Bag(typing.Generic[T]): + __type_params__ = (T,) + ... + return Bag + Bag = TYPE_PARAMS_OF_Bag() + +Here again ``annotation-def`` (not a real keyword) indicates an +:ref:`annotation scope <annotation-scopes>`, and the name +``TYPE_PARAMS_OF_Bag`` is not actually bound at runtime. + +Generic classes implicitly inherit from :data:`typing.Generic`. +The base classes and keyword arguments of generic classes are +evaluated within the type scope for the type parameters, +and decorators are evaluated outside that scope. This is illustrated +by this example:: + + @decorator + class Bag(Base[T], arg=T): ... + +This is equivalent to:: + + annotation-def TYPE_PARAMS_OF_Bag(): + T = typing.TypeVar("T") + class Bag(Base[T], typing.Generic[T], arg=T): + __type_params__ = (T,) + ... + return Bag + Bag = decorator(TYPE_PARAMS_OF_Bag()) + +.. _generic-type-aliases: + +Generic type aliases +-------------------- + +The :keyword:`type` statement can also be used to create a generic type alias:: + + type ListOrSet[T] = list[T] | set[T] + +Except for the :ref:`lazy evaluation <lazy-evaluation>` of the value, +this is equivalent to:: + + annotation-def TYPE_PARAMS_OF_ListOrSet(): + T = typing.TypeVar("T") + + annotation-def VALUE_OF_ListOrSet(): + return list[T] | set[T] + # In reality, the value is lazily evaluated + return typing.TypeAliasType("ListOrSet", VALUE_OF_ListOrSet(), type_params=(T,)) + ListOrSet = TYPE_PARAMS_OF_ListOrSet() + +Here, ``annotation-def`` (not a real keyword) indicates an +:ref:`annotation scope <annotation-scopes>`. The capitalized names +like ``TYPE_PARAMS_OF_ListOrSet`` are not actually bound at runtime. + +.. _annotations: + +Annotations +=========== + +.. versionchanged:: 3.14 + Annotations are now lazily evaluated by default. + +Variables and function parameters may carry :term:`annotations <annotation>`, +created by adding a colon after the name, followed by an expression:: + + x: annotation = 1 + def f(param: annotation): ... + +Functions may also carry a return annotation following an arrow:: + + def f() -> annotation: ... + +Annotations are conventionally used for :term:`type hints <type hint>`, but this +is not enforced by the language, and in general annotations may contain arbitrary +expressions. The presence of annotations does not change the runtime semantics of +the code, except if some mechanism is used that introspects and uses the annotations +(such as :mod:`dataclasses` or :deco:`functools.singledispatch`). + +By default, annotations are lazily evaluated in an :ref:`annotation scope <annotation-scopes>`. +This means that they are not evaluated when the code containing the annotation is evaluated. +Instead, the interpreter saves information that can be used to evaluate the annotation later +if requested. The :mod:`annotationlib` module provides tools for evaluating annotations. + +If the :ref:`future statement <future>` ``from __future__ import annotations`` is present, +all annotations are instead stored as strings:: + + >>> from __future__ import annotations + >>> def f(param: annotation): ... + >>> f.__annotations__ + {'param': 'annotation'} + +This future statement will be deprecated and removed in a future version of Python, +but not before Python 3.13 reaches its end of life (see :pep:`749`). +When it is used, introspection tools like +:func:`annotationlib.get_annotations` and :func:`typing.get_type_hints` are +less likely to be able to resolve annotations at runtime. + + +.. rubric:: Footnotes + +.. [#] The exception is propagated to the invocation stack unless + there is a :keyword:`finally` clause which happens to raise another + exception. That new exception causes the old one to be lost. + +.. [#] In pattern matching, a sequence is defined as one of the following: + + * a class that inherits from :class:`collections.abc.Sequence` + * a Python class that has been registered as :class:`collections.abc.Sequence` + * a builtin class that has its (CPython) :c:macro:`Py_TPFLAGS_SEQUENCE` bit set + * a class that inherits from any of the above + + The following standard library classes are sequences: + + * :class:`array.array` + * :class:`collections.deque` + * :class:`list` + * :class:`memoryview` + * :class:`range` + * :class:`tuple` + + .. note:: Subject values of type ``str``, ``bytes``, and ``bytearray`` + do not match sequence patterns. + +.. [#] In pattern matching, a mapping is defined as one of the following: + + * a class that inherits from :class:`collections.abc.Mapping` + * a Python class that has been registered as :class:`collections.abc.Mapping` + * a builtin class that has its (CPython) :c:macro:`Py_TPFLAGS_MAPPING` bit set + * a class that inherits from any of the above + + The standard library classes :class:`dict` and :class:`types.MappingProxyType` + are mappings. + +.. [#] A string literal appearing as the first statement in the function body is + transformed into the function's :attr:`~function.__doc__` attribute and + therefore the function's :term:`docstring`. + +.. [#] A string literal appearing as the first statement in the class body is + transformed into the namespace's :attr:`~type.__doc__` item and therefore + the class's :term:`docstring`. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/datamodel.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/datamodel.rst new file mode 100644 index 00000000..fde3cef6 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/datamodel.rst @@ -0,0 +1,4021 @@ + +.. _datamodel: + +********** +Data model +********** + + +.. _objects: + +Objects, values and types +========================= + +.. index:: + single: object + single: data + +:dfn:`Objects` are Python's abstraction for data. All data in a Python program +is represented by objects or by relations between objects. Even code is +represented by objects. + +.. index:: + pair: built-in function; id + pair: built-in function; type + single: identity of an object + single: value of an object + single: type of an object + single: mutable object + single: immutable object + +Every object has an identity, a type and a value. An object's *identity* never +changes once it has been created; you may think of it as the object's address in +memory. The :keyword:`is` operator compares the identity of two objects; the +:func:`id` function returns an integer representing its identity. + +.. impl-detail:: + + For CPython, ``id(x)`` is the memory address where ``x`` is stored. + +An object's type determines the operations that the object supports (e.g., "does +it have a length?") and also defines the possible values for objects of that +type. The :func:`type` function returns an object's type (which is an object +itself). Like its identity, an object's :dfn:`type` is also unchangeable. +[#]_ + +The *value* of some objects can change. Objects whose value can +change are said to be *mutable*; objects whose value is unchangeable once they +are created are called *immutable*. (The value of an immutable container object +that contains a reference to a mutable object can change when the latter's value +is changed; however the container is still considered immutable, because the +collection of objects it contains cannot be changed. So, immutability is not +strictly the same as having an unchangeable value, it is more subtle.) An +object's mutability is determined by its type; for instance, numbers, strings +and tuples are immutable, while dictionaries and lists are mutable. + +.. index:: + single: garbage collection + single: reference counting + single: unreachable object + +Objects are never explicitly destroyed; however, when they become unreachable +they may be garbage-collected. An implementation is allowed to postpone garbage +collection or omit it altogether --- it is a matter of implementation quality +how garbage collection is implemented, as long as no objects are collected that +are still reachable. + +.. impl-detail:: + + CPython currently uses a reference-counting scheme with (optional) delayed + detection of cyclically linked garbage, which collects most objects as soon + as they become unreachable, but is not guaranteed to collect garbage + containing circular references. See the documentation of the :mod:`gc` + module for information on controlling the collection of cyclic garbage. + Other implementations act differently and CPython may change. + Do not depend on immediate finalization of objects when they become + unreachable (so you should always close files explicitly). + +Note that the use of the implementation's tracing or debugging facilities may +keep objects alive that would normally be collectable. Also note that catching +an exception with a :keyword:`try`...\ :keyword:`except` statement may keep +objects alive. + +Some objects contain references to "external" resources such as open files or +windows. It is understood that these resources are freed when the object is +garbage-collected, but since garbage collection is not guaranteed to happen, +such objects also provide an explicit way to release the external resource, +usually a :meth:`!close` method. Programs are strongly recommended to explicitly +close such objects. The :keyword:`try`...\ :keyword:`finally` statement +and the :keyword:`with` statement provide convenient ways to do this. + +.. index:: single: container + +Some objects contain references to other objects; these are called *containers*. +Examples of containers are tuples, lists and dictionaries. The references are +part of a container's value. In most cases, when we talk about the value of a +container, we imply the values, not the identities of the contained objects; +however, when we talk about the mutability of a container, only the identities +of the immediately contained objects are implied. So, if an immutable container +(like a tuple) contains a reference to a mutable object, its value changes if +that mutable object is changed. + +Types affect almost all aspects of object behavior. Even the importance of +object identity is affected in some sense: for immutable types, operations that +compute new values may actually return a reference to any existing object with +the same type and value, while for mutable objects this is not allowed. +For example, after ``a = 1; b = 1``, *a* and *b* may or may not refer to +the same object with the value one, depending on the implementation. +This is because :class:`int` is an immutable type, so the reference to ``1`` +can be reused. This behaviour depends on the implementation used, so should +not be relied upon, but is something to be aware of when making use of object +identity tests. +However, after ``c = []; d = []``, *c* and *d* are guaranteed to refer to two +different, unique, newly created empty lists. (Note that ``e = f = []`` assigns +the *same* object to both *e* and *f*.) + + +.. _types: + +The standard type hierarchy +=========================== + +.. index:: + single: type + pair: data; type + pair: type; hierarchy + pair: extension; module + pair: C; language + +Below is a list of the types that are built into Python. Extension modules +(written in C, Java, or other languages, depending on the implementation) can +define additional types. Future versions of Python may add types to the type +hierarchy (e.g., rational numbers, efficiently stored arrays of integers, etc.), +although such additions will often be provided via the standard library instead. + +.. index:: + single: attribute + pair: special; attribute + triple: generic; special; attribute + +Some of the type descriptions below contain a paragraph listing 'special +attributes.' These are attributes that provide access to the implementation and +are not intended for general use. Their definition may change in the future. + + +None +---- + +.. index:: pair: object; None + +This type has a single value. There is a single object with this value. This +object is accessed through the built-in name ``None``. It is used to signify the +absence of a value in many situations, e.g., it is returned from functions that +don't explicitly return anything. Its truth value is false. + + +NotImplemented +-------------- + +.. index:: pair: object; NotImplemented + +This type has a single value. There is a single object with this value. This +object is accessed through the built-in name :data:`NotImplemented`. Numeric methods +and rich comparison methods should return this value if they do not implement the +operation for the operands provided. (The interpreter will then try the +reflected operation, or some other fallback, depending on the operator.) It +should not be evaluated in a boolean context. + +See +:ref:`implementing-the-arithmetic-operations` +for more details. + +.. versionchanged:: 3.9 + Evaluating :data:`NotImplemented` in a boolean context was deprecated. + +.. versionchanged:: 3.14 + Evaluating :data:`NotImplemented` in a boolean context now raises a :exc:`TypeError`. + It previously evaluated to :const:`True` and emitted a :exc:`DeprecationWarning` + since Python 3.9. + + +Ellipsis +-------- +.. index:: + pair: object; Ellipsis + single: ...; ellipsis literal + +This type has a single value. There is a single object with this value. This +object is accessed through the literal ``...`` or the built-in name +``Ellipsis``. Its truth value is true. + + +:class:`numbers.Number` +----------------------- + +.. index:: pair: object; numeric + +These are created by numeric literals and returned as results by arithmetic +operators and arithmetic built-in functions. Numeric objects are immutable; +once created their value never changes. Python numbers are of course strongly +related to mathematical numbers, but subject to the limitations of numerical +representation in computers. + +The string representations of the numeric classes, computed by +:meth:`~object.__repr__` and :meth:`~object.__str__`, have the following +properties: + +* They are valid numeric literals which, when passed to their + class constructor, produce an object having the value of the + original numeric. + +* The representation is in base 10, when possible. + +* Leading zeros, possibly excepting a single zero before a + decimal point, are not shown. + +* Trailing zeros, possibly excepting a single zero after a + decimal point, are not shown. + +* A sign is shown only when the number is negative. + +Python distinguishes between integers, floating-point numbers, and complex +numbers: + + +:class:`numbers.Integral` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: pair: object; integer + +These represent elements from the mathematical set of integers (positive and +negative). + +.. note:: + .. index:: pair: integer; representation + + The rules for integer representation are intended to give the most meaningful + interpretation of shift and mask operations involving negative integers. + +There are two types of integers: + +Integers (:class:`int`) + These represent numbers in an unlimited range, subject to available (virtual) + memory only. For the purpose of shift and mask operations, a binary + representation is assumed, and negative numbers are represented in a variant of + 2's complement which gives the illusion of an infinite string of sign bits + extending to the left. + +Booleans (:class:`bool`) + .. index:: + pair: object; Boolean + single: False + single: True + + These represent the truth values False and True. The two objects representing + the values ``False`` and ``True`` are the only Boolean objects. The Boolean type is a + subtype of the integer type, and Boolean values behave like the values 0 and 1, + respectively, in almost all contexts, the exception being that when converted to + a string, the strings ``"False"`` or ``"True"`` are returned, respectively. + + +.. _datamodel-float: + +:class:`numbers.Real` (:class:`float`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; floating-point + pair: floating-point; number + pair: C; language + pair: Java; language + +These represent machine-level double precision floating-point numbers. You are +at the mercy of the underlying machine architecture (and C or Java +implementation) for the accepted range and handling of overflow. Python does not +support single-precision floating-point numbers; the savings in processor and +memory usage that are usually the reason for using these are dwarfed by the +overhead of using objects in Python, so there is no reason to complicate the +language with two kinds of floating-point numbers. + + +:class:`numbers.Complex` (:class:`complex`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; complex + pair: complex; number + +These represent complex numbers as a pair of machine-level double precision +floating-point numbers. The same caveats apply as for floating-point numbers. +The real and imaginary parts of a complex number ``z`` can be retrieved through +the read-only attributes ``z.real`` and ``z.imag``. + +.. _datamodel-sequences: + +Sequences +--------- + +.. index:: + pair: built-in function; len + pair: object; sequence + single: index operation + single: item selection + single: subscription + +These represent finite ordered sets indexed by non-negative numbers. The +built-in function :func:`len` returns the number of items of a sequence. When +the length of a sequence is *n*, the index set contains the numbers 0, 1, +..., *n*-1. Item *i* of sequence *a* is selected by ``a[i]``. Some sequences, +including built-in sequences, interpret negative subscripts by adding the +sequence length. For example, ``a[-2]`` equals ``a[n-2]``, the second to last +item of sequence a with length ``n``. + +The resulting value must be a nonnegative integer less than the number of items +in the sequence. If it is not, an :exc:`IndexError` is raised. + +.. index:: + single: slicing + single: start (slice object attribute) + single: stop (slice object attribute) + single: step (slice object attribute) + +Sequences also support slicing: ``a[start:stop]`` selects all items with index *k* such +that *start* ``<=`` *k* ``<`` *stop*. When used as an expression, a slice is a +sequence of the same type. The comment above about negative subscripts also applies +to negative slice positions. +Note that no error is raised if a slice position is less than zero or larger +than the length of the sequence. + +If *start* is missing or :data:`None`, slicing behaves as if *start* was zero. +If *stop* is missing or ``None``, slicing behaves as if *stop* was equal to +the length of the sequence. + +Some sequences also support "extended slicing" with a third "step" parameter: +``a[i:j:k]`` selects all items of *a* with index *x* where ``x = i + n*k``, *n* +``>=`` ``0`` and *i* ``<=`` *x* ``<`` *j*. + +Sequences are distinguished according to their mutability: + + +Immutable sequences +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; immutable sequence + pair: object; immutable + +An object of an immutable sequence type cannot change once it is created. (If +the object contains references to other objects, these other objects may be +mutable and may be changed; however, the collection of objects directly +referenced by an immutable object cannot change.) + +The following types are immutable sequences: + +.. index:: + single: string; immutable sequences + +Strings + .. index:: + pair: built-in function; chr + pair: built-in function; ord + single: character + pair: string; item + single: Unicode + + A string (:class:`str`) is a sequence of values that represent + :dfn:`characters`, or more formally, *Unicode code points*. + All the code points in the range ``0`` to ``0x10FFFF`` can be + represented in a string. + + Python doesn't have a dedicated *character* type. + Instead, every code point in the string is represented as a string + object with length ``1``. + + The built-in function :func:`ord` + converts a code point from its string form to an integer in the + range ``0`` to ``0x10FFFF``; :func:`chr` converts an integer in the range + ``0`` to ``0x10FFFF`` to the corresponding length ``1`` string object. + :meth:`str.encode` can be used to convert a :class:`str` to + :class:`bytes` using the given text encoding, and + :meth:`bytes.decode` can be used to achieve the opposite. + +Tuples + .. index:: + pair: object; tuple + pair: singleton; tuple + pair: empty; tuple + + The items of a :class:`tuple` are arbitrary Python objects. Tuples of two or + more items are formed by comma-separated lists of expressions. A tuple + of one item (a 'singleton') can be formed by affixing a comma to an + expression (an expression by itself does not create a tuple, since + parentheses must be usable for grouping of expressions). An empty + tuple can be formed by an empty pair of parentheses. + +Bytes + .. index:: bytes, byte + + A :class:`bytes` object is an immutable array. The items are 8-bit bytes, + represented by integers in the range 0 <= x < 256. Bytes literals + (like ``b'abc'``) and the built-in :func:`bytes` constructor + can be used to create bytes objects. Also, bytes objects can be + decoded to strings via the :meth:`~bytes.decode` method. + + +Mutable sequences +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; mutable sequence + pair: object; mutable + pair: assignment; statement + single: subscription + single: slicing + +Mutable sequences can be changed after they are created. The subscription and +slicing notations can be used as the target of assignment and :keyword:`del` +(delete) statements. + +.. note:: + .. index:: pair: module; array + .. index:: pair: module; collections + + The :mod:`collections` and :mod:`array` module provide + additional examples of mutable sequence types. + +There are currently two intrinsic mutable sequence types: + +Lists + .. index:: pair: object; list + + The items of a list are arbitrary Python objects. Lists are formed by + placing a comma-separated list of expressions in square brackets. (Note + that there are no special cases needed to form lists of length 0 or 1.) + +Byte Arrays + .. index:: bytearray + + A bytearray object is a mutable array. They are created by the built-in + :func:`bytearray` constructor. Aside from being mutable + (and hence unhashable), byte arrays otherwise provide the same interface + and functionality as immutable :class:`bytes` objects. + + +Set types +--------- + +.. index:: + pair: built-in function; len + pair: object; set type + +These represent unordered, finite sets of unique, immutable objects. As such, +they cannot be indexed by any subscript. However, they can be iterated over, and +the built-in function :func:`len` returns the number of items in a set. Common +uses for sets are fast membership testing, removing duplicates from a sequence, +and computing mathematical operations such as intersection, union, difference, +and symmetric difference. + +For set elements, the same immutability rules apply as for dictionary keys. Note +that numeric types obey the normal rules for numeric comparison: if two numbers +compare equal (e.g., ``1`` and ``1.0``), only one of them can be contained in a +set. + +There are currently two intrinsic set types: + + +Sets + .. index:: pair: object; set + + These represent a mutable set. They are created by the built-in :func:`set` + constructor and can be modified afterwards by several methods, such as + :meth:`~set.add`. + + +Frozen sets + .. index:: pair: object; frozenset + + These represent an immutable set. They are created by the built-in + :func:`frozenset` constructor. As a frozenset is immutable and + :term:`hashable`, it can be used again as an element of another set, or as + a dictionary key. + + +.. _datamodel-mappings: + +Mappings +-------- + +.. index:: + pair: built-in function; len + single: subscription + pair: object; mapping + +These represent finite sets of objects indexed by arbitrary index sets. The +subscript notation ``a[k]`` selects the item indexed by ``k`` from the mapping +``a``; this can be used in expressions and as the target of assignments or +:keyword:`del` statements. The built-in function :func:`len` returns the number +of items in a mapping. + +There are two intrinsic mapping types: + + +Dictionaries +^^^^^^^^^^^^ + +.. index:: pair: object; dictionary + +These represent finite sets of objects indexed by nearly arbitrary values. The +only types of values not acceptable as keys are values containing lists or +dictionaries or other mutable types that are compared by value rather than by +object identity, the reason being that the efficient implementation of +dictionaries requires a key's hash value to remain constant. Numeric types used +for keys obey the normal rules for numeric comparison: if two numbers compare +equal (e.g., ``1`` and ``1.0``) then they can be used interchangeably to index +the same dictionary entry. + +Dictionaries preserve insertion order, meaning that keys will be produced +in the same order they were added sequentially over the dictionary. +Replacing an existing key does not change the order, however removing a key +and re-inserting it will add it to the end instead of keeping its old place. + +Dictionaries are mutable; they can be created by the ``{}`` notation (see +section :ref:`dict`). + +.. index:: + pair: module; dbm.ndbm + pair: module; dbm.gnu + +The extension modules :mod:`dbm.ndbm` and :mod:`dbm.gnu` provide +additional examples of mapping types, as does the :mod:`collections` +module. + +.. versionchanged:: 3.7 + Dictionaries did not preserve insertion order in versions of Python before 3.6. + In CPython 3.6, insertion order was preserved, but it was considered + an implementation detail at that time rather than a language guarantee. + + +Frozen dictionaries +^^^^^^^^^^^^^^^^^^^ + +.. index:: pair: object; frozendict + +These represent an immutable dictionary. They are created by the built-in +:func:`frozendict` constructor. A frozendict is :term:`hashable` if all of +its keys and values are hashable, in which case it can be used as an element +of a set, or as a key in another mapping. :class:`!frozendict` is not a +subclass of :class:`dict`; it inherits directly from :class:`object`. + +.. versionadded:: 3.15 + + +Callable types +-------------- + +.. index:: + pair: object; callable + pair: function; call + single: invocation + pair: function; argument + +These are the types to which the function call operation (see section +:ref:`calls`) can be applied: + + +.. _user-defined-funcs: + +User-defined functions +^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: user-defined; function + pair: object; function + pair: object; user-defined function + +A user-defined function object is created by a function definition (see +section :ref:`function`). It should be called with an argument list +containing the same number of items as the function's formal parameter +list. + +Special read-only attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: + single: __builtins__ (function attribute) + single: __closure__ (function attribute) + single: __globals__ (function attribute) + pair: global; namespace + +.. list-table:: + :header-rows: 1 + + * - Attribute + - Meaning + + * - .. attribute:: function.__builtins__ + - A reference to the :class:`dictionary <dict>` that holds the function's + builtins namespace. + + .. versionadded:: 3.10 + + * - .. attribute:: function.__globals__ + - A reference to the :class:`dictionary <dict>` that holds the function's + :ref:`global variables <naming>` -- the global namespace of the module + in which the function was defined. + + * - .. attribute:: function.__closure__ + - ``None`` or a :class:`tuple` of cells that contain bindings for the names specified + in the :attr:`~codeobject.co_freevars` attribute of the function's + :attr:`code object <function.__code__>`. + + A cell object has the attribute ``cell_contents``. + This can be used to get the value of the cell, as well as set the value. + +Special writable attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: + single: __doc__ (function attribute) + single: __name__ (function attribute) + single: __module__ (function attribute) + single: __dict__ (function attribute) + single: __defaults__ (function attribute) + single: __code__ (function attribute) + single: __annotations__ (function attribute) + single: __annotate__ (function attribute) + single: __kwdefaults__ (function attribute) + single: __type_params__ (function attribute) + +Most of these attributes check the type of the assigned value: + +.. list-table:: + :header-rows: 1 + + * - Attribute + - Meaning + + * - .. attribute:: function.__doc__ + - The function's documentation string, or ``None`` if unavailable. + + * - .. attribute:: function.__name__ + - The function's name. + See also: :attr:`__name__ attributes <definition.__name__>`. + + * - .. attribute:: function.__qualname__ + - The function's :term:`qualified name`. + See also: :attr:`__qualname__ attributes <definition.__qualname__>`. + + .. versionadded:: 3.3 + + * - .. attribute:: function.__module__ + - The name of the module the function was defined in, + or ``None`` if unavailable. + + * - .. attribute:: function.__defaults__ + - A :class:`tuple` containing default :term:`parameter` values + for those parameters that have defaults, + or ``None`` if no parameters have a default value. + + * - .. attribute:: function.__code__ + - The :ref:`code object <code-objects>` representing + the compiled function body. + + * - .. attribute:: function.__dict__ + - The namespace supporting arbitrary function attributes. + See also: :attr:`__dict__ attributes <object.__dict__>`. + + * - .. attribute:: function.__annotations__ + - A :class:`dictionary <dict>` containing annotations of + :term:`parameters <parameter>`. + The keys of the dictionary are the parameter names, + and ``'return'`` for the return annotation, if provided. + See also: :attr:`object.__annotations__`. + + .. versionchanged:: 3.14 + Annotations are now :ref:`lazily evaluated <lazy-evaluation>`. + See :pep:`649`. + + * - .. attribute:: function.__annotate__ + - The :term:`annotate function` for this function, or ``None`` + if the function has no annotations. See :attr:`object.__annotate__`. + + .. versionadded:: 3.14 + + * - .. attribute:: function.__kwdefaults__ + - A :class:`dictionary <dict>` containing defaults for keyword-only + :term:`parameters <parameter>`. + + * - .. attribute:: function.__type_params__ + - A :class:`tuple` containing the :ref:`type parameters <type-params>` of + a :ref:`generic function <generic-functions>`. + + .. versionadded:: 3.12 + +Function objects also support getting and setting arbitrary attributes, which +can be used, for example, to attach metadata to functions. Regular attribute +dot-notation is used to get and set such attributes. + +.. impl-detail:: + + CPython's current implementation only supports function attributes + on user-defined functions. Function attributes on + :ref:`built-in functions <builtin-functions>` may be supported in the + future. + +Additional information about a function's definition can be retrieved from its +:ref:`code object <code-objects>` +(accessible via the :attr:`~function.__code__` attribute). + + +.. _instance-methods: + +Instance methods +^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; method + pair: object; user-defined method + pair: user-defined; method + +An instance method object combines a class, a class instance and any +callable object (normally a user-defined function). + +.. index:: + single: __func__ (method attribute) + single: __self__ (method attribute) + single: __doc__ (method attribute) + single: __name__ (method attribute) + single: __module__ (method attribute) + +Special read-only attributes: + +.. list-table:: + + * - .. attribute:: method.__self__ + - Refers to the class instance object to which the method is + :ref:`bound <method-binding>` + + * - .. attribute:: method.__func__ + - Refers to the original :ref:`function object <user-defined-funcs>` + + * - .. attribute:: method.__doc__ + - The method's documentation + (same as :attr:`method.__func__.__doc__ <function.__doc__>`). + A :class:`string <str>` if the original function had a docstring, else + ``None``. + + * - .. attribute:: method.__name__ + - The name of the method + (same as :attr:`method.__func__.__name__ <function.__name__>`) + + * - .. attribute:: method.__module__ + - The name of the module the method was defined in, or ``None`` if + unavailable. + +Methods also support accessing (but not setting) the arbitrary function +attributes on the underlying :ref:`function object <user-defined-funcs>`. + +User-defined method objects may be created when getting an attribute of a +class (perhaps via an instance of that class), if that attribute is a +user-defined :ref:`function object <user-defined-funcs>` or a +:class:`classmethod` object. + +.. _method-binding: + +When an instance method object is created by retrieving a user-defined +:ref:`function object <user-defined-funcs>` from a class via one of its +instances, its :attr:`~method.__self__` attribute is the instance, and the +method object is said to be *bound*. The new method's :attr:`~method.__func__` +attribute is the original function object. + +When an instance method object is created by retrieving a :class:`classmethod` +object from a class or instance, its :attr:`~method.__self__` attribute is the +class itself, and its :attr:`~method.__func__` attribute is the function object +underlying the class method. + +When an instance method object is called, the underlying function +(:attr:`~method.__func__`) is called, inserting the class instance +(:attr:`~method.__self__`) in front of the argument list. For instance, when +:class:`!C` is a class which contains a definition for a function +:meth:`!f`, and ``x`` is an instance of :class:`!C`, calling ``x.f(1)`` is +equivalent to calling ``C.f(x, 1)``. + +When an instance method object is derived from a :class:`classmethod` object, the +"class instance" stored in :attr:`~method.__self__` will actually be the class +itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to +calling ``f(C,1)`` where ``f`` is the underlying function. + +It is important to note that user-defined functions +which are attributes of a class instance are not converted to bound +methods; this *only* happens when the function is an attribute of the +class. + + +Generator functions +^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: generator; function + single: generator; iterator + +A function or method which uses the :keyword:`yield` statement (see section +:ref:`yield`) is called a :dfn:`generator function`. Such a function, when +called, always returns an :term:`iterator` object which can be used to +execute the body of the function: calling the iterator's +:meth:`iterator.__next__` method will cause the function to execute until +it provides a value using the :keyword:`!yield` statement. When the +function executes a :keyword:`return` statement or falls off the end, a +:exc:`StopIteration` exception is raised and the iterator will have +reached the end of the set of values to be returned. + + +Coroutine functions +^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: coroutine; function + +A function or method which is defined using :keyword:`async def` is called +a :dfn:`coroutine function`. Such a function, when called, returns a +:term:`coroutine` object. It may contain :keyword:`await` expressions, +as well as :keyword:`async with` and :keyword:`async for` statements. See +also the :ref:`coroutine-objects` section. + + +Asynchronous generator functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: asynchronous generator; function + single: asynchronous generator; asynchronous iterator + +A function or method which is defined using :keyword:`async def` and +which uses the :keyword:`yield` statement is called a +:dfn:`asynchronous generator function`. Such a function, when called, +returns an :term:`asynchronous iterator` object which can be used in an +:keyword:`async for` statement to execute the body of the function. + +Calling the asynchronous iterator's +:meth:`aiterator.__anext__ <object.__anext__>` method +will return an :term:`awaitable` which when awaited +will execute until it provides a value using the :keyword:`yield` +expression. When the function executes an empty :keyword:`return` +statement or falls off the end, a :exc:`StopAsyncIteration` exception +is raised and the asynchronous iterator will have reached the end of +the set of values to be yielded. + + +.. _builtin-functions: + +Built-in functions +^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; built-in function + pair: object; function + pair: C; language + +A built-in function object is a wrapper around a C function. Examples of +built-in functions are :func:`len` and :func:`math.sin` (:mod:`math` is a +standard built-in module). The number and type of the arguments are +determined by the C function. Special read-only attributes: + +* :attr:`!__doc__` is the function's documentation string, or ``None`` if + unavailable. See :attr:`function.__doc__`. +* :attr:`!__name__` is the function's name. See :attr:`function.__name__`. +* :attr:`!__self__` is set to ``None`` (but see the next item). +* :attr:`!__module__` is the name of + the module the function was defined in or ``None`` if unavailable. + See :attr:`function.__module__`. + + +.. _builtin-methods: + +Built-in methods +^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; built-in method + pair: object; method + pair: built-in; method + +This is really a different disguise of a built-in function, this time containing +an object passed to the C function as an implicit extra argument. An example of +a built-in method is ``alist.append()``, assuming *alist* is a list object. In +this case, the special read-only attribute :attr:`!__self__` is set to the object +denoted by *alist*. (The attribute has the same semantics as it does with +:attr:`other instance methods <method.__self__>`.) + +.. _classes: + +Classes +^^^^^^^ + +Classes are callable. These objects normally act as factories for new +instances of themselves, but variations are possible for class types that +override :meth:`~object.__new__`. The arguments of the call are passed to +:meth:`!__new__` and, in the typical case, to :meth:`~object.__init__` to +initialize the new instance. + + +Class Instances +^^^^^^^^^^^^^^^ + +Instances of arbitrary classes can be made callable by defining a +:meth:`~object.__call__` method in their class. + + +.. _module-objects: + +Modules +------- + +.. index:: + pair: statement; import + pair: object; module + +Modules are a basic organizational unit of Python code, and are created by +the :ref:`import system <importsystem>` as invoked either by the +:keyword:`import` statement, or by calling +functions such as :func:`importlib.import_module` and built-in +:func:`__import__`. A module object has a namespace implemented by a +:class:`dictionary <dict>` object (this is the dictionary referenced by the +:attr:`~function.__globals__` +attribute of functions defined in the module). Attribute references are +translated to lookups in this dictionary, e.g., ``m.x`` is equivalent to +``m.__dict__["x"]``. A module object does not contain the code object used +to initialize the module (since it isn't needed once the initialization is +done). + +Attribute assignment updates the module's namespace dictionary, e.g., +``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``. + +.. index:: + single: __name__ (module attribute) + single: __spec__ (module attribute) + single: __package__ (module attribute) + single: __loader__ (module attribute) + single: __path__ (module attribute) + single: __file__ (module attribute) + single: __doc__ (module attribute) + single: __annotations__ (module attribute) + single: __annotate__ (module attribute) + single: __lazy_modules__ (module attribute) + pair: module; namespace + +.. _import-mod-attrs: + +Import-related attributes on module objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Module objects have the following attributes that relate to the +:ref:`import system <importsystem>`. When a module is created using the machinery associated +with the import system, these attributes are filled in based on the module's +:term:`spec <module spec>`, before the :term:`loader` executes and loads the +module. + +To create a module dynamically rather than using the import system, +it's recommended to use :func:`importlib.util.module_from_spec`, +which will set the various import-controlled attributes to appropriate values. +It's also possible to use the :class:`types.ModuleType` constructor to create +modules directly, but this technique is more error-prone, as most attributes +must be manually set on the module object after it has been created when using +this approach. + +.. caution:: + + With the exception of :attr:`~module.__name__`, it is **strongly** + recommended that you rely on :attr:`~module.__spec__` and its attributes + instead of any of the other individual attributes listed in this subsection. + Note that updating an attribute on :attr:`!__spec__` will not update the + corresponding attribute on the module itself: + + .. doctest:: + + >>> import typing + >>> typing.__name__, typing.__spec__.name + ('typing', 'typing') + >>> typing.__spec__.name = 'spelling' + >>> typing.__name__, typing.__spec__.name + ('typing', 'spelling') + >>> typing.__name__ = 'keyboard_smashing' + >>> typing.__name__, typing.__spec__.name + ('keyboard_smashing', 'spelling') + +.. attribute:: module.__name__ + + The name used to uniquely identify the module in the import system. + For a directly executed module, this will be set to ``"__main__"``. + + This attribute must be set to the fully qualified name of the module. + It is expected to match the value of + :attr:`module.__spec__.name <importlib.machinery.ModuleSpec.name>`. + +.. attribute:: module.__spec__ + + A record of the module's import-system-related state. + + Set to the :class:`module spec <importlib.machinery.ModuleSpec>` that was + used when importing the module. See :ref:`module-specs` for more details. + + .. versionadded:: 3.4 + +.. attribute:: module.__package__ + + The :term:`package` a module belongs to. + + If the module is top-level (that is, not a part of any specific package) + then the attribute should be set to ``''`` (the empty string). Otherwise, + it should be set to the name of the module's package (which can be equal to + :attr:`module.__name__` if the module itself is a package). See :pep:`366` + for further details. + + This attribute is used instead of :attr:`~module.__name__` to calculate + explicit relative imports for main modules. It defaults to ``None`` for + modules created dynamically using the :class:`types.ModuleType` constructor; + use :func:`importlib.util.module_from_spec` instead to ensure the attribute + is set to a :class:`str`. + + It is **strongly** recommended that you use + :attr:`module.__spec__.parent <importlib.machinery.ModuleSpec.parent>` + instead of :attr:`!module.__package__`. :attr:`__package__` is now only used + as a fallback if :attr:`!__spec__.parent` is not set, and this fallback + path is deprecated. + + .. versionchanged:: 3.4 + This attribute now defaults to ``None`` for modules created dynamically + using the :class:`types.ModuleType` constructor. + Previously the attribute was optional. + + .. versionchanged:: 3.6 + The value of :attr:`!__package__` is expected to be the same as + :attr:`__spec__.parent <importlib.machinery.ModuleSpec.parent>`. + :attr:`__package__` is now only used as a fallback during import + resolution if :attr:`!__spec__.parent` is not defined. + + .. versionchanged:: 3.10 + :exc:`ImportWarning` is raised if an import resolution falls back to + :attr:`!__package__` instead of + :attr:`__spec__.parent <importlib.machinery.ModuleSpec.parent>`. + + .. versionchanged:: 3.12 + Raise :exc:`DeprecationWarning` instead of :exc:`ImportWarning` when + falling back to :attr:`!__package__` during import resolution. + + .. deprecated-removed:: 3.13 3.16 + :attr:`!__package__` will cease to be set or taken into consideration + by the import system or standard library. + +.. attribute:: module.__loader__ + + The :term:`loader` object that the import machinery used to load the module. + + This attribute is mostly useful for introspection, but can be used for + additional loader-specific functionality, for example getting data + associated with a loader. + + :attr:`!__loader__` defaults to ``None`` for modules created dynamically + using the :class:`types.ModuleType` constructor; + use :func:`importlib.util.module_from_spec` instead to ensure the attribute + is set to a :term:`loader` object. + + It is **strongly** recommended that you use + :attr:`module.__spec__.loader <importlib.machinery.ModuleSpec.loader>` + instead of :attr:`!module.__loader__`. + + .. versionchanged:: 3.4 + This attribute now defaults to ``None`` for modules created dynamically + using the :class:`types.ModuleType` constructor. + Previously the attribute was optional. + + .. deprecated-removed:: 3.12 3.16 + Setting :attr:`!__loader__` on a module while failing to set + :attr:`!__spec__.loader` is deprecated. In Python 3.16, + :attr:`!__loader__` will cease to be set or taken into consideration by + the import system or the standard library. + +.. attribute:: module.__path__ + + A (possibly empty) :term:`sequence` of strings enumerating the locations + where the package's submodules will be found. Non-package modules should + not have a :attr:`!__path__` attribute. See :ref:`package-path-rules` for + more details. + + It is **strongly** recommended that you use + :attr:`module.__spec__.submodule_search_locations <importlib.machinery.ModuleSpec.submodule_search_locations>` + instead of :attr:`!module.__path__`. + +.. attribute:: module.__file__ + + :attr:`!__file__` is an optional attribute that + may or may not be set. Both attributes should be a :class:`str` when they + are available. + + An optional attribute, :attr:`!__file__` indicates the pathname of the file + from which the module was loaded (if loaded from a file), or the pathname of + the shared library file for extension modules loaded dynamically from a + shared library. It might be missing for certain types of modules, such as C + modules that are statically linked into the interpreter, and the + :ref:`import system <importsystem>` may opt to leave it unset if it + has no semantic meaning (for example, a module loaded from a database). + +.. versionchanged:: 3.15 + The ``__cached__`` attribute is no longer set on modules or taken into + consideration by the import system or standard library. + +Other writable attributes on module objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As well as the import-related attributes listed above, module objects also have +the following writable attributes: + +.. attribute:: module.__doc__ + + The module's documentation string, or ``None`` if unavailable. + See also: :attr:`__doc__ attributes <definition.__doc__>`. + +.. attribute:: module.__annotations__ + + A dictionary containing :term:`variable annotations <variable annotation>` + collected during module body execution. For best practices on working with + :attr:`!__annotations__`, see :mod:`annotationlib`. + + .. versionchanged:: 3.14 + Annotations are now :ref:`lazily evaluated <lazy-evaluation>`. + See :pep:`649`. + +.. attribute:: module.__annotate__ + + The :term:`annotate function` for this module, or ``None`` if the module has + no annotations. See also: :attr:`~object.__annotate__` attributes. + + .. versionadded:: 3.14 + +.. attribute:: module.__lazy_modules__ + + A container (an object implementing :meth:`~object.__contains__`) of fully + qualified module name strings. When defined + at module scope, any regular :keyword:`import` statement in that module whose + target module name appears in this container is treated as a + :ref:`lazy import <lazy-imports>`, as if the :keyword:`lazy` keyword had + been used. Imports inside functions, class bodies, or + :keyword:`try`/:keyword:`except`/:keyword:`finally` blocks are unaffected. + + See :ref:`lazy-modules-compat` for details and examples. + + .. versionadded:: 3.15 + +Module dictionaries +^^^^^^^^^^^^^^^^^^^ + +Module objects also have the following special read-only attribute: + +.. index:: single: __dict__ (module attribute) +.. attribute:: module.__dict__ + + The module's namespace as a dictionary object. Uniquely among the attributes + listed here, :attr:`!__dict__` cannot be accessed as a global variable from + within a module; it can only be accessed as an attribute on module objects. + + .. impl-detail:: + + Because of the way CPython clears module dictionaries, the module + dictionary will be cleared when the module falls out of scope even if the + dictionary still has live references. To avoid this, copy the dictionary + or keep the module around while using its dictionary directly. + + +.. _class-attrs-and-methods: + +Custom classes +-------------- + +Custom class types are typically created by class definitions (see section +:ref:`class`). A class has a namespace implemented by a dictionary object. +Class attribute references are translated to lookups in this dictionary, e.g., +``C.x`` is translated to ``C.__dict__["x"]`` (although there are a number of +hooks which allow for other means of locating attributes). When the attribute +name is not found there, the attribute search continues in the base classes. +This search of the base classes uses the C3 method resolution order which +behaves correctly even in the presence of 'diamond' inheritance structures +where there are multiple inheritance paths leading back to a common ancestor. +Additional details on the C3 MRO used by Python can be found at +:ref:`python_2.3_mro`. + +.. index:: + pair: object; class + pair: object; class instance + pair: object; instance + pair: class object; call + single: container + pair: object; dictionary + pair: class; attribute + +When a class attribute reference (for class :class:`!C`, say) would yield a +class method object, it is transformed into an instance method object whose +:attr:`~method.__self__` attribute is :class:`!C`. +When it would yield a :class:`staticmethod` object, +it is transformed into the object wrapped by the static method +object. See section :ref:`descriptors` for another way in which attributes +retrieved from a class may differ from those actually contained in its +:attr:`~object.__dict__`. + +.. index:: triple: class; attribute; assignment + +Class attribute assignments update the class's dictionary, never the dictionary +of a base class. + +.. index:: pair: class object; call + +A class object can be called (see above) to yield a class instance (see below). + +Special attributes +^^^^^^^^^^^^^^^^^^ + +.. index:: + single: __name__ (class attribute) + single: __module__ (class attribute) + single: __dict__ (class attribute) + single: __bases__ (class attribute) + single: __base__ (class attribute) + single: __doc__ (class attribute) + single: __annotations__ (class attribute) + single: __annotate__ (class attribute) + single: __type_params__ (class attribute) + single: __static_attributes__ (class attribute) + single: __firstlineno__ (class attribute) + +.. list-table:: + :header-rows: 1 + + * - Attribute + - Meaning + + * - .. attribute:: type.__name__ + - The class's name. + See also: :attr:`__name__ attributes <definition.__name__>`. + + * - .. attribute:: type.__qualname__ + - The class's :term:`qualified name`. + See also: :attr:`__qualname__ attributes <definition.__qualname__>`. + + * - .. attribute:: type.__module__ + - The name of the module in which the class was defined. + + * - .. attribute:: type.__dict__ + - A :class:`mapping proxy <types.MappingProxyType>` + providing a read-only view of the class's namespace. + See also: :attr:`__dict__ attributes <object.__dict__>`. + + * - .. attribute:: type.__bases__ + - A :class:`tuple` containing the class's bases. + In most cases, for a class defined as ``class X(A, B, C)``, + ``X.__bases__`` will be exactly equal to ``(A, B, C)``. + + * - .. attribute:: type.__base__ + - .. impl-detail:: + + The single base class in the inheritance chain that is responsible + for the memory layout of instances. This attribute corresponds to + :c:member:`~PyTypeObject.tp_base` at the C level. + + * - .. attribute:: type.__doc__ + - The class's documentation string, or ``None`` if undefined. + Not inherited by subclasses. + + * - .. attribute:: type.__annotations__ + - A dictionary containing + :term:`variable annotations <variable annotation>` + collected during class body execution. See also: + :attr:`__annotations__ attributes <object.__annotations__>`. + + For best practices on working with :attr:`~object.__annotations__`, + please see :mod:`annotationlib`. Use + :func:`annotationlib.get_annotations` instead of accessing this + attribute directly. + + .. warning:: + + Accessing the :attr:`!__annotations__` attribute directly + on a class object may return annotations for the wrong class, specifically + in certain cases where the class, its base class, or a metaclass + is defined under ``from __future__ import annotations``. + See :pep:`749 <749#pep749-metaclasses>` for details. + + This attribute does not exist on certain builtin classes. On + user-defined classes without ``__annotations__``, it is an + empty dictionary. + + .. versionchanged:: 3.14 + Annotations are now :ref:`lazily evaluated <lazy-evaluation>`. + See :pep:`649`. + + * - .. method:: type.__annotate__ + - The :term:`annotate function` for this class, or ``None`` + if the class has no annotations. + See also: :attr:`__annotate__ attributes <object.__annotate__>`. + + .. versionadded:: 3.14 + + * - .. attribute:: type.__type_params__ + - A :class:`tuple` containing the :ref:`type parameters <type-params>` of + a :ref:`generic class <generic-classes>`. + + .. versionadded:: 3.12 + + * - .. attribute:: type.__static_attributes__ + - A :class:`tuple` containing names of attributes of this class which are + assigned through ``self.X`` from any function in its body. + + .. versionadded:: 3.13 + + * - .. attribute:: type.__firstlineno__ + - The line number of the first line of the class definition, + including decorators. + Setting the :attr:`~type.__module__` attribute removes the + :attr:`!__firstlineno__` item from the type's dictionary. + + .. versionadded:: 3.13 + + * - .. attribute:: type.__mro__ + - The :class:`tuple` of classes that are considered when looking for + base classes during method resolution. + + +Special methods +^^^^^^^^^^^^^^^ + +In addition to the special attributes described above, all Python classes also +have the following two methods available: + +.. method:: type.mro + + This method can be overridden by a metaclass to customize the method + resolution order for its instances. It is called at class instantiation, + and its result is stored in :attr:`~type.__mro__`. + +.. method:: type.__subclasses__ + + Each class keeps a list of weak references to its immediate subclasses. This + method returns a list of all those references still alive. The list is in + definition order. Example: + + .. doctest:: + + >>> class A: pass + >>> class B(A): pass + >>> A.__subclasses__() + [<class 'B'>] + +Class instances +--------------- + +.. index:: + pair: object; class instance + pair: object; instance + pair: class; instance + pair: class instance; attribute + +A class instance is created by calling a class object (see above). A class +instance has a namespace implemented as a dictionary which is the first place +in which attribute references are searched. When an attribute is not found +there, and the instance's class has an attribute by that name, the search +continues with the class attributes. If a class attribute is found that is a +user-defined function object, it is transformed into an instance method +object whose :attr:`~method.__self__` attribute is the instance. Static method and +class method objects are also transformed; see above under "Classes". See +section :ref:`descriptors` for another way in which attributes of a class +retrieved via its instances may differ from the objects actually stored in +the class's :attr:`~object.__dict__`. If no class attribute is found, and the +object's class has a :meth:`~object.__getattr__` method, that is called to satisfy +the lookup. + +.. index:: triple: class instance; attribute; assignment + +Attribute assignments and deletions update the instance's dictionary, never a +class's dictionary. If the class has a :meth:`~object.__setattr__` or +:meth:`~object.__delattr__` method, this is called instead of updating the instance +dictionary directly. + +.. index:: + pair: object; numeric + pair: object; sequence + pair: object; mapping + +Class instances can pretend to be numbers, sequences, or mappings if they have +methods with certain special names. See section :ref:`specialnames`. + +Special attributes +^^^^^^^^^^^^^^^^^^ + +.. index:: + single: __dict__ (instance attribute) + single: __class__ (instance attribute) + +.. attribute:: object.__class__ + + The class to which a class instance belongs. + +.. attribute:: object.__dict__ + + A dictionary or other mapping object used to store an object's (writable) + attributes. Not all instances have a :attr:`!__dict__` attribute; see the + section on :ref:`slots` for more details. + + +I/O objects (also known as file objects) +---------------------------------------- + +.. index:: + pair: built-in function; open + pair: module; io + single: popen() (in module os) + single: makefile() (socket method) + single: sys.stdin + single: sys.stdout + single: sys.stderr + single: stdio + single: stdin (in module sys) + single: stdout (in module sys) + single: stderr (in module sys) + +A :term:`file object` represents an open file. Various shortcuts are +available to create file objects: the :func:`open` built-in function, and +also :func:`os.popen`, :func:`os.fdopen`, and the +:meth:`~socket.socket.makefile` method of socket objects (and perhaps by +other functions or methods provided by extension modules). + +File objects implement common methods, listed below, to simplify usage in +generic code. They are expected to be :ref:`context-managers`. + +The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are +initialized to file objects corresponding to the interpreter's standard +input, output and error streams; they are all open in text mode and +therefore follow the interface defined by the :class:`io.TextIOBase` +abstract class. + +.. method:: file.read(size=-1, /) + + Retrieve up to *size* data from the file. As a convenience if *size* is + unspecified or -1 retrieve all data available. + +.. method:: file.write(data, /) + + Store *data* to the file. + +.. method:: file.close() + + Flush any buffers and close the underlying file. + + +Internal types +-------------- + +.. index:: + single: internal type + single: types, internal + +A few types used internally by the interpreter are exposed to the user. Their +definitions may change with future versions of the interpreter, but they are +mentioned here for completeness. + + +.. _code-objects: + +Code objects +^^^^^^^^^^^^ + +.. index:: bytecode, object; code, code object + +Code objects represent *byte-compiled* executable Python code, or :term:`bytecode`. +The difference between a code object and a function object is that the function +object contains an explicit reference to the function's globals (the module in +which it was defined), while a code object contains no context; also the default +argument values are stored in the function object, not in the code object +(because they represent values calculated at run-time). Unlike function +objects, code objects are immutable and contain no references (directly or +indirectly) to mutable objects. + +.. index:: + single: co_argcount (code object attribute) + single: co_posonlyargcount (code object attribute) + single: co_kwonlyargcount (code object attribute) + single: co_code (code object attribute) + single: co_consts (code object attribute) + single: co_filename (code object attribute) + single: co_firstlineno (code object attribute) + single: co_flags (code object attribute) + single: co_name (code object attribute) + single: co_names (code object attribute) + single: co_nlocals (code object attribute) + single: co_stacksize (code object attribute) + single: co_varnames (code object attribute) + single: co_cellvars (code object attribute) + single: co_freevars (code object attribute) + single: co_qualname (code object attribute) + +Special read-only attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + + * - .. attribute:: codeobject.co_name + - The function name + + * - .. attribute:: codeobject.co_qualname + - The fully qualified function name + + .. versionadded:: 3.11 + + * - .. attribute:: codeobject.co_argcount + - The total number of positional :term:`parameters <parameter>` + (including positional-only parameters and parameters with default values) + that the function has + + * - .. attribute:: codeobject.co_posonlyargcount + - The number of positional-only :term:`parameters <parameter>` + (including arguments with default values) that the function has + + * - .. attribute:: codeobject.co_kwonlyargcount + - The number of keyword-only :term:`parameters <parameter>` + (including arguments with default values) that the function has + + * - .. attribute:: codeobject.co_nlocals + - The number of :ref:`local variables <naming>` used by the function + (including parameters) + + * - .. attribute:: codeobject.co_varnames + - A :class:`tuple` containing the names of the local variables in the + function (starting with the parameter names) + + * - .. attribute:: codeobject.co_cellvars + - A :class:`tuple` containing the names of :ref:`local variables <naming>` + that are referenced from at least one :term:`nested scope` inside the function + + * - .. attribute:: codeobject.co_freevars + - A :class:`tuple` containing the names of + :term:`free (closure) variables <closure variable>` that a :term:`nested scope` + references in an outer scope. See also :attr:`function.__closure__`. + + Note: references to global and builtin names are *not* included. + + * - .. attribute:: codeobject.co_code + - A string representing the sequence of :term:`bytecode` instructions in + the function + + * - .. attribute:: codeobject.co_consts + - A :class:`tuple` containing the literals used by the :term:`bytecode` in + the function + + * - .. attribute:: codeobject.co_names + - A :class:`tuple` containing the names used by the :term:`bytecode` in + the function + + * - .. attribute:: codeobject.co_filename + - The name of the file from which the code was compiled + + * - .. attribute:: codeobject.co_firstlineno + - The line number of the first line of the function + + * - .. attribute:: codeobject.co_stacksize + - The required stack size of the code object + + * - .. attribute:: codeobject.co_flags + - An :class:`integer <int>` encoding a number of flags for the + interpreter. + +.. index:: pair: object; generator + +The following flag bits are defined for :attr:`~codeobject.co_flags`: +bit ``0x04`` is set if +the function uses the ``*arguments`` syntax to accept an arbitrary number of +positional arguments; bit ``0x08`` is set if the function uses the +``**keywords`` syntax to accept arbitrary keyword arguments; bit ``0x20`` is set +if the function is a generator. See :ref:`inspect-module-co-flags` for details +on the semantics of each flags that might be present. + +Future feature declarations (for example, ``from __future__ import division``) also use bits +in :attr:`~codeobject.co_flags` to indicate whether a code object was compiled with a +particular feature enabled. See :attr:`~__future__._Feature.compiler_flag`. + +Other bits in :attr:`~codeobject.co_flags` are reserved for internal use. + +.. index:: single: documentation string + +If a code object represents a function and has a docstring, +the :data:`~inspect.CO_HAS_DOCSTRING` bit is set in :attr:`~codeobject.co_flags` +and the first item in :attr:`~codeobject.co_consts` is +the docstring of the function. + +Methods on code objects +~~~~~~~~~~~~~~~~~~~~~~~ + +.. method:: codeobject.co_positions() + + Returns an iterable over the source code positions of each :term:`bytecode` + instruction in the code object. + + The iterator returns :class:`tuple`\s containing the ``(start_line, end_line, + start_column, end_column)``. The *i-th* tuple corresponds to the + position of the source code that compiled to the *i-th* code unit. + Column information is 0-indexed utf-8 byte offsets on the given source + line. + + This positional information can be missing. A non-exhaustive lists of + cases where this may happen: + + - Running the interpreter with :option:`-X` ``no_debug_ranges``. + - Loading a pyc file compiled while using :option:`-X` ``no_debug_ranges``. + - Position tuples corresponding to artificial instructions. + - Line and column numbers that can't be represented due to + implementation specific limitations. + + When this occurs, some or all of the tuple elements can be + :const:`None`. + + .. versionadded:: 3.11 + + .. note:: + This feature requires storing column positions in code objects which may + result in a small increase of disk usage of compiled Python files or + interpreter memory usage. To avoid storing the extra information and/or + deactivate printing the extra traceback information, the + :option:`-X` ``no_debug_ranges`` command line flag or the :envvar:`PYTHONNODEBUGRANGES` + environment variable can be used. + +.. method:: codeobject.co_lines() + + Returns an iterator that yields information about successive ranges of + :term:`bytecode`\s. Each item yielded is a ``(start, end, lineno)`` + :class:`tuple`: + + * ``start`` (an :class:`int`) represents the offset (inclusive) of the start + of the :term:`bytecode` range + * ``end`` (an :class:`int`) represents the offset (exclusive) of the end of + the :term:`bytecode` range + * ``lineno`` is an :class:`int` representing the line number of the + :term:`bytecode` range, or ``None`` if the bytecodes in the given range + have no line number + + The items yielded will have the following properties: + + * The first range yielded will have a ``start`` of 0. + * The ``(start, end)`` ranges will be non-decreasing and consecutive. That + is, for any pair of :class:`tuple`\s, the ``start`` of the second will be + equal to the ``end`` of the first. + * No range will be backwards: ``end >= start`` for all triples. + * The last :class:`tuple` yielded will have ``end`` equal to the size of the + :term:`bytecode`. + + Zero-width ranges, where ``start == end``, are allowed. Zero-width ranges + are used for lines that are present in the source code, but have been + eliminated by the :term:`bytecode` compiler. + + .. versionadded:: 3.10 + + .. seealso:: + + :pep:`626` - Precise line numbers for debugging and other tools. + The PEP that introduced the :meth:`!co_lines` method. + +.. method:: codeobject.replace(**kwargs) + + Return a copy of the code object with new values for the specified fields. + + Code objects are also supported by the generic function :func:`copy.replace`. + + .. versionadded:: 3.8 + + +.. _frame-objects: + +Frame objects +^^^^^^^^^^^^^ + +.. index:: pair: object; frame + +Frame objects represent execution frames. They may occur in +:ref:`traceback objects <traceback-objects>`, +and are also passed to registered trace functions. + +.. index:: + single: f_back (frame attribute) + single: f_code (frame attribute) + single: f_globals (frame attribute) + single: f_locals (frame attribute) + single: f_lasti (frame attribute) + single: f_builtins (frame attribute) + single: f_generator (frame attribute) + +Special read-only attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + + * - .. attribute:: frame.f_back + - Points to the previous stack frame (towards the caller), + or ``None`` if this is the bottom stack frame + + * - .. attribute:: frame.f_code + - The :ref:`code object <code-objects>` being executed in this frame. + Accessing this attribute raises an :ref:`auditing event <auditing>` + ``object.__getattr__`` with arguments ``obj`` and ``"f_code"``. + + * - .. attribute:: frame.f_locals + - The mapping used by the frame to look up + :ref:`local variables <naming>`. + If the frame refers to an :term:`optimized scope`, + this may return a write-through proxy object. + + .. versionchanged:: 3.13 + Return a proxy for optimized scopes. + + * - .. attribute:: frame.f_globals + - The dictionary used by the frame to look up + :ref:`global variables <naming>` + + * - .. attribute:: frame.f_builtins + - The dictionary used by the frame to look up + :ref:`built-in (intrinsic) names <naming>` + + * - .. attribute:: frame.f_lasti + - The "precise instruction" of the frame object + (this is an index into the :term:`bytecode` string of the + :ref:`code object <code-objects>`) + + * - .. attribute:: frame.f_generator + - The :term:`generator` or :term:`coroutine` object that owns this frame, + or ``None`` if the frame is a normal function. + + .. versionadded:: 3.14 + +.. index:: + single: f_trace (frame attribute) + single: f_trace_lines (frame attribute) + single: f_trace_opcodes (frame attribute) + single: f_lineno (frame attribute) + +Special writable attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + + * - .. attribute:: frame.f_trace + - If not ``None``, this is a function called for various events during + code execution (this is used by debuggers). Normally an event is + triggered for each new source line (see :attr:`~frame.f_trace_lines`). + + * - .. attribute:: frame.f_trace_lines + - Set this attribute to :const:`False` to disable triggering a tracing + event for each source line. + + * - .. attribute:: frame.f_trace_opcodes + - Set this attribute to :const:`True` to allow per-opcode events to be + requested. Note that this may lead to + undefined interpreter behaviour if exceptions raised by the trace + function escape to the function being traced. + + * - .. attribute:: frame.f_lineno + - The current line number of the frame -- writing to this + from within a trace function jumps to the given line (only for the bottom-most + frame). A debugger can implement a Jump command (aka Set Next Statement) + by writing to this attribute. + +Frame object methods +~~~~~~~~~~~~~~~~~~~~ + +Frame objects support one method: + +.. method:: frame.clear() + + This method clears all references to :ref:`local variables <naming>` held by the + frame. Also, if the frame belonged to a :term:`generator`, the generator + is finalized. This helps break reference cycles involving frame + objects (for example when catching an :ref:`exception <bltin-exceptions>` + and storing its :ref:`traceback <traceback-objects>` for later use). + + :exc:`RuntimeError` is raised if the frame is currently executing + or suspended. + + .. versionadded:: 3.4 + + .. versionchanged:: 3.13 + Attempting to clear a suspended frame raises :exc:`RuntimeError` + (as has always been the case for executing frames). + + +.. _traceback-objects: + +Traceback objects +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; traceback + pair: stack; trace + pair: exception; handler + pair: execution; stack + single: exc_info (in module sys) + single: last_traceback (in module sys) + single: sys.exc_info + single: sys.exception + single: sys.last_traceback + +Traceback objects represent the stack trace of an :ref:`exception <tut-errors>`. +A traceback object +is implicitly created when an exception occurs, and may also be explicitly +created by calling :class:`types.TracebackType`. + +.. versionchanged:: 3.7 + Traceback objects can now be explicitly instantiated from Python code. + +For implicitly created tracebacks, when the search for an exception handler +unwinds the execution stack, at each unwound level a traceback object is +inserted in front of the current traceback. When an exception handler is +entered, the stack trace is made available to the program. (See section +:ref:`try`.) It is accessible as the third item of the +tuple returned by :func:`sys.exc_info`, and as the +:attr:`~BaseException.__traceback__` attribute +of the caught exception. + +When the program contains no suitable +handler, the stack trace is written (nicely formatted) to the standard error +stream; if the interpreter is interactive, it is also made available to the user +as :data:`sys.last_traceback`. + +For explicitly created tracebacks, it is up to the creator of the traceback +to determine how the :attr:`~traceback.tb_next` attributes should be linked to +form a full stack trace. + +.. index:: + single: tb_frame (traceback attribute) + single: tb_lineno (traceback attribute) + single: tb_lasti (traceback attribute) + pair: statement; try + +Special read-only attributes: + +.. list-table:: + + * - .. attribute:: traceback.tb_frame + - Points to the execution :ref:`frame <frame-objects>` of the current + level. + + Accessing this attribute raises an + :ref:`auditing event <auditing>` ``object.__getattr__`` with arguments + ``obj`` and ``"tb_frame"``. + + * - .. attribute:: traceback.tb_lineno + - Gives the line number where the exception occurred + + * - .. attribute:: traceback.tb_lasti + - Indicates the "precise instruction". + +The line number and last instruction in the traceback may differ from the +line number of its :ref:`frame object <frame-objects>` if the exception +occurred in a +:keyword:`try` statement with no matching except clause or with a +:keyword:`finally` clause. + +.. index:: + single: tb_next (traceback attribute) + +.. attribute:: traceback.tb_next + + The special writable attribute :attr:`!tb_next` is the next level in the + stack trace (towards the frame where the exception occurred), or ``None`` if + there is no next level. + + .. versionchanged:: 3.7 + This attribute is now writable + + +Slice objects +^^^^^^^^^^^^^ + +.. index:: pair: built-in function; slice + +Slice objects are used to represent slices for +:meth:`~object.__getitem__` +methods. They are also created by the built-in :func:`slice` function. + +.. versionadded:: 3.15 + + The :func:`slice` type now supports :ref:`subscription <subscriptions>`. For + example, ``slice[float]`` may be used in type annotations to indicate a slice + containing :type:`float` objects. + +.. index:: + single: start (slice object attribute) + single: stop (slice object attribute) + single: step (slice object attribute) + +Special read-only attributes: :attr:`~slice.start` is the lower bound; +:attr:`~slice.stop` is the upper bound; :attr:`~slice.step` is the step +value; each is ``None`` if omitted. These attributes can have any type. + +Slice objects support one method: + +.. method:: slice.indices(self, length) + + This method takes a single integer argument *length* and computes + information about the slice that the slice object would describe if + applied to a sequence of *length* items. It returns a tuple of three + integers; respectively these are the *start* and *stop* indices and the + *step* or stride length of the slice. Missing or out-of-bounds indices + are handled in a manner consistent with regular slices. + + +Static method objects +^^^^^^^^^^^^^^^^^^^^^ + +Static method objects provide a way of defeating the transformation of function +objects to method objects described above. A static method object is a wrapper +around any other object, usually a user-defined method object. When a static +method object is retrieved from a class or a class instance, the object actually +returned is the wrapped object, which is not subject to any further +transformation. Static method objects are also callable. Static method +objects are created by the built-in :func:`staticmethod` constructor. + + +Class method objects +^^^^^^^^^^^^^^^^^^^^ + +A class method object, like a static method object, is a wrapper around another +object that alters the way in which that object is retrieved from classes and +class instances. The behaviour of class method objects upon such retrieval is +described above, under :ref:`"instance methods" <instance-methods>`. Class method objects are created +by the built-in :func:`classmethod` constructor. + + +.. _specialnames: + +Special method names +==================== + +.. index:: + pair: operator; overloading + single: __getitem__() (mapping object method) + +A class can implement certain operations that are invoked by special syntax +(such as arithmetic operations or subscripting and slicing) by defining methods +with special names. This is Python's approach to :dfn:`operator overloading`, +allowing classes to define their own behavior with respect to language +operators. For instance, if a class defines a method named +:meth:`~object.__getitem__`, +and ``x`` is an instance of this class, then ``x[i]`` is roughly equivalent +to ``type(x).__getitem__(x, i)``. Except where mentioned, attempts to execute an +operation raise an exception when no appropriate method is defined (typically +:exc:`AttributeError` or :exc:`TypeError`). + +Setting a special method to ``None`` indicates that the corresponding +operation is not available. For example, if a class sets +:meth:`~object.__iter__` to ``None``, the class is not iterable, so calling +:func:`iter` on its instances will raise a :exc:`TypeError` (without +falling back to :meth:`~object.__getitem__`). [#]_ + +When implementing a class that emulates any built-in type, it is important that +the emulation only be implemented to the degree that it makes sense for the +object being modelled. For example, some sequences may work well with retrieval +of individual elements, but extracting a slice may not make sense. +(One example of this is the :ref:`NodeList <dom-nodelist-objects>` interface +in the W3C's Document Object Model.) + + +.. _customization: + +Basic customization +------------------- + +.. method:: object.__new__(cls[, ...]) + + .. index:: pair: subclassing; immutable types + + Called to create a new instance of class *cls*. :meth:`__new__` is a static + method (special-cased so you need not declare it as such) that takes the class + of which an instance was requested as its first argument. The remaining + arguments are those passed to the object constructor expression (the call to the + class). The return value of :meth:`__new__` should be the new object instance + (usually an instance of *cls*). + + Typical implementations create a new instance of the class by invoking the + superclass's :meth:`__new__` method using ``super().__new__(cls[, ...])`` + with appropriate arguments and then modifying the newly created instance + as necessary before returning it. + + If :meth:`__new__` is invoked during object construction and it returns an + instance of *cls*, then the new instance’s :meth:`__init__` method + will be invoked like ``__init__(self[, ...])``, where *self* is the new instance + and the remaining arguments are the same as were passed to the object constructor. + + If :meth:`__new__` does not return an instance of *cls*, then the new instance's + :meth:`__init__` method will not be invoked. + + :meth:`__new__` is intended mainly to allow subclasses of immutable types (like + int, str, or tuple) to customize instance creation. It is also commonly + overridden in custom metaclasses in order to customize class creation. + + +.. method:: object.__init__(self[, ...]) + + .. index:: pair: class; constructor + + Called after the instance has been created (by :meth:`__new__`), but before + it is returned to the caller. The arguments are those passed to the + class constructor expression. If a base class has an :meth:`__init__` + method, the derived class's :meth:`__init__` method, if any, must explicitly + call it to ensure proper initialization of the base class part of the + instance; for example: ``super().__init__([args...])``. + + Because :meth:`__new__` and :meth:`__init__` work together in constructing + objects (:meth:`__new__` to create it, and :meth:`__init__` to customize it), + no non-``None`` value may be returned by :meth:`__init__`; doing so will + cause a :exc:`TypeError` to be raised at runtime. + + +.. method:: object.__del__(self) + + .. index:: + single: destructor + single: finalizer + pair: statement; del + + Called when the instance is about to be destroyed. This is also called a + finalizer or (improperly) a destructor. If a base class has a + :meth:`__del__` method, the derived class's :meth:`__del__` method, + if any, must explicitly call it to ensure proper deletion of the base + class part of the instance. + + It is possible (though not recommended!) for the :meth:`__del__` method + to postpone destruction of the instance by creating a new reference to + it. This is called object *resurrection*. It is implementation-dependent + whether :meth:`__del__` is called a second time when a resurrected object + is about to be destroyed; the current :term:`CPython` implementation + only calls it once. + + It is not guaranteed that :meth:`__del__` methods are called for objects + that still exist when the interpreter exits. + :class:`weakref.finalize` provides a straightforward way to register + a cleanup function to be called when an object is garbage collected. + + .. note:: + + ``del x`` doesn't directly call ``x.__del__()`` --- the former decrements + the reference count for ``x`` by one, and the latter is only called when + ``x``'s reference count reaches zero. + + .. impl-detail:: + It is possible for a reference cycle to prevent the reference count + of an object from going to zero. In this case, the cycle will be + later detected and deleted by the :term:`cyclic garbage collector + <garbage collection>`. A common cause of reference cycles is when + an exception has been caught in a local variable. The frame's + locals then reference the exception, which references its own + traceback, which references the locals of all frames caught in the + traceback. + + .. seealso:: + Documentation for the :mod:`gc` module. + + .. warning:: + + Due to the precarious circumstances under which :meth:`__del__` methods are + invoked, exceptions that occur during their execution are ignored, and a warning + is printed to ``sys.stderr`` instead. In particular: + + * :meth:`__del__` can be invoked when arbitrary code is being executed, + including from any arbitrary thread. If :meth:`__del__` needs to take + a lock or invoke any other blocking resource, it may deadlock as + the resource may already be taken by the code that gets interrupted + to execute :meth:`__del__`. + + * :meth:`__del__` can be executed during interpreter shutdown. As a + consequence, the global variables it needs to access (including other + modules) may already have been deleted or set to ``None``. Python + guarantees that globals whose name begins with a single underscore + are deleted from their module before other globals are deleted; if + no other references to such globals exist, this may help in assuring + that imported modules are still available at the time when the + :meth:`__del__` method is called. + + + .. index:: + single: repr() (built-in function); __repr__() (object method) + +.. method:: object.__repr__(self) + + Called by the :func:`repr` built-in function to compute the "official" string + representation of an object. If at all possible, this should look like a + valid Python expression that could be used to recreate an object with the + same value (given an appropriate environment). If this is not possible, a + string of the form ``<...some useful description...>`` should be returned. + The return value must be a string object. If a class defines :meth:`__repr__` + but not :meth:`__str__`, then :meth:`__repr__` is also used when an + "informal" string representation of instances of that class is required. + + This is typically used for debugging, so it is important that the representation + is information-rich and unambiguous. A default implementation is provided by the + :class:`object` class itself. + + .. index:: + single: string; __str__() (object method) + single: format() (built-in function); __str__() (object method) + single: print() (built-in function); __str__() (object method) + + +.. method:: object.__str__(self) + + Called by :func:`str(object) <str>`, the default :meth:`__format__` implementation, + and the built-in function :func:`print`, to compute the "informal" or nicely + printable string representation of an object. The return value must be a + :ref:`str <textseq>` object. + + This method differs from :meth:`object.__repr__` in that there is no + expectation that :meth:`__str__` return a valid Python expression: a more + convenient or concise representation can be used. + + The default implementation defined by the built-in type :class:`object` + calls :meth:`object.__repr__`. + + .. XXX what about subclasses of string? + + +.. method:: object.__bytes__(self) + + .. index:: pair: built-in function; bytes + + Called by :ref:`bytes <func-bytes>` to compute a byte-string representation + of an object. This should return a :class:`bytes` object. The :class:`object` + class itself does not provide this method. + + .. index:: + single: string; __format__() (object method) + pair: string; conversion + pair: built-in function; print + + +.. method:: object.__format__(self, format_spec) + + Called by the :func:`format` built-in function, + and by extension, evaluation of :ref:`formatted string literals + <f-strings>` and the :meth:`str.format` method, to produce a "formatted" + string representation of an object. The *format_spec* argument is + a string that contains a description of the formatting options desired. + The interpretation of the *format_spec* argument is up to the type + implementing :meth:`__format__`, however most classes will either + delegate formatting to one of the built-in types, or use a similar + formatting option syntax. + + See :ref:`formatspec` for a description of the standard formatting syntax. + + The return value must be a string object. + + The default implementation by the :class:`object` class should be given + an empty *format_spec* string. It delegates to :meth:`__str__`. + + .. versionchanged:: 3.4 + The __format__ method of ``object`` itself raises a :exc:`TypeError` + if passed any non-empty string. + + .. versionchanged:: 3.7 + ``object.__format__(x, '')`` is now equivalent to ``str(x)`` rather + than ``format(str(x), '')``. + + +.. _richcmpfuncs: +.. method:: object.__lt__(self, other) + object.__le__(self, other) + object.__eq__(self, other) + object.__ne__(self, other) + object.__gt__(self, other) + object.__ge__(self, other) + + .. index:: + single: comparisons + + These are the so-called "rich comparison" methods. The correspondence between + operator symbols and method names is as follows: ``x<y`` calls ``x.__lt__(y)``, + ``x<=y`` calls ``x.__le__(y)``, ``x==y`` calls ``x.__eq__(y)``, ``x!=y`` calls + ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and ``x>=y`` calls + ``x.__ge__(y)``. + + A rich comparison method may return the singleton :data:`NotImplemented` if it does + not implement the operation for a given pair of arguments. By convention, + ``False`` and ``True`` are returned for a successful comparison. However, these + methods can return any value, so if the comparison operator is used in a Boolean + context (e.g., in the condition of an ``if`` statement), Python will call + :func:`bool` on the value to determine if the result is true or false. + + By default, ``object`` implements :meth:`__eq__` by using ``is``, returning + :data:`NotImplemented` in the case of a false comparison: + ``True if x is y else NotImplemented``. For :meth:`__ne__`, by default it + delegates to :meth:`__eq__` and inverts the result unless it is + :data:`!NotImplemented`. There are no other implied relationships among the + comparison operators or default implementations; for example, the truth of + ``(x<y or x==y)`` does not imply ``x<=y``. To automatically generate ordering + operations from a single root operation, see :deco:`functools.total_ordering`. + + By default, the :class:`object` class provides implementations consistent + with :ref:`expressions-value-comparisons`: equality compares according to + object identity, and order comparisons raise :exc:`TypeError`. Each default + method may generate these results directly, but may also return + :data:`NotImplemented`. + + See the paragraph on :meth:`__hash__` for + some important notes on creating :term:`hashable` objects which support + custom comparison operations and are usable as dictionary keys. + + There are no swapped-argument versions of these methods (to be used when the + left argument does not support the operation but the right argument does); + rather, :meth:`__lt__` and :meth:`__gt__` are each other's reflection, + :meth:`__le__` and :meth:`__ge__` are each other's reflection, and + :meth:`__eq__` and :meth:`__ne__` are their own reflection. + If the operands are of different types, and the right operand's type is + a direct or indirect subclass of the left operand's type, + the reflected method of the right operand has priority, otherwise + the left operand's method has priority. Virtual subclassing is + not considered. + + When no appropriate method returns any value other than :data:`NotImplemented`, the + ``==`` and ``!=`` operators will fall back to ``is`` and ``is not``, respectively. + +.. method:: object.__hash__(self) + + .. index:: + pair: object; dictionary + pair: built-in function; hash + + Called by built-in function :func:`hash` and for operations on members of + hashed collections including :class:`set`, :class:`frozenset`, :class:`dict`, + and :class:`frozendict`. The ``__hash__()`` method should return an integer. + The only required property is that objects which compare equal have the same + hash value; it is advised to mix together the hash values of the components + of the object that also play a part in comparison of objects by packing them + into a tuple and hashing the tuple. Example:: + + def __hash__(self): + return hash((self.name, self.nick, self.color)) + + .. note:: + + :func:`hash` truncates the value returned from an object's custom + :meth:`__hash__` method to the size of a :c:type:`Py_ssize_t`. This is + typically 8 bytes on 64-bit builds and 4 bytes on 32-bit builds. If an + object's :meth:`__hash__` must interoperate on builds of different bit + sizes, be sure to check the width on all supported builds. An easy way + to do this is with + ``python -c "import sys; print(sys.hash_info.width)"``. + + If a class does not define an :meth:`__eq__` method it should not define a + :meth:`__hash__` operation either; if it defines :meth:`__eq__` but not + :meth:`__hash__`, its instances will not be usable as items in hashable + collections. If a class defines mutable objects and implements an + :meth:`__eq__` method, it should not implement :meth:`__hash__`, since the + implementation of :term:`hashable` collections requires that a key's hash value is + immutable (if the object's hash value changes, it will be in the wrong hash + bucket). + + User-defined classes have :meth:`__eq__` and :meth:`__hash__` methods + by default (inherited from the :class:`object` class); with them, all objects compare + unequal (except with themselves) and ``x.__hash__()`` returns an appropriate + value such that ``x == y`` implies both that ``x is y`` and ``hash(x) == hash(y)``. + + A class that overrides :meth:`__eq__` and does not define :meth:`__hash__` + will have its :meth:`__hash__` implicitly set to ``None``. When the + :meth:`__hash__` method of a class is ``None``, instances of the class will + raise an appropriate :exc:`TypeError` when a program attempts to retrieve + their hash value, and will also be correctly identified as unhashable when + checking ``isinstance(obj, collections.abc.Hashable)``. + + If a class that overrides :meth:`__eq__` needs to retain the implementation + of :meth:`__hash__` from a parent class, the interpreter must be told this + explicitly by setting ``__hash__ = <ParentClass>.__hash__``. + + If a class that does not override :meth:`__eq__` wishes to suppress hash + support, it should include ``__hash__ = None`` in the class definition. + A class which defines its own :meth:`__hash__` that explicitly raises + a :exc:`TypeError` would be incorrectly identified as hashable by + an ``isinstance(obj, collections.abc.Hashable)`` call. + + + .. note:: + + By default, the :meth:`__hash__` values of str and bytes objects are + "salted" with an unpredictable random value. Although they + remain constant within an individual Python process, they are not + predictable between repeated invocations of Python. + + This is intended to provide protection against a denial-of-service caused + by carefully chosen inputs that exploit the worst case performance of a + dict insertion, *O*\ (*n*\ :sup:`2`) complexity. See + https://ocert.org/advisories/ocert-2011-003.html for details. + + Changing hash values affects the iteration order of sets. + Python has never made guarantees about this ordering + (and it typically varies between 32-bit and 64-bit builds). + + See also :envvar:`PYTHONHASHSEED`. + + .. versionchanged:: 3.3 + Hash randomization is enabled by default. + + +.. method:: object.__bool__(self) + + .. index:: single: __len__() (mapping object method) + + Called to implement truth value testing and the built-in operation + ``bool()``; should return ``False`` or ``True``. When this method is not + defined, :meth:`~object.__len__` is called, if it is defined, and the object is + considered true if its result is nonzero. If a class defines neither + :meth:`!__len__` nor :meth:`!__bool__` (which is true of the :class:`object` + class itself), all its instances are considered true. + + +.. _attribute-access: + +Customizing attribute access +---------------------------- + +The following methods can be defined to customize the meaning of attribute +access (use of, assignment to, or deletion of ``x.name``) for class instances. + +.. XXX explain how descriptors interfere here! + + +.. method:: object.__getattr__(self, name) + + Called when the default attribute access fails with an :exc:`AttributeError` + (either :meth:`__getattribute__` raises an :exc:`AttributeError` because + *name* is not an instance attribute or an attribute in the class tree + for ``self``; or :meth:`__get__` of a *name* property raises + :exc:`AttributeError`). This method should either return the (computed) + attribute value or raise an :exc:`AttributeError` exception. + The :class:`object` class itself does not provide this method. + + Note that if the attribute is found through the normal mechanism, + :meth:`__getattr__` is not called. (This is an intentional asymmetry between + :meth:`__getattr__` and :meth:`__setattr__`.) This is done both for efficiency + reasons and because otherwise :meth:`__getattr__` would have no way to access + other attributes of the instance. Note that at least for instance variables, + you can take total control by not inserting any values in the instance attribute + dictionary (but instead inserting them in another object). See the + :meth:`__getattribute__` method below for a way to actually get total control + over attribute access. + + +.. method:: object.__getattribute__(self, name) + + Called unconditionally to implement attribute accesses for instances of the + class. If the class also defines :meth:`__getattr__`, the latter will not be + called unless :meth:`__getattribute__` either calls it explicitly or raises an + :exc:`AttributeError`. This method should return the (computed) attribute value + or raise an :exc:`AttributeError` exception. In order to avoid infinite + recursion in this method, its implementation should always call the base class + method with the same name to access any attributes it needs, for example, + ``object.__getattribute__(self, name)``. + + .. note:: + + This method may still be bypassed when looking up special methods as the + result of implicit invocation via language syntax or + :ref:`built-in functions <builtin-functions>`. + See :ref:`special-lookup`. + + .. audit-event:: object.__getattr__ obj,name object.__getattribute__ + + For certain sensitive attribute accesses, raises an + :ref:`auditing event <auditing>` ``object.__getattr__`` with arguments + ``obj`` and ``name``. + + +.. method:: object.__setattr__(self, name, value) + + Called when an attribute assignment is attempted. This is called instead of + the normal mechanism (i.e. store the value in the instance dictionary). + *name* is the attribute name, *value* is the value to be assigned to it. + + If :meth:`__setattr__` wants to assign to an instance attribute, it should + call the base class method with the same name, for example, + ``object.__setattr__(self, name, value)``. + + .. audit-event:: object.__setattr__ obj,name,value object.__setattr__ + + For certain sensitive attribute assignments, raises an + :ref:`auditing event <auditing>` ``object.__setattr__`` with arguments + ``obj``, ``name``, ``value``. + + +.. method:: object.__delattr__(self, name) + + Like :meth:`__setattr__` but for attribute deletion instead of assignment. This + should only be implemented if ``del obj.name`` is meaningful for the object. + + .. audit-event:: object.__delattr__ obj,name object.__delattr__ + + For certain sensitive attribute deletions, raises an + :ref:`auditing event <auditing>` ``object.__delattr__`` with arguments + ``obj`` and ``name``. + + +.. method:: object.__dir__(self) + + Called when :func:`dir` is called on the object. An iterable must be + returned. :func:`dir` converts the returned iterable to a list and sorts it. + + +Customizing module attribute access +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: __getattr__ (module attribute) + single: __dir__ (module attribute) + single: __class__ (module attribute) + +.. method:: module.__getattr__ + module.__dir__ + +Special names ``__getattr__`` and ``__dir__`` can be also used to customize +access to module attributes. The ``__getattr__`` function at the module level +should accept one argument which is the name of an attribute and return the +computed value or raise an :exc:`AttributeError`. If an attribute is +not found on a module object through the normal lookup, i.e. +:meth:`object.__getattribute__`, then ``__getattr__`` is searched in +the module ``__dict__`` before raising an :exc:`AttributeError`. If found, +it is called with the attribute name and the result is returned. + +The ``__dir__`` function should accept no arguments, and return an iterable of +strings that represents the names accessible on module. If present, this +function overrides the standard :func:`dir` search on a module. + +.. attribute:: module.__class__ + +For a more fine grained customization of the module behavior (setting +attributes, properties, etc.), one can set the ``__class__`` attribute of +a module object to a subclass of :class:`types.ModuleType`. For example:: + + import sys + from types import ModuleType + + class VerboseModule(ModuleType): + def __repr__(self): + return f'Verbose {self.__name__}' + + def __setattr__(self, attr, value): + print(f'Setting {attr}...') + super().__setattr__(attr, value) + + sys.modules[__name__].__class__ = VerboseModule + +.. note:: + Defining module ``__getattr__`` and setting module ``__class__`` only + affect lookups made using the attribute access syntax -- directly accessing + the module globals (whether by code within the module, or via a reference + to the module's globals dictionary) is unaffected. + +.. versionchanged:: 3.5 + ``__class__`` module attribute is now writable. + +.. versionadded:: 3.7 + ``__getattr__`` and ``__dir__`` module attributes. + +.. seealso:: + + :pep:`562` - Module __getattr__ and __dir__ + Describes the ``__getattr__`` and ``__dir__`` functions on modules. + + +.. _descriptors: + +Implementing Descriptors +^^^^^^^^^^^^^^^^^^^^^^^^ + +The following methods only apply when an instance of the class containing the +method (a so-called *descriptor* class) appears in an *owner* class (the +descriptor must be in either the owner's class dictionary or in the class +dictionary for one of its parents). In the examples below, "the attribute" +refers to the attribute whose name is the key of the property in the owner +class' :attr:`~object.__dict__`. The :class:`object` class itself does not +implement any of these protocols. + +.. method:: object.__get__(self, instance, owner=None) + + Called to get the attribute of the owner class (class attribute access) or + of an instance of that class (instance attribute access). The optional + *owner* argument is the owner class, while *instance* is the instance that + the attribute was accessed through, or ``None`` when the attribute is + accessed through the *owner*. + + This method should return the computed attribute value or raise an + :exc:`AttributeError` exception. + + :PEP:`252` specifies that :meth:`__get__` is callable with one or two + arguments. Python's own built-in descriptors support this specification; + however, it is likely that some third-party tools have descriptors + that require both arguments. Python's own :meth:`__getattribute__` + implementation always passes in both arguments whether they are required + or not. + +.. method:: object.__set__(self, instance, value) + + Called to set the attribute on an instance *instance* of the owner class to a + new value, *value*. + + Note, adding :meth:`__set__` or :meth:`__delete__` changes the kind of + descriptor to a "data descriptor". See :ref:`descriptor-invocation` for + more details. + +.. method:: object.__delete__(self, instance) + + Called to delete the attribute on an instance *instance* of the owner class. + +Instances of descriptors may also have the :attr:`!__objclass__` attribute +present: + +.. attribute:: object.__objclass__ + + The attribute :attr:`!__objclass__` is interpreted by the :mod:`inspect` module + as specifying the class where this object was defined (setting this + appropriately can assist in runtime introspection of dynamic class attributes). + For callables, it may indicate that an instance of the given type (or a + subclass) is expected or required as the first positional argument (for example, + CPython sets this attribute for unbound methods that are implemented in C). + + +.. _descriptor-invocation: + +Invoking Descriptors +^^^^^^^^^^^^^^^^^^^^ + +In general, a descriptor is an object attribute with "binding behavior", one +whose attribute access has been overridden by methods in the descriptor +protocol: :meth:`~object.__get__`, :meth:`~object.__set__`, and +:meth:`~object.__delete__`. If any of +those methods are defined for an object, it is said to be a descriptor. + +The default behavior for attribute access is to get, set, or delete the +attribute from an object's dictionary. For instance, ``a.x`` has a lookup chain +starting with ``a.__dict__['x']``, then ``type(a).__dict__['x']``, and +continuing through the base classes of ``type(a)`` excluding metaclasses. + +However, if the looked-up value is an object defining one of the descriptor +methods, then Python may override the default behavior and invoke the descriptor +method instead. Where this occurs in the precedence chain depends on which +descriptor methods were defined and how they were called. + +The starting point for descriptor invocation is a binding, ``a.x``. How the +arguments are assembled depends on ``a``: + +Direct Call + The simplest and least common call is when user code directly invokes a + descriptor method: ``x.__get__(a)``. + +Instance Binding + If binding to an object instance, ``a.x`` is transformed into the call: + ``type(a).__dict__['x'].__get__(a, type(a))``. + +Class Binding + If binding to a class, ``A.x`` is transformed into the call: + ``A.__dict__['x'].__get__(None, A)``. + +Super Binding + A dotted lookup such as ``super(A, a).x`` searches + ``a.__class__.__mro__`` for a base class ``B`` following ``A`` and then + returns ``B.__dict__['x'].__get__(a, A)``. If not a descriptor, ``x`` is + returned unchanged. + +.. testcode:: + :hide: + + class Desc: + def __get__(*args): + return args + + class B: + + x = Desc() + + class A(B): + + x = 999 + + def m(self): + 'Demonstrate these two descriptor invocations are equivalent' + result1 = super(A, self).x + result2 = B.__dict__['x'].__get__(self, A) + return result1 == result2 + +.. doctest:: + :hide: + + >>> a = A() + >>> a.__class__.__mro__.index(B) > a.__class__.__mro__.index(A) + True + >>> super(A, a).x == B.__dict__['x'].__get__(a, A) + True + >>> a.m() + True + +For instance bindings, the precedence of descriptor invocation depends on +which descriptor methods are defined. A descriptor can define any combination +of :meth:`~object.__get__`, :meth:`~object.__set__` and +:meth:`~object.__delete__`. If it does not +define :meth:`!__get__`, then accessing the attribute will return the descriptor +object itself unless there is a value in the object's instance dictionary. If +the descriptor defines :meth:`!__set__` and/or :meth:`!__delete__`, it is a data +descriptor; if it defines neither, it is a non-data descriptor. Normally, data +descriptors define both :meth:`!__get__` and :meth:`!__set__`, while non-data +descriptors have just the :meth:`!__get__` method. Data descriptors with +:meth:`!__get__` and :meth:`!__set__` (and/or :meth:`!__delete__`) defined +always override a redefinition in an +instance dictionary. In contrast, non-data descriptors can be overridden by +instances. + +Python methods (including those decorated with +:deco:`staticmethod` and :deco:`classmethod`) are +implemented as non-data descriptors. Accordingly, instances can redefine and +override methods. This allows individual instances to acquire behaviors that +differ from other instances of the same class. + +The :deco:`property` decorator is implemented as a data descriptor. Accordingly, +instances cannot override the behavior of a property. + + +.. _slots: + +__slots__ +^^^^^^^^^ + +*__slots__* allow us to explicitly declare data members (like +properties) and deny the creation of :attr:`~object.__dict__` and *__weakref__* +(unless explicitly declared in *__slots__* or available in a parent.) + +The space saved over using :attr:`~object.__dict__` can be significant. +Attribute lookup speed can be significantly improved as well. + +.. data:: object.__slots__ + + This class variable can be assigned a string, iterable, or sequence of + strings with variable names used by instances. *__slots__* reserves space + for the declared variables and prevents the automatic creation of + :attr:`~object.__dict__` + and *__weakref__* for each instance. + + +.. _datamodel-note-slots: + +Notes on using *__slots__*: + +* When inheriting from a class without *__slots__*, the + :attr:`~object.__dict__` and + *__weakref__* attribute of the instances will always be accessible. + +* Without a :attr:`~object.__dict__` variable, instances cannot be assigned new + variables not + listed in the *__slots__* definition. Attempts to assign to an unlisted + variable name raises :exc:`AttributeError`. If dynamic assignment of new + variables is desired, then add ``'__dict__'`` to the sequence of strings in + the *__slots__* declaration. + +* Without a *__weakref__* variable for each instance, classes defining + *__slots__* do not support :mod:`weak references <weakref>` to its instances. + If weak reference + support is needed, then add ``'__weakref__'`` to the sequence of strings in the + *__slots__* declaration. + +* *__slots__* are implemented at the class level by creating :ref:`descriptors <descriptors>` + for each variable name. As a result, class attributes + cannot be used to set default values for instance variables defined by + *__slots__*; otherwise, the class attribute would overwrite the descriptor + assignment. + +* The action of a *__slots__* declaration is not limited to the class + where it is defined. *__slots__* declared in parents are available in + child classes. However, instances of a child subclass will get a + :attr:`~object.__dict__` and *__weakref__* unless the subclass also defines + *__slots__* (which should only contain names of any *additional* slots). + +* If a class defines a slot also defined in a base class, the instance variable + defined by the base class slot is inaccessible (except by retrieving its + descriptor directly from the base class). This renders the meaning of the + program undefined. In the future, a check may be added to prevent this. + +* :exc:`TypeError` will be raised if *__slots__* other than *__dict__* and + *__weakref__* are defined for a class derived from a + :c:member:`"variable-length" built-in type <PyTypeObject.tp_itemsize>` such as + :class:`int`, :class:`bytes`, and :class:`type`, except :class:`tuple`. + +* Any non-string :term:`iterable` may be assigned to *__slots__*. + +* If a :class:`dictionary <dict>` is used to assign *__slots__*, the dictionary + keys will be used as the slot names. The values of the dictionary can be used + to provide per-attribute docstrings that will be recognised by + :func:`inspect.getdoc` and displayed in the output of :func:`help`. + +* :attr:`~object.__class__` assignment works only if both classes have the + same *__slots__*. + +* :ref:`Multiple inheritance <multiple-inheritance>` with multiple slotted parent + classes can be used, + but only one parent is allowed to have attributes created by slots + (the other bases must have empty slot layouts) - violations raise + :exc:`TypeError`. + +* If an :term:`iterator` is used for *__slots__* then a :term:`descriptor` is + created for each + of the iterator's values. However, the *__slots__* attribute will be an empty + iterator. + +.. versionchanged:: 3.15 + Allowed defining the *__dict__* and *__weakref__* *__slots__* for any class. + Allowed defining any *__slots__* for a class derived from :class:`tuple`. + + +.. _class-customization: + +Customizing class creation +-------------------------- + +Whenever a class inherits from another class, :meth:`~object.__init_subclass__` is +called on the parent class. This way, it is possible to write classes which +change the behavior of subclasses. This is closely related to class +decorators, but where class decorators only affect the specific class they're +applied to, ``__init_subclass__`` solely applies to future subclasses of the +class defining the method. + +.. classmethod:: object.__init_subclass__(cls) + + This method is called whenever the containing class is subclassed. + *cls* is then the new subclass. If defined as a normal instance method, + this method is implicitly converted to a class method. + + Keyword arguments which are given to a new class are passed to + the parent class's ``__init_subclass__``. For compatibility with + other classes using ``__init_subclass__``, one should take out the + needed keyword arguments and pass the others over to the base + class, as in:: + + class Philosopher: + def __init_subclass__(cls, /, default_name, **kwargs): + super().__init_subclass__(**kwargs) + cls.default_name = default_name + + class AustralianPhilosopher(Philosopher, default_name="Bruce"): + pass + + The default implementation ``object.__init_subclass__`` does + nothing, but raises an error if it is called with any arguments. + + .. note:: + + The metaclass hint ``metaclass`` is consumed by the rest of the type + machinery, and is never passed to ``__init_subclass__`` implementations. + The actual metaclass (rather than the explicit hint) can be accessed as + ``type(cls)``. + + .. versionadded:: 3.6 + + +When a class is created, :meth:`!type.__new__` scans the class variables +and makes callbacks to those with a :meth:`~object.__set_name__` hook. + +.. method:: object.__set_name__(self, owner, name) + + Automatically called at the time the owning class *owner* is + created. The object has been assigned to *name* in that class:: + + class A: + x = C() # Automatically calls: x.__set_name__(A, 'x') + + If the class variable is assigned after the class is created, + :meth:`__set_name__` will not be called automatically. + If needed, :meth:`__set_name__` can be called directly:: + + class A: + pass + + c = C() + A.x = c # The hook is not called + c.__set_name__(A, 'x') # Manually invoke the hook + + See :ref:`class-object-creation` for more details. + + .. versionadded:: 3.6 + + +.. _metaclasses: + +Metaclasses +^^^^^^^^^^^ + +.. index:: + single: metaclass + pair: built-in function; type + single: = (equals); class definition + +By default, classes are constructed using :func:`type`. The class body is +executed in a new namespace and the class name is bound locally to the +result of ``type(name, bases, namespace)``. + +The class creation process can be customized by passing the ``metaclass`` +keyword argument in the class definition line, or by inheriting from an +existing class that included such an argument. In the following example, +both ``MyClass`` and ``MySubclass`` are instances of ``Meta``:: + + class Meta(type): + pass + + class MyClass(metaclass=Meta): + pass + + class MySubclass(MyClass): + pass + +Any other keyword arguments that are specified in the class definition are +passed through to all metaclass operations described below. + +When a class definition is executed, the following steps occur: + +* MRO entries are resolved; +* the appropriate metaclass is determined; +* the class namespace is prepared; +* the class body is executed; +* the class object is created. + + +Resolving MRO entries +^^^^^^^^^^^^^^^^^^^^^ + +.. method:: object.__mro_entries__(self, bases) + + If a base that appears in a class definition is not an instance of + :class:`type`, then an :meth:`!__mro_entries__` method is searched on the base. + If an :meth:`!__mro_entries__` method is found, the base is substituted with the + result of a call to :meth:`!__mro_entries__` when creating the class. + The method is called with the original bases tuple + passed to the *bases* parameter, and must return a tuple + of classes that will be used instead of the base. The returned tuple may be + empty: in these cases, the original base is ignored. + +.. seealso:: + + :func:`types.resolve_bases` + Dynamically resolve bases that are not instances of :class:`type`. + + :func:`types.get_original_bases` + Retrieve a class's "original bases" prior to modifications by + :meth:`~object.__mro_entries__`. + + :pep:`560` + Core support for typing module and generic types. + + +.. _metaclass-determination: + +Determining the appropriate metaclass +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. index:: + single: metaclass hint + +The appropriate metaclass for a class definition is determined as follows: + +* if no bases and no explicit metaclass are given, then :func:`type` is used; +* if an explicit metaclass is given and it is *not* an instance of + :func:`type`, then it is used directly as the metaclass; +* if an instance of :func:`type` is given as the explicit metaclass, or + bases are defined, then the most derived metaclass is used. + +The most derived metaclass is selected from the explicitly specified +metaclass (if any) and the metaclasses (i.e. ``type(cls)``) of all specified +base classes. The most derived metaclass is one which is a subtype of *all* +of these candidate metaclasses. If none of the candidate metaclasses meets +that criterion, then the class definition will fail with ``TypeError``. + + +.. _prepare: + +Preparing the class namespace +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: __prepare__ (metaclass method) + +Once the appropriate metaclass has been identified, then the class namespace +is prepared. If the metaclass has a ``__prepare__`` attribute, it is called +as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the +additional keyword arguments, if any, come from the class definition). The +``__prepare__`` method should be implemented as a +:func:`classmethod <classmethod>`. The +namespace returned by ``__prepare__`` is passed in to ``__new__``, but when +the final class object is created the namespace is copied into a new ``dict``. + +If the metaclass has no ``__prepare__`` attribute, then the class namespace +is initialised as an empty ordered mapping. + +.. seealso:: + + :pep:`3115` - Metaclasses in Python 3000 + Introduced the ``__prepare__`` namespace hook + + +Executing the class body +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: class; body + +The class body is executed (approximately) as +``exec(body, globals(), namespace)``. The key difference from a normal +call to :func:`exec` is that lexical scoping allows the class body (including +any methods) to reference names from the current and outer scopes when the +class definition occurs inside a function. + +However, even when the class definition occurs inside the function, methods +defined inside the class still cannot see names defined at the class scope. +Class variables must be accessed through the first parameter of instance or +class methods, or through the implicit lexically scoped ``__class__`` reference +described in the next section. + +.. _class-object-creation: + +Creating the class object +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: __class__ (method cell) + single: __classcell__ (class namespace entry) + + +Once the class namespace has been populated by executing the class body, +the class object is created by calling +``metaclass(name, bases, namespace, **kwds)`` (the additional keywords +passed here are the same as those passed to ``__prepare__``). + +This class object is the one that will be referenced by the zero-argument +form of :func:`super`. ``__class__`` is an implicit closure reference +created by the compiler if any methods in a class body refer to either +``__class__`` or ``super``. This allows the zero argument form of +:func:`super` to correctly identify the class being defined based on +lexical scoping, while the class or instance that was used to make the +current call is identified based on the first argument passed to the method. + +.. impl-detail:: + + In CPython 3.6 and later, the ``__class__`` cell is passed to the metaclass + as a ``__classcell__`` entry in the class namespace. If present, this must + be propagated up to the ``type.__new__`` call in order for the class to be + initialised correctly. + Failing to do so will result in a :exc:`RuntimeError` in Python 3.8. + +When using the default metaclass :class:`type`, or any metaclass that ultimately +calls ``type.__new__``, the following additional customization steps are +invoked after creating the class object: + +1) The ``type.__new__`` method collects all of the attributes in the class + namespace that define a :meth:`~object.__set_name__` method; +2) Those ``__set_name__`` methods are called with the class + being defined and the assigned name of that particular attribute; +3) The :meth:`~object.__init_subclass__` hook is called on the + immediate parent of the new class in its method resolution order. + +After the class object is created, it is passed to the class decorators +included in the class definition (if any) and the resulting object is bound +in the local namespace as the defined class. + +When a new class is created by ``type.__new__``, the object provided as the +namespace parameter is copied to a new ordered mapping and the original +object is discarded. The new copy is wrapped in a read-only proxy, which +becomes the :attr:`~type.__dict__` attribute of the class object. + +.. seealso:: + + :pep:`3135` - New super + Describes the implicit ``__class__`` closure reference + + +Uses for metaclasses +^^^^^^^^^^^^^^^^^^^^ + +The potential uses for metaclasses are boundless. Some ideas that have been +explored include enum, logging, interface checking, automatic delegation, +automatic property creation, proxies, frameworks, and automatic resource +locking/synchronization. + + +Customizing instance and subclass checks +---------------------------------------- + +The following methods are used to override the default behavior of the +:func:`isinstance` and :func:`issubclass` built-in functions. + +In particular, the metaclass :class:`abc.ABCMeta` implements these methods in +order to allow the addition of Abstract Base Classes (ABCs) as "virtual base +classes" to any class or type (including built-in types), including other +ABCs. + +.. method:: type.__instancecheck__(self, instance) + + Return true if *instance* should be considered a (direct or indirect) + instance of *class*. If defined, called to implement ``isinstance(instance, + class)``. + + +.. method:: type.__subclasscheck__(self, subclass) + + Return true if *subclass* should be considered a (direct or indirect) + subclass of *class*. If defined, called to implement ``issubclass(subclass, + class)``. + + +Note that these methods are looked up on the type (metaclass) of a class. They +cannot be defined as class methods in the actual class. This is consistent with +the lookup of special methods that are called on instances, only in this +case the instance is itself a class. + +.. seealso:: + + :pep:`3119` - Introducing Abstract Base Classes + Includes the specification for customizing :func:`isinstance` and + :func:`issubclass` behavior through :meth:`~type.__instancecheck__` and + :meth:`~type.__subclasscheck__`, with motivation for this functionality + in the context of adding Abstract Base Classes (see the :mod:`abc` + module) to the language. + + +Emulating generic types +----------------------- + +When using :term:`type annotations<annotation>`, it is often useful to +*parameterize* a :term:`generic type` using Python's square-brackets notation. +For example, the annotation ``list[int]`` might be used to signify a +:class:`list` in which all the elements are of type :class:`int`. + +.. seealso:: + + :pep:`484` - Type Hints + Introducing Python's framework for type annotations + + :ref:`Generic Alias Types<types-genericalias>` + Documentation for objects representing parameterized generic classes + + :ref:`Generics`, :ref:`user-defined generics<user-defined-generics>` and :class:`typing.Generic` + Documentation on how to implement generic classes that can be + parameterized at runtime and understood by static type-checkers. + +A class can *generally* only be parameterized if it defines the special +class method ``__class_getitem__()``. + +.. classmethod:: object.__class_getitem__(cls, key) + + Return an object representing the specialization of a generic class + by type arguments found in *key*. + + When defined on a class, ``__class_getitem__()`` is automatically a class + method. As such, there is no need for it to be decorated with + :deco:`classmethod` when it is defined. + + +The purpose of *__class_getitem__* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The purpose of :meth:`~object.__class_getitem__` is to allow runtime +parameterization of standard-library generic classes in order to more easily +apply :term:`type hints<type hint>` to these classes. + +To implement custom generic classes that can be parameterized at runtime and +understood by static type-checkers, users should either inherit from a standard +library class that already implements :meth:`~object.__class_getitem__`, or +inherit from :class:`typing.Generic`, which has its own implementation of +``__class_getitem__()``. + +Custom implementations of :meth:`~object.__class_getitem__` on classes defined +outside of the standard library may not be understood by third-party +type-checkers such as mypy. Using ``__class_getitem__()`` on any class for +purposes other than type hinting is discouraged. + + +.. _classgetitem-versus-getitem: + + +*__class_getitem__* versus *__getitem__* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Usually, the :ref:`subscription<subscriptions>` of an object using square +brackets will call the :meth:`~object.__getitem__` instance method defined on +the object's class. However, if the object being subscribed is itself a class, +the class method :meth:`~object.__class_getitem__` may be called instead. +``__class_getitem__()`` should return a :ref:`GenericAlias<types-genericalias>` +object if it is properly defined. + +Presented with the :term:`expression` ``obj[x]``, the Python interpreter +follows something like the following process to decide whether +:meth:`~object.__getitem__` or :meth:`~object.__class_getitem__` should be +called:: + + from inspect import isclass + + def subscribe(obj, x): + """Return the result of the expression 'obj[x]'""" + + class_of_obj = type(obj) + + # If the class of obj defines __getitem__, + # call class_of_obj.__getitem__(obj, x) + if hasattr(class_of_obj, '__getitem__'): + return class_of_obj.__getitem__(obj, x) + + # Else, if obj is a class and defines __class_getitem__, + # call obj.__class_getitem__(x) + elif isclass(obj) and hasattr(obj, '__class_getitem__'): + return obj.__class_getitem__(x) + + # Else, raise an exception + else: + raise TypeError( + f"'{class_of_obj.__name__}' object is not subscriptable" + ) + +In Python, all classes are themselves instances of other classes. The class of +a class is known as that class's :term:`metaclass`, and most classes have the +:class:`type` class as their metaclass. :class:`type` does not define +:meth:`~object.__getitem__`, meaning that expressions such as ``list[int]``, +``dict[str, float]`` and ``tuple[str, bytes]`` all result in +:meth:`~object.__class_getitem__` being called:: + + >>> # list has class "type" as its metaclass, like most classes: + >>> type(list) + <class 'type'> + >>> type(dict) == type(list) == type(tuple) == type(str) == type(bytes) + True + >>> # "list[int]" calls "list.__class_getitem__(int)" + >>> list[int] + list[int] + >>> # list.__class_getitem__ returns a GenericAlias object: + >>> type(list[int]) + <class 'types.GenericAlias'> + +However, if a class has a custom metaclass that defines +:meth:`~object.__getitem__`, subscribing the class may result in different +behaviour. An example of this can be found in the :mod:`enum` module:: + + >>> from enum import Enum + >>> class Menu(Enum): + ... """A breakfast menu""" + ... SPAM = 'spam' + ... BACON = 'bacon' + ... + >>> # Enum classes have a custom metaclass: + >>> type(Menu) + <class 'enum.EnumMeta'> + >>> # EnumMeta defines __getitem__, + >>> # so __class_getitem__ is not called, + >>> # and the result is not a GenericAlias object: + >>> Menu['SPAM'] + <Menu.SPAM: 'spam'> + >>> type(Menu['SPAM']) + <enum 'Menu'> + + +.. seealso:: + :pep:`560` - Core Support for typing module and generic types + Introducing :meth:`~object.__class_getitem__`, and outlining when a + :ref:`subscription<subscriptions>` results in ``__class_getitem__()`` + being called instead of :meth:`~object.__getitem__` + + +.. _callable-types: + +Emulating callable objects +-------------------------- + + +.. method:: object.__call__(self[, args...]) + + .. index:: pair: call; instance + + Called when the instance is "called" as a function; if this method is defined, + ``x(arg1, arg2, ...)`` roughly translates to ``type(x).__call__(x, arg1, ...)``. + The :class:`object` class itself does not provide this method. + + +.. _sequence-types: + +Emulating container types +------------------------- + +The following methods can be defined to implement container objects. None of them +are provided by the :class:`object` class itself. Containers usually are +:term:`sequences <sequence>` (such as :class:`lists <list>` or +:class:`tuples <tuple>`) or :term:`mappings <mapping>` (like +:term:`dictionaries <dictionary>`), +but can represent other containers as well. The first set of methods is used +either to emulate a sequence or to emulate a mapping; the difference is that for +a sequence, the allowable keys should be the integers *k* for which ``0 <= k < +N`` where *N* is the length of the sequence, or :class:`slice` objects, which define a +range of items. It is also recommended that mappings provide the methods +:meth:`!keys`, :meth:`!values`, :meth:`!items`, :meth:`!get`, :meth:`!clear`, +:meth:`!setdefault`, :meth:`!pop`, :meth:`!popitem`, :meth:`!copy`, and +:meth:`!update` behaving similar to those for Python's standard :class:`dictionary <dict>` +objects. The :mod:`collections.abc` module provides a +:class:`~collections.abc.MutableMapping` +:term:`abstract base class` to help create those methods from a base set of +:meth:`~object.__getitem__`, :meth:`~object.__setitem__`, +:meth:`~object.__delitem__`, and :meth:`!keys`. + +Mutable sequences should provide methods +:meth:`~sequence.append`, :meth:`~sequence.clear`, :meth:`~sequence.count`, +:meth:`~sequence.extend`, :meth:`~sequence.index`, :meth:`~sequence.insert`, +:meth:`~sequence.pop`, :meth:`~sequence.remove`, and :meth:`~sequence.reverse`, +like Python standard :class:`list` objects. +Finally, sequence types should implement addition (meaning concatenation) and +multiplication (meaning repetition) by defining the methods +:meth:`~object.__add__`, :meth:`~object.__radd__`, :meth:`~object.__iadd__`, +:meth:`~object.__mul__`, :meth:`~object.__rmul__` and :meth:`~object.__imul__` +described below; they should not define other numerical +operators. + +It is recommended that both mappings and sequences implement the +:meth:`~object.__contains__` method to allow efficient use of the ``in`` +operator; for +mappings, ``in`` should search the mapping's keys; for sequences, it should +search through the values. It is further recommended that both mappings and +sequences implement the :meth:`~object.__iter__` method to allow efficient iteration +through the container; for mappings, :meth:`!__iter__` should iterate +through the object's keys; for sequences, it should iterate through the values. + +.. method:: object.__len__(self) + + .. index:: + pair: built-in function; len + single: __bool__() (object method) + + Called to implement the built-in function :func:`len`. Should return the length + of the object, an integer ``>=`` 0. Also, an object that doesn't define a + :meth:`~object.__bool__` method and whose :meth:`!__len__` method returns zero is + considered to be false in a Boolean context. + + .. impl-detail:: + + In CPython, the length is required to be at most :data:`sys.maxsize`. + If the length is larger than :data:`!sys.maxsize` some features (such as + :func:`len`) may raise :exc:`OverflowError`. To prevent raising + :exc:`!OverflowError` by truth value testing, an object must define a + :meth:`~object.__bool__` method. + + +.. method:: object.__length_hint__(self) + + Called to implement :func:`operator.length_hint`. Should return an estimated + length for the object (which may be greater or less than the actual length). + The length must be an integer ``>=`` 0. The return value may also be + :data:`NotImplemented`, which is treated the same as if the + ``__length_hint__`` method didn't exist at all. This method is purely an + optimization and is never required for correctness. + + .. versionadded:: 3.4 + + +.. method:: object.__getitem__(self, subscript) + + Called to implement *subscription*, that is, ``self[subscript]``. + See :ref:`subscriptions` for details on the syntax. + + There are two types of built-in objects that support subscription + via :meth:`!__getitem__`: + + - **sequences**, where *subscript* (also called + :term:`index`) should be an integer or a :class:`slice` object. + See the :ref:`sequence documentation <datamodel-sequences>` for the expected + behavior, including handling :class:`slice` objects and negative indices. + - **mappings**, where *subscript* is also called the :term:`key`. + See :ref:`mapping documentation <datamodel-mappings>` for the expected + behavior. + + If *subscript* is of an inappropriate type, :meth:`!__getitem__` + should raise :exc:`TypeError`. + If *subscript* has an inappropriate value, :meth:`!__getitem__` + should raise an :exc:`LookupError` or one of its subclasses + (:exc:`IndexError` for sequences; :exc:`KeyError` for mappings). + + .. index:: pair: object; slice + + .. note:: + + Slicing is handled by :meth:`!__getitem__`, :meth:`~object.__setitem__`, + and :meth:`~object.__delitem__`. + A call like :: + + a[1:2] = b + + is translated to :: + + a[slice(1, 2, None)] = b + + and so forth. Missing slice items are always filled in with ``None``. + + .. note:: + + The sequence iteration protocol (used, for example, in :keyword:`for` + loops), expects that an :exc:`IndexError` will be raised for illegal + indexes to allow proper detection of the end of a sequence. + + .. note:: + + When :ref:`subscripting <subscriptions>` a *class*, the special + class method :meth:`~object.__class_getitem__` may be called instead of + :meth:`!__getitem__`. See :ref:`classgetitem-versus-getitem` for more + details. + + +.. method:: object.__setitem__(self, key, value) + + Called to implement assignment to ``self[key]``. Same note as for + :meth:`__getitem__`. This should only be implemented for mappings if the + objects support changes to the values for keys, or if new keys can be added, or + for sequences if elements can be replaced. The same exceptions should be raised + for improper *key* values as for the :meth:`__getitem__` method. + + +.. method:: object.__delitem__(self, key) + + Called to implement deletion of ``self[key]``. Same note as for + :meth:`__getitem__`. This should only be implemented for mappings if the + objects support removal of keys, or for sequences if elements can be removed + from the sequence. The same exceptions should be raised for improper *key* + values as for the :meth:`__getitem__` method. + + +.. method:: object.__missing__(self, key) + + Called by :class:`dict`\ .\ :meth:`__getitem__` to implement ``self[key]`` for dict subclasses + when key is not in the dictionary. + + +.. method:: object.__iter__(self) + + This method is called when an :term:`iterator` is required for a container. + This method should return a new iterator object that can iterate over all the + objects in the container. For mappings, it should iterate over the keys of + the container. + + +.. method:: object.__reversed__(self) + + Called (if present) by the :func:`reversed` built-in to implement + reverse iteration. It should return a new iterator object that iterates + over all the objects in the container in reverse order. + + If the :meth:`__reversed__` method is not provided, the :func:`reversed` + built-in will fall back to using the sequence protocol (:meth:`__len__` and + :meth:`__getitem__`). Objects that support the sequence protocol should + only provide :meth:`__reversed__` if they can provide an implementation + that is more efficient than the one provided by :func:`reversed`. + + +The membership test operators (:keyword:`in` and :keyword:`not in`) are normally +implemented as an iteration through a container. However, container objects can +supply the following special method with a more efficient implementation, which +also does not require the object be iterable. + +.. method:: object.__contains__(self, item) + + Called to implement membership test operators. Should return true if *item* + is in *self*, false otherwise. For mapping objects, this should consider the + keys of the mapping rather than the values or the key-item pairs. + + For objects that don't define :meth:`__contains__`, the membership test first + tries iteration via :meth:`__iter__`, then the old sequence iteration + protocol via :meth:`__getitem__`, see :ref:`this section in the language + reference <membership-test-details>`. + + +.. _numeric-types: + +Emulating numeric types +----------------------- + +The following methods can be defined to emulate numeric objects. Methods +corresponding to operations that are not supported by the particular kind of +number implemented (e.g., bitwise operations for non-integral numbers) should be +left undefined. + + +.. method:: object.__add__(self, other) + object.__sub__(self, other) + object.__mul__(self, other) + object.__matmul__(self, other) + object.__truediv__(self, other) + object.__floordiv__(self, other) + object.__mod__(self, other) + object.__divmod__(self, other) + object.__pow__(self, other[, modulo]) + object.__lshift__(self, other) + object.__rshift__(self, other) + object.__and__(self, other) + object.__xor__(self, other) + object.__or__(self, other) + + .. index:: + pair: built-in function; divmod + pair: built-in function; pow + pair: built-in function; pow + + These methods are called to implement the binary arithmetic operations + (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, + :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For instance, to + evaluate the expression ``x + y``, where *x* is an instance of a class that + has an :meth:`__add__` method, ``type(x).__add__(x, y)`` is called. The + :meth:`__divmod__` method should be the equivalent to using + :meth:`__floordiv__` and :meth:`__mod__`; it should not be related to + :meth:`__truediv__`. Note that :meth:`__pow__` should be defined to accept + an optional third argument if the three-argument version of the built-in :func:`pow` + function is to be supported. + + If one of those methods does not support the operation with the supplied + arguments, it should return :data:`NotImplemented`. + + +.. method:: object.__radd__(self, other) + object.__rsub__(self, other) + object.__rmul__(self, other) + object.__rmatmul__(self, other) + object.__rtruediv__(self, other) + object.__rfloordiv__(self, other) + object.__rmod__(self, other) + object.__rdivmod__(self, other) + object.__rpow__(self, other[, modulo]) + object.__rlshift__(self, other) + object.__rrshift__(self, other) + object.__rand__(self, other) + object.__rxor__(self, other) + object.__ror__(self, other) + + .. index:: + pair: built-in function; divmod + pair: built-in function; pow + + These methods are called to implement the binary arithmetic operations + (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, + :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected + (swapped) operands. These functions are only called if the operands + are of different types, when the left operand does not support the corresponding + operation [#]_, or the right operand's class is derived from the left operand's + class. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is + an instance of a class that has an :meth:`__rsub__` method, ``type(y).__rsub__(y, x)`` + is called if ``type(x).__sub__(x, y)`` returns :data:`NotImplemented` or ``type(y)`` + is a subclass of ``type(x)``. [#]_ + + Note that :meth:`__rpow__` should be defined to accept an optional third + argument if the three-argument version of the built-in :func:`pow` function + is to be supported. + + .. versionchanged:: 3.14 + + Three-argument :func:`pow` now try calling :meth:`~object.__rpow__` if necessary. + Previously it was only called in two-argument :func:`!pow` and the binary + power operator. + + .. note:: + + If the right operand's type is a subclass of the left operand's type and + that subclass provides a different implementation of the reflected method + for the operation, this method will be called before the left operand's + non-reflected method. This behavior allows subclasses to override their + ancestors' operations. + +.. method:: object.__iadd__(self, other) + object.__isub__(self, other) + object.__imul__(self, other) + object.__imatmul__(self, other) + object.__itruediv__(self, other) + object.__ifloordiv__(self, other) + object.__imod__(self, other) + object.__ipow__(self, other[, modulo]) + object.__ilshift__(self, other) + object.__irshift__(self, other) + object.__iand__(self, other) + object.__ixor__(self, other) + object.__ior__(self, other) + + These methods are called to implement the augmented arithmetic assignments + (``+=``, ``-=``, ``*=``, ``@=``, ``/=``, ``//=``, ``%=``, ``**=``, ``<<=``, + ``>>=``, ``&=``, ``^=``, ``|=``). These methods should attempt to do the + operation in-place (modifying *self*) and return the result (which could be, + but does not have to be, *self*). If a specific method is not defined, or if + that method returns :data:`NotImplemented`, the + augmented assignment falls back to the normal methods. For instance, if *x* + is an instance of a class with an :meth:`__iadd__` method, ``x += y`` is + equivalent to ``x = x.__iadd__(y)`` . If :meth:`__iadd__` does not exist, or if ``x.__iadd__(y)`` + returns :data:`!NotImplemented`, ``x.__add__(y)`` and + ``y.__radd__(x)`` are considered, as with the evaluation of ``x + y``. In + certain situations, augmented assignment can result in unexpected errors (see + :ref:`faq-augmented-assignment-tuple-error`), but this behavior is in fact + part of the data model. + + +.. method:: object.__neg__(self) + object.__pos__(self) + object.__abs__(self) + object.__invert__(self) + + .. index:: pair: built-in function; abs + + Called to implement the unary arithmetic operations (``-``, ``+``, :func:`abs` + and ``~``). + + +.. method:: object.__complex__(self) + object.__int__(self) + object.__float__(self) + + .. index:: + pair: built-in function; complex + pair: built-in function; int + pair: built-in function; float + + Called to implement the built-in functions :func:`complex`, + :func:`int` and :func:`float`. Should return a value + of the appropriate type. + + +.. method:: object.__index__(self) + + Called to implement :func:`operator.index`, and whenever Python needs to + losslessly convert the numeric object to an integer object (such as in + slicing, or in the built-in :func:`bin`, :func:`hex` and :func:`oct` + functions). Presence of this method indicates that the numeric object is + an integer type. Must return an integer. + + If :meth:`__int__`, :meth:`__float__` and :meth:`__complex__` are not + defined then corresponding built-in functions :func:`int`, :func:`float` + and :func:`complex` fall back to :meth:`__index__`. + + +.. method:: object.__round__(self, [,ndigits]) + object.__trunc__(self) + object.__floor__(self) + object.__ceil__(self) + + .. index:: pair: built-in function; round + + Called to implement the built-in function :func:`round` and :mod:`math` + functions :func:`~math.trunc`, :func:`~math.floor` and :func:`~math.ceil`. + Unless *ndigits* is passed to :meth:`!__round__` all these methods should + return the value of the object truncated to an :class:`~numbers.Integral` + (typically an :class:`int`). + + .. versionchanged:: 3.14 + :func:`int` no longer delegates to the :meth:`~object.__trunc__` method. + + +.. _context-managers: + +With Statement Context Managers +------------------------------- + +A :dfn:`context manager` is an object that defines the runtime context to be +established when executing a :keyword:`with` statement. The context manager +handles the entry into, and the exit from, the desired runtime context for the +execution of the block of code. Context managers are normally invoked using the +:keyword:`!with` statement (described in section :ref:`with`), but can also be +used by directly invoking their methods. + +.. index:: + pair: statement; with + single: context manager + +Typical uses of context managers include saving and restoring various kinds of +global state, locking and unlocking resources, closing opened files, etc. + +For more information on context managers, see :ref:`typecontextmanager`. +The :class:`object` class itself does not provide the context manager methods. + + +.. method:: object.__enter__(self) + + Enter the runtime context related to this object. The :keyword:`with` statement + will bind this method's return value to the target(s) specified in the + :keyword:`!as` clause of the statement, if any. + + +.. method:: object.__exit__(self, exc_type, exc_value, traceback) + + Exit the runtime context related to this object. The parameters describe the + exception that caused the context to be exited. If the context was exited + without an exception, all three arguments will be :const:`None`. + + If an exception is supplied, and the method wishes to suppress the exception + (i.e., prevent it from being propagated), it should return a true value. + Otherwise, the exception will be processed normally upon exit from this method. + + Note that :meth:`~object.__exit__` methods should not reraise the passed-in exception; + this is the caller's responsibility. + + +.. seealso:: + + :pep:`343` - The "with" statement + The specification, background, and examples for the Python :keyword:`with` + statement. + + +.. _class-pattern-matching: + +Customizing positional arguments in class pattern matching +---------------------------------------------------------- + +When using a class name in a pattern, positional arguments in the pattern are not +allowed by default, i.e. ``case MyClass(x, y)`` is typically invalid without special +support in ``MyClass``. To be able to use that kind of pattern, the class needs to +define a *__match_args__* attribute. + +.. data:: object.__match_args__ + + This class variable can be assigned a tuple of strings. When this class is + used in a class pattern with positional arguments, each positional argument will + be converted into a keyword argument, using the corresponding value in + *__match_args__* as the keyword. The absence of this attribute is equivalent to + setting it to ``()``. + +For example, if ``MyClass.__match_args__`` is ``("left", "center", "right")`` that means +that ``case MyClass(x, y)`` is equivalent to ``case MyClass(left=x, center=y)``. Note +that the number of arguments in the pattern must be smaller than or equal to the number +of elements in *__match_args__*; if it is larger, the pattern match attempt will raise +a :exc:`TypeError`. + +.. versionadded:: 3.10 + +.. seealso:: + + :pep:`634` - Structural Pattern Matching + The specification for the Python ``match`` statement. + + +.. _python-buffer-protocol: + +Emulating buffer types +---------------------- + +The :ref:`buffer protocol <bufferobjects>` provides a way for Python +objects to expose efficient access to a low-level memory array. This protocol +is implemented by builtin types such as :class:`bytes` and :class:`memoryview`, +and third-party libraries may define additional buffer types. + +While buffer types are usually implemented in C, it is also possible to +implement the protocol in Python. + +.. method:: object.__buffer__(self, flags) + + Called when a buffer is requested from *self* (for example, by the + :class:`memoryview` constructor). The *flags* argument is an integer + representing the kind of buffer requested, affecting for example whether + the returned buffer is read-only or writable. :class:`inspect.BufferFlags` + provides a convenient way to interpret the flags. The method must return + a :class:`memoryview` object. + + **Thread safety:** In :term:`free-threaded <free threading>` Python, + implementations must manage any internal export counter using atomic + operations. The method must be safe to call concurrently from multiple + threads, and the returned buffer's underlying data must remain valid + until the corresponding :meth:`~object.__release_buffer__` call + completes. See :ref:`thread-safety-memoryview` for details. + +.. method:: object.__release_buffer__(self, buffer) + + Called when a buffer is no longer needed. The *buffer* argument is a + :class:`memoryview` object that was previously returned by + :meth:`~object.__buffer__`. The method must release any resources associated + with the buffer. This method should return ``None``. + + **Thread safety:** In :term:`free-threaded <free threading>` Python, + any export counter decrement must use atomic operations. Resource + cleanup must be thread-safe, as the final release may race with + concurrent releases from other threads. + + Buffer objects that do not need to perform any cleanup are not required + to implement this method. + +.. versionadded:: 3.12 + +.. seealso:: + + :pep:`688` - Making the buffer protocol accessible in Python + Introduces the Python ``__buffer__`` and ``__release_buffer__`` methods. + + :class:`collections.abc.Buffer` + ABC for buffer types. + +Annotations +----------- + +Functions, classes, and modules may contain :term:`annotations <annotation>`, +which are a way to associate information (usually :term:`type hints <type hint>`) +with a symbol. + +.. attribute:: object.__annotations__ + + This attribute contains the annotations for an object. It is + :ref:`lazily evaluated <lazy-evaluation>`, so accessing the attribute may + execute arbitrary code and raise exceptions. If evaluation is successful, the + attribute is set to a dictionary mapping from variable names to annotations. + + .. versionchanged:: 3.14 + Annotations are now lazily evaluated. + +.. method:: object.__annotate__(format) + + An :term:`annotate function`. + Returns a new dictionary object mapping attribute/parameter names to their annotation values. + + Takes a format parameter specifying the format in which annotations values should be provided. + It must be a member of the :class:`annotationlib.Format` enum, or an integer with + a value corresponding to a member of the enum. + + If an annotate function doesn't support the requested format, it must raise + :exc:`NotImplementedError`. Annotate functions must always support + :attr:`~annotationlib.Format.VALUE` format; they must not raise + :exc:`NotImplementedError()` when called with this format. + + When called with :attr:`~annotationlib.Format.VALUE` format, an annotate function may raise + :exc:`NameError`; it must not raise :exc:`!NameError` when called requesting any other format. + + If an object does not have any annotations, :attr:`~object.__annotate__` should preferably be set + to ``None`` (it can’t be deleted), rather than set to a function that returns an empty dict. + + .. versionadded:: 3.14 + +.. seealso:: + + :pep:`649` --- Deferred evaluation of annotation using descriptors + Introduces lazy evaluation of annotations and the ``__annotate__`` function. + + +.. _special-lookup: + +Special method lookup +--------------------- + +For custom classes, implicit invocations of special methods are only guaranteed +to work correctly if defined on an object's type, not in the object's instance +dictionary. That behaviour is the reason why the following code raises an +exception:: + + >>> class C: + ... pass + ... + >>> c = C() + >>> c.__len__ = lambda: 5 + >>> len(c) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + TypeError: object of type 'C' has no len() + +The rationale behind this behaviour lies with a number of special methods such +as :meth:`~object.__hash__` and :meth:`~object.__repr__` that are implemented +by all objects, +including type objects. If the implicit lookup of these methods used the +conventional lookup process, they would fail when invoked on the type object +itself:: + + >>> 1 .__hash__() == hash(1) + True + >>> int.__hash__() == hash(int) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + TypeError: descriptor '__hash__' of 'int' object needs an argument + +Incorrectly attempting to invoke an unbound method of a class in this way is +sometimes referred to as 'metaclass confusion', and is avoided by bypassing +the instance when looking up special methods:: + + >>> type(1).__hash__(1) == hash(1) + True + >>> type(int).__hash__(int) == hash(int) + True + +In addition to bypassing any instance attributes in the interest of +correctness, implicit special method lookup generally also bypasses the +:meth:`~object.__getattribute__` method even of the object's metaclass:: + + >>> class Meta(type): + ... def __getattribute__(*args): + ... print("Metaclass getattribute invoked") + ... return type.__getattribute__(*args) + ... + >>> class C(object, metaclass=Meta): + ... def __len__(self): + ... return 10 + ... def __getattribute__(*args): + ... print("Class getattribute invoked") + ... return object.__getattribute__(*args) + ... + >>> c = C() + >>> c.__len__() # Explicit lookup via instance + Class getattribute invoked + 10 + >>> type(c).__len__(c) # Explicit lookup via type + Metaclass getattribute invoked + 10 + >>> len(c) # Implicit lookup + 10 + +Bypassing the :meth:`~object.__getattribute__` machinery in this fashion +provides significant scope for speed optimisations within the +interpreter, at the cost of some flexibility in the handling of +special methods (the special method *must* be set on the class +object itself in order to be consistently invoked by the interpreter). + + +.. index:: + single: coroutine + +Coroutines +========== + + +Awaitable Objects +----------------- + +An :term:`awaitable` object generally implements an :meth:`~object.__await__` method. +:term:`Coroutine objects <coroutine>` returned from :keyword:`async def` functions +are awaitable. + +.. note:: + + The :term:`generator iterator` objects returned from generators + decorated with :func:`types.coroutine` + are also awaitable, but they do not implement :meth:`~object.__await__`. + +.. method:: object.__await__(self) + + Must return an :term:`iterator`. Should be used to implement + :term:`awaitable` objects. For instance, :class:`asyncio.Future` implements + this method to be compatible with the :keyword:`await` expression. + The :class:`object` class itself is not awaitable and does not provide + this method. + + .. note:: + + The language doesn't place any restriction on the type or value of the + objects yielded by the iterator returned by ``__await__``, as this is + specific to the implementation of the asynchronous execution framework + (e.g. :mod:`asyncio`) that will be managing the :term:`awaitable` object. + + +.. versionadded:: 3.5 + +.. seealso:: :pep:`492` for additional information about awaitable objects. + + +.. _coroutine-objects: + +Coroutine Objects +----------------- + +:term:`Coroutine objects <coroutine>` are :term:`awaitable` objects. +A coroutine's execution can be controlled by calling :meth:`~object.__await__` and +iterating over the result. When the coroutine has finished executing and +returns, the iterator raises :exc:`StopIteration`, and the exception's +:attr:`~StopIteration.value` attribute holds the return value. If the +coroutine raises an exception, it is propagated by the iterator. Coroutines +should not directly raise unhandled :exc:`StopIteration` exceptions. + +Coroutines also have the methods listed below, which are analogous to +those of generators (see :ref:`generator-methods`). However, unlike +generators, coroutines do not directly support iteration. + +Coroutines are :ref:`generic <generics>` over the types of their yield, send, +and return values, respectively. + +.. versionchanged:: 3.5.2 + It is a :exc:`RuntimeError` to await on a coroutine more than once. + + +.. method:: coroutine.send(value) + + Starts or resumes execution of the coroutine. If *value* is ``None``, + this is equivalent to advancing the iterator returned by + :meth:`~object.__await__`. If *value* is not ``None``, this method delegates + to the :meth:`~generator.send` method of the iterator that caused + the coroutine to suspend. The result (return value, + :exc:`StopIteration`, or other exception) is the same as when + iterating over the :meth:`!__await__` return value, described above. + +.. method:: coroutine.throw(value) + coroutine.throw(type[, value[, traceback]]) + + Raises the specified exception in the coroutine. This method delegates + to the :meth:`~generator.throw` method of the iterator that caused + the coroutine to suspend, if it has such a method. Otherwise, + the exception is raised at the suspension point. The result + (return value, :exc:`StopIteration`, or other exception) is the same as + when iterating over the :meth:`~object.__await__` return value, described + above. If the exception is not caught in the coroutine, it propagates + back to the caller. + + .. versionchanged:: 3.12 + + The second signature \(type\[, value\[, traceback\]\]\) is deprecated and + may be removed in a future version of Python. + +.. method:: coroutine.close() + + Causes the coroutine to clean itself up and exit. If the coroutine + is suspended, this method first delegates to the :meth:`~generator.close` + method of the iterator that caused the coroutine to suspend, if it + has such a method. Then it raises :exc:`GeneratorExit` at the + suspension point, causing the coroutine to immediately clean itself up. + Finally, the coroutine is marked as having finished executing, even if + it was never started. + + Coroutine objects are automatically closed using the above process when + they are about to be destroyed. + +.. _async-iterators: + +Asynchronous Iterators +---------------------- + +An *asynchronous iterator* can call asynchronous code in +its ``__anext__`` method. + +Asynchronous iterators can be used in an :keyword:`async for` statement. + +The :class:`object` class itself does not provide these methods. + + +.. method:: object.__aiter__(self) + + Must return an *asynchronous iterator* object. + +.. method:: object.__anext__(self) + + Must return an *awaitable* resulting in a next value of the iterator. Should + raise a :exc:`StopAsyncIteration` error when the iteration is over. + +An example of an asynchronous iterable object:: + + class Reader: + async def readline(self): + ... + + def __aiter__(self): + return self + + async def __anext__(self): + val = await self.readline() + if val == b'': + raise StopAsyncIteration + return val + +.. versionadded:: 3.5 + +.. versionchanged:: 3.7 + Prior to Python 3.7, :meth:`~object.__aiter__` could return an *awaitable* + that would resolve to an + :term:`asynchronous iterator <asynchronous iterator>`. + + Starting with Python 3.7, :meth:`~object.__aiter__` must return an + asynchronous iterator object. Returning anything else + will result in a :exc:`TypeError` error. + + +.. _async-context-managers: + +Asynchronous Context Managers +----------------------------- + +An *asynchronous context manager* is a *context manager* that is able to +suspend execution in its ``__aenter__`` and ``__aexit__`` methods. + +Asynchronous context managers can be used in an :keyword:`async with` statement. + +The :class:`object` class itself does not provide these methods. + +.. method:: object.__aenter__(self) + + Semantically similar to :meth:`~object.__enter__`, the only + difference being that it must return an *awaitable*. + +.. method:: object.__aexit__(self, exc_type, exc_value, traceback) + + Semantically similar to :meth:`~object.__exit__`, the only + difference being that it must return an *awaitable*. + +An example of an asynchronous context manager class:: + + class AsyncContextManager: + async def __aenter__(self): + await log('entering context') + + async def __aexit__(self, exc_type, exc, tb): + await log('exiting context') + +.. versionadded:: 3.5 + + +.. rubric:: Footnotes + +.. [#] It *is* possible in some cases to change an object's type, under certain + controlled conditions. It generally isn't a good idea though, since it can + lead to some very strange behaviour if it is handled incorrectly. + +.. [#] The :meth:`~object.__hash__`, :meth:`~object.__iter__`, + :meth:`~object.__reversed__`, :meth:`~object.__contains__`, + :meth:`~object.__class_getitem__` and :meth:`~os.PathLike.__fspath__` + methods have special handling for this. Others + will still raise a :exc:`TypeError`, but may do so by relying on + the behavior that ``None`` is not callable. + +.. [#] "Does not support" here means that the class has no such method, or + the method returns :data:`NotImplemented`. Do not set the method to + ``None`` if you want to force fallback to the right operand's reflected + method—that will instead have the opposite effect of explicitly + *blocking* such fallback. + +.. [#] For operands of the same type, it is assumed that if the non-reflected method + (such as :meth:`~object.__add__`) fails then the operation is not supported, which is why the + reflected method is not called. + +.. [#] If the right operand's type is a subclass of the left operand's type, the + reflected method having precedence allows subclasses to override their ancestors' + operations. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/executionmodel.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/executionmodel.rst new file mode 100644 index 00000000..639c2325 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/executionmodel.rst @@ -0,0 +1,590 @@ + +.. _execmodel: + +*************** +Execution model +*************** + +.. index:: + single: execution model + pair: code; block + +.. _prog_structure: + +Structure of a program +====================== + +.. index:: block + +A Python program is constructed from code blocks. +A :dfn:`block` is a piece of Python program text that is executed as a unit. +The following are blocks: a module, a function body, and a class definition. +Each command typed interactively is a block. A script file (a file given as +standard input to the interpreter or specified as a command line argument to the +interpreter) is a code block. A script command (a command specified on the +interpreter command line with the :option:`-c` option) is a code block. +A module run as a top level script (as module ``__main__``) from the command +line using a :option:`-m` argument is also a code block. The string +argument passed to the built-in functions :func:`eval` and :func:`exec` is a +code block. + +.. index:: pair: execution; frame + +A code block is executed in an :dfn:`execution frame`. A frame contains some +administrative information (used for debugging) and determines where and how +execution continues after the code block's execution has completed. + +.. _naming: + +Naming and binding +================== + +.. index:: + single: namespace + single: scope + +.. _bind_names: + +Binding of names +---------------- + +.. index:: + single: name + pair: binding; name + +:dfn:`Names` refer to objects. Names are introduced by name binding operations. + +.. index:: single: from; import statement + +The following constructs bind names: + +* formal parameters to functions, +* class definitions, +* function definitions, +* assignment expressions, +* :ref:`targets <assignment>` that are identifiers if occurring in + an assignment: + + + :keyword:`for` loop header, + + after :keyword:`!as` in a :keyword:`with` statement, :keyword:`except` + clause, :keyword:`except* <except_star>` clause, or in the as-pattern in structural pattern matching, + + in a capture pattern in structural pattern matching + +* :keyword:`import` statements. +* :keyword:`type` statements. +* :ref:`type parameter lists <type-params>`. + +The :keyword:`!import` statement of the form ``from ... import *`` binds all +names defined in the imported module, except those beginning with an underscore. +This form may only be used at the module level. + +A target occurring in a :keyword:`del` statement is also considered bound for +this purpose (though the actual semantics are to unbind the name). + +Each assignment or import statement occurs within a block defined by a class or +function definition or at the module level (the top-level code block). + +.. index:: pair: free; variable + +If a name is bound in a block, it is a local variable of that block, unless +declared as :keyword:`nonlocal` or :keyword:`global`. If a name is bound at +the module level, it is a global variable. (The variables of the module code +block are local and global.) If a variable is used in a code block but not +defined there, it is a :term:`free variable`. + +Each occurrence of a name in the program text refers to the :dfn:`binding` of +that name established by the following name resolution rules. + +.. _resolve_names: + +Resolution of names +------------------- + +.. index:: scope + +A :dfn:`scope` defines the visibility of a name within a block. If a local +variable is defined in a block, its scope includes that block. If the +definition occurs in a function block, the scope extends to any blocks contained +within the defining one, unless a contained block introduces a different binding +for the name. + +.. index:: single: environment + +When a name is used in a code block, it is resolved using the nearest enclosing +scope. The set of all such scopes visible to a code block is called the block's +:dfn:`environment`. + +.. index:: + single: NameError (built-in exception) + single: UnboundLocalError + +When a name is not found at all, a :exc:`NameError` exception is raised. +If the current scope is a function scope, and the name refers to a local +variable that has not yet been bound to a value at the point where the name is +used, an :exc:`UnboundLocalError` exception is raised. +:exc:`UnboundLocalError` is a subclass of :exc:`NameError`. + +If a name binding operation occurs anywhere within a code block, all uses of the +name within the block are treated as references to the current block. This can +lead to errors when a name is used within a block before it is bound. This rule +is subtle. Python lacks declarations and allows name binding operations to +occur anywhere within a code block. The local variables of a code block can be +determined by scanning the entire text of the block for name binding operations. +See :ref:`the FAQ entry on UnboundLocalError <faq-unboundlocalerror>` +for examples. + +If the :keyword:`global` statement occurs within a block, all uses of the names +specified in the statement refer to the bindings of those names in the top-level +namespace. Names are resolved in the top-level namespace by searching the +global namespace, i.e. the namespace of the module containing the code block, +and the builtins namespace, the namespace of the module :mod:`builtins`. The +global namespace is searched first. If the names are not found there, the +builtins namespace is searched next. If the names are also not found in the +builtins namespace, new variables are created in the global namespace. +The global statement must precede all uses of the listed names. + +The :keyword:`global` statement has the same scope as a name binding operation +in the same block. If the nearest enclosing scope for a free variable contains +a global statement, the free variable is treated as a global. + +.. XXX say more about "nonlocal" semantics here + +The :keyword:`nonlocal` statement causes corresponding names to refer +to previously bound variables in the nearest enclosing function scope. +:exc:`SyntaxError` is raised at compile time if the given name does not +exist in any enclosing function scope. :ref:`Type parameters <type-params>` +cannot be rebound with the :keyword:`!nonlocal` statement. + +.. index:: pair: module; __main__ + +The namespace for a module is automatically created the first time a module is +imported. The main module for a script is always called :mod:`__main__`. + +Class definition blocks and arguments to :func:`exec` and :func:`eval` are +special in the context of name resolution. +A class definition is an executable statement that may use and define names. +These references follow the normal rules for name resolution with an exception +that unbound local variables are looked up in the global namespace. +The namespace of the class definition becomes the attribute dictionary of +the class. The scope of names defined in a class block is limited to the +class block; it does not extend to the code blocks of methods. This includes +comprehensions and generator expressions, but it does not include +:ref:`annotation scopes <annotation-scopes>`, +which have access to their enclosing class scopes. +This means that the following will fail:: + + class A: + a = 42 + b = list(a + i for i in range(10)) + +However, the following will succeed:: + + class A: + type Alias = Nested + class Nested: pass + + print(A.Alias.__value__) # <type 'A.Nested'> + +.. _annotation-scopes: + +Annotation scopes +----------------- + +:term:`Annotations <annotation>`, :ref:`type parameter lists <type-params>` +and :keyword:`type` statements +introduce *annotation scopes*, which behave mostly like function scopes, +but with some exceptions discussed below. + +Annotation scopes are used in the following contexts: + +* :term:`Function annotations <function annotation>`. +* :term:`Variable annotations <variable annotation>`. +* Type parameter lists for :ref:`generic type aliases <generic-type-aliases>`. +* Type parameter lists for :ref:`generic functions <generic-functions>`. + A generic function's annotations are + executed within the annotation scope, but its defaults and decorators are not. +* Type parameter lists for :ref:`generic classes <generic-classes>`. + A generic class's base classes and + keyword arguments are executed within the annotation scope, but its decorators are not. +* The bounds, constraints, and default values for type parameters + (:ref:`lazily evaluated <lazy-evaluation>`). +* The value of type aliases (:ref:`lazily evaluated <lazy-evaluation>`). + +Annotation scopes differ from function scopes in the following ways: + +* Annotation scopes have access to their enclosing class namespace. + If an annotation scope is immediately within a class scope, or within another + annotation scope that is immediately within a class scope, the code in the + annotation scope can use names defined in the class scope as if it were + executed directly within the class body. This contrasts with regular + functions defined within classes, which cannot access names defined in the class scope. +* Expressions in annotation scopes cannot contain :keyword:`yield`, ``yield from``, + :keyword:`await`, or :token:`:= <python-grammar:assignment_expression>` + expressions. (These expressions are allowed in other scopes contained within the + annotation scope.) +* Names defined in annotation scopes cannot be rebound with :keyword:`nonlocal` + statements in inner scopes. This includes only type parameters, as no other + syntactic elements that can appear within annotation scopes can introduce new names. +* While annotation scopes have an internal name, that name is not reflected in the + :term:`qualified name` of objects defined within the scope. + Instead, the :attr:`~definition.__qualname__` + of such objects is as if the object were defined in the enclosing scope. + +.. versionadded:: 3.12 + Annotation scopes were introduced in Python 3.12 as part of :pep:`695`. + +.. versionchanged:: 3.13 + Annotation scopes are also used for type parameter defaults, as + introduced by :pep:`696`. + +.. versionchanged:: 3.14 + Annotation scopes are now also used for annotations, as specified in + :pep:`649` and :pep:`749`. + +.. _lazy-evaluation: + +Lazy evaluation +--------------- + +Most annotation scopes are *lazily evaluated*. This includes annotations, +the values of type aliases created through the :keyword:`type` statement, and +the bounds, constraints, and default values of type +variables created through the :ref:`type parameter syntax <type-params>`. +This means that they are not evaluated when the type alias or type variable is +created, or when the object carrying annotations is created. Instead, they +are only evaluated when necessary, for example when the ``__value__`` +attribute on a type alias is accessed. + +Example: + +.. doctest:: + + >>> type Alias = 1/0 + >>> Alias.__value__ + Traceback (most recent call last): + ... + ZeroDivisionError: division by zero + >>> def func[T: 1/0](): pass + >>> T = func.__type_params__[0] + >>> T.__bound__ + Traceback (most recent call last): + ... + ZeroDivisionError: division by zero + +Here the exception is raised only when the ``__value__`` attribute +of the type alias or the ``__bound__`` attribute of the type variable +is accessed. + +This behavior is primarily useful for references to types that have not +yet been defined when the type alias or type variable is created. For example, +lazy evaluation enables creation of mutually recursive type aliases:: + + from typing import Literal + + type SimpleExpr = int | Parenthesized + type Parenthesized = tuple[Literal["("], Expr, Literal[")"]] + type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", "-"], Expr] + +Lazily evaluated values are evaluated in :ref:`annotation scope <annotation-scopes>`, +which means that names that appear inside the lazily evaluated value are looked up +as if they were used in the immediately enclosing scope. + +.. versionadded:: 3.12 + +.. _restrict_exec: + +Builtins and restricted execution +--------------------------------- + +.. index:: pair: restricted; execution + +.. impl-detail:: + + Users should not touch ``__builtins__``; it is strictly an implementation + detail. Users wanting to override values in the builtins namespace should + :keyword:`import` the :mod:`builtins` module and modify its + attributes appropriately. + +The builtins namespace associated with the execution of a code block +is actually found by looking up the name ``__builtins__`` in its +global namespace; this should be a dictionary or a module (in the +latter case the module's dictionary is used). By default, when in the +:mod:`__main__` module, ``__builtins__`` is the built-in module +:mod:`builtins`; when in any other module, ``__builtins__`` is an +alias for the dictionary of the :mod:`builtins` module itself. + + +.. _dynamic-features: + +Interaction with dynamic features +--------------------------------- + +Name resolution of free variables occurs at runtime, not at compile time. +This means that the following code will print 42:: + + i = 10 + def f(): + print(i) + i = 42 + f() + +.. XXX from * also invalid with relative imports (at least currently) + +The :func:`eval` and :func:`exec` functions do not have access to the full +environment for resolving names. Names may be resolved in the local and global +namespaces of the caller. Free variables are not resolved in the nearest +enclosing namespace, but in the global namespace. [#]_ The :func:`exec` and +:func:`eval` functions have optional arguments to override the global and local +namespace. If only one namespace is specified, it is used for both. + +.. XXX(ncoghlan) above is only accurate for string execution. When executing code objects, + closure cells may now be passed explicitly to resolve co_freevars references. + Docs issue: https://github.com/python/cpython/issues/122826 + +.. _exceptions: + +Exceptions +========== + +.. index:: single: exception + +.. index:: + single: raise an exception + single: handle an exception + single: exception handler + single: errors + single: error handling + +Exceptions are a means of breaking out of the normal flow of control of a code +block in order to handle errors or other exceptional conditions. An exception +is *raised* at the point where the error is detected; it may be *handled* by the +surrounding code block or by any code block that directly or indirectly invoked +the code block where the error occurred. + +The Python interpreter raises an exception when it detects a run-time error +(such as division by zero). A Python program can also explicitly raise an +exception with the :keyword:`raise` statement. Exception handlers are specified +with the :keyword:`try` ... :keyword:`except` statement. The :keyword:`finally` +clause of such a statement can be used to specify cleanup code which does not +handle the exception, but is executed whether an exception occurred or not in +the preceding code. + +.. index:: single: termination model + +Python uses the "termination" model of error handling: an exception handler can +find out what happened and continue execution at an outer level, but it cannot +repair the cause of the error and retry the failing operation (except by +re-entering the offending piece of code from the top). + +.. index:: single: SystemExit (built-in exception) + +When an exception is not handled at all, the interpreter terminates execution of +the program, or returns to its interactive main loop. In either case, it prints +a stack traceback, except when the exception is :exc:`SystemExit`. + +Exceptions are identified by class instances. The :keyword:`except` clause is +selected depending on the class of the instance: it must reference the class of +the instance or a :term:`non-virtual base class <abstract base class>` thereof. +The instance can be received by the handler and can carry additional information +about the exceptional condition. + +.. note:: + + Exception messages are not part of the Python API. Their contents may change + from one version of Python to the next without warning and should not be + relied on by code which will run under multiple versions of the interpreter. + +See also the description of the :keyword:`try` statement in section :ref:`try` +and :keyword:`raise` statement in section :ref:`raise`. + + +.. _execcomponents: + +Runtime Components +================== + +General Computing Model +----------------------- + +Python's execution model does not operate in a vacuum. It runs on +a host machine and through that host's runtime environment, including +its operating system (OS), if there is one. When a program runs, +the conceptual layers of how it runs on the host look something +like this: + + | **host machine** + | **process** (global resources) + | **thread** (runs machine code) + +Each process represents a program running on the host. Think of each +process itself as the data part of its program. Think of the process' +threads as the execution part of the program. This distinction will +be important to understand the conceptual Python runtime. + +The process, as the data part, is the execution context in which the +program runs. It mostly consists of the set of resources assigned to +the program by the host, including memory, signals, file handles, +sockets, and environment variables. + +Processes are isolated and independent from one another. (The same +is true for hosts.) The host manages the process' access to its +assigned resources, in addition to coordinating between processes. + +Each thread represents the actual execution of the program's machine +code, running relative to the resources assigned to the program's +process. It's strictly up to the host how and when that execution +takes place. + +From the point of view of Python, a program always starts with exactly +one thread. However, the program may grow to run in multiple +simultaneous threads. Not all hosts support multiple threads per +process, but most do. Unlike processes, threads in a process are not +isolated and independent from one another. Specifically, all threads +in a process share all of the process' resources. + +The fundamental point of threads is that each one does *run* +independently, at the same time as the others. That may be only +conceptually at the same time ("concurrently") or physically +("in parallel"). Either way, the threads effectively run +at a non-synchronized rate. + +.. note:: + + That non-synchronized rate means none of the process' memory is + guaranteed to stay consistent for the code running in any given + thread. Thus multi-threaded programs must take care to coordinate + access to intentionally shared resources. Likewise, they must take + care to be absolutely diligent about not accessing any *other* + resources in multiple threads; otherwise two threads running at the + same time might accidentally interfere with each other's use of some + shared data. All this is true for both Python programs and the + Python runtime. + + The cost of this broad, unstructured requirement is the tradeoff for + the kind of raw concurrency that threads provide. The alternative + to the required discipline generally means dealing with + non-deterministic bugs and data corruption. + +Python Runtime Model +-------------------- + +The same conceptual layers apply to each Python program, with some +extra data layers specific to Python: + + | **host machine** + | **process** (global resources) + | Python global runtime (*state*) + | Python interpreter (*state*) + | **thread** (runs Python bytecode and "C-API") + | Python thread *state* + +At the conceptual level: when a Python program starts, it looks exactly +like that diagram, with one of each. The runtime may grow to include +multiple interpreters, and each interpreter may grow to include +multiple thread states. + +.. note:: + + A Python implementation won't necessarily implement the runtime + layers distinctly or even concretely. The only exception is places + where distinct layers are directly specified or exposed to users, + like through the :mod:`threading` module. + +.. note:: + + The initial interpreter is typically called the "main" interpreter. + Some Python implementations, like CPython, assign special roles + to the main interpreter. + + Likewise, the host thread where the runtime was initialized is known + as the "main" thread. It may be different from the process' initial + thread, though they are often the same. In some cases "main thread" + may be even more specific and refer to the initial thread state. + A Python runtime might assign specific responsibilities + to the main thread, such as handling signals. + +As a whole, the Python runtime consists of the global runtime state, +interpreters, and thread states. The runtime ensures all that state +stays consistent over its lifetime, particularly when used with +multiple host threads. + +The global runtime, at the conceptual level, is just a set of +interpreters. While those interpreters are otherwise isolated and +independent from one another, they may share some data or other +resources. The runtime is responsible for managing these global +resources safely. The actual nature and management of these resources +is implementation-specific. Ultimately, the external utility of the +global runtime is limited to managing interpreters. + +In contrast, an "interpreter" is conceptually what we would normally +think of as the (full-featured) "Python runtime". When machine code +executing in a host thread interacts with the Python runtime, it calls +into Python in the context of a specific interpreter. + +.. note:: + + The term "interpreter" here is not the same as the "bytecode + interpreter", which is what regularly runs in threads, executing + compiled Python code. + + In an ideal world, "Python runtime" would refer to what we currently + call "interpreter". However, it's been called "interpreter" at least + since introduced in 1997 (`CPython:a027efa5b`_). + + .. _CPython:a027efa5b: https://github.com/python/cpython/commit/a027efa5b + +Each interpreter completely encapsulates all of the non-process-global, +non-thread-specific state needed for the Python runtime to work. +Notably, the interpreter's state persists between uses. It includes +fundamental data like :data:`sys.modules`. The runtime ensures +multiple threads using the same interpreter will safely +share it between them. + +A Python implementation may support using multiple interpreters at the +same time in the same process. They are independent and isolated from +one another. For example, each interpreter has its own +:data:`sys.modules`. + +For thread-specific runtime state, each interpreter has a set of thread +states, which it manages, in the same way the global runtime contains +a set of interpreters. It can have thread states for as many host +threads as it needs. It may even have multiple thread states for +the same host thread, though that isn't as common. + +Each thread state, conceptually, has all the thread-specific runtime +data an interpreter needs to operate in one host thread. The thread +state includes the current raised exception and the thread's Python +call stack. It may include other thread-specific resources. + +.. note:: + + The term "Python thread" can sometimes refer to a thread state, but + normally it means a thread created using the :mod:`threading` module. + +Each thread state, over its lifetime, is always tied to exactly one +interpreter and exactly one host thread. It will only ever be used in +that thread and with that interpreter. + +Multiple thread states may be tied to the same host thread, whether for +different interpreters or even the same interpreter. However, for any +given host thread, only one of the thread states tied to it can be used +by the thread at a time. + +Thread states are isolated and independent from one another and don't +share any data, except for possibly sharing an interpreter and objects +or other resources belonging to that interpreter. + +Once a program is running, new Python threads can be created using the +:mod:`threading` module (on platforms and Python implementations that +support threads). Additional processes can be created using the +:mod:`os`, :mod:`subprocess`, and :mod:`multiprocessing` modules. +Interpreters can be created and used with the +:mod:`~concurrent.interpreters` module. Coroutines (async) can +be run using :mod:`asyncio` in each interpreter, typically only +in a single thread (often the main thread). + + +.. rubric:: Footnotes + +.. [#] This limitation occurs because the code that is executed by these operations + is not available at the time the module is compiled. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/expressions.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/expressions.rst new file mode 100644 index 00000000..2e0b6621 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/expressions.rst @@ -0,0 +1,2658 @@ + +.. _expressions: + +*********** +Expressions +*********** + +.. index:: expression, BNF + +This chapter explains the meaning of the elements of expressions in Python. + +**Syntax Notes:** In this and the following chapters, +:ref:`grammar notation <notation>` will be used to describe syntax, +not lexical analysis. + +When (one alternative of) a syntax rule has the form: + +.. productionlist:: python-grammar + name: othername + +and no semantics are given, the semantics of this form of ``name`` are the same +as for ``othername``. + + +.. _conversions: + +Arithmetic conversions +====================== + +.. index:: pair: arithmetic; conversion + +When a description of an arithmetic operator below uses the phrase "the numeric +arguments are converted to a common real type", this means that the operator +implementation for built-in numeric types works as described in the +:ref:`Numeric Types <stdtypes-mixed-arithmetic>` section of the standard +library documentation. + +Some additional rules apply for certain operators and non-numeric operands +(for example, a string as a left argument to the ``%`` operator). +Extensions must define their own conversion behavior. + + +.. _atoms: + +Atoms +===== + +.. index:: atom + +Atoms are the most basic elements of expressions. +The simplest atoms are :ref:`builtin constants <atom-singletons>`, +:ref:`names <identifiers>` and :ref:`literals <atom-literals>`. +More complex atoms are enclosed in paired delimiters: + +- ``()`` (parentheses): :ref:`groups <parenthesized>`, + :ref:`tuple displays <tuple-display>`, + :ref:`yield atoms <yieldexpr>`, and + :ref:`generator expressions <genexpr>`; +- ``[]`` (square brackets): :ref:`list displays <lists>`; +- ``{}`` (curly braces): :ref:`dictionary <dict>` and :ref:`set <set>` displays. + +Formally, the syntax for atoms is: + +.. grammar-snippet:: + :group: python-grammar + + atom: + | `builtin_constant` + | `identifier` + | `literal` + | `parenthesized_enclosure` + | `bracketed_enclosure` + | `braced_enclosure` + parenthesized_enclosure: + | `group` + | `tuple` + | `yield_atom` + | `generator_expression` + bracketed_enclosure: + | `listcomp` + | `list` + braced_enclosure: + | `dictcomp` + | `dict` + | `setcomp` + | `set` + +.. _atom-singletons: + +Built-in constants +------------------ + +The keywords ``True``, ``False``, and ``None`` name +:ref:`built-in constants <built-in-consts>`. +The token ``...`` names the :py:data:`Ellipsis` constant. + +Evaluation of these atoms yields the corresponding value. + +.. note:: + + Several more built-in constants are available as global variables, + but only the ones mentioned here are :ref:`keywords <keywords>`. + In particular, these names cannot be reassigned or used as attributes: + + .. code-block:: pycon + + >>> False = 123 + File "<input>", line 1 + False = 123 + ^^^^^ + SyntaxError: cannot assign to False + +Formally, the syntax for built-in constants is: + +.. grammar-snippet:: + :group: python-grammar + + builtin_constant: 'True' | 'False' | 'None' | '...' + +.. _atom-identifiers: + +Identifiers (Names) +------------------- + +.. index:: name, identifier + +An identifier occurring as an atom is a name. See section :ref:`identifiers` +for lexical definition and section :ref:`naming` for documentation of naming and +binding. + +.. index:: pair: exception; NameError + +When the name is bound to an object, evaluation of the atom yields that object. +When a name is not bound, an attempt to evaluate it raises a :exc:`NameError` +exception. + +.. _private-name-mangling: + +.. index:: + pair: name; mangling + pair: private; names + +Private name mangling +^^^^^^^^^^^^^^^^^^^^^ + +When an identifier that textually occurs in a class definition begins with two +or more underscore characters and does not end in two or more underscores, it +is considered a :dfn:`private name` of that class. + +.. seealso:: + + The :ref:`class specifications <class>`. + +More precisely, private names are transformed to a longer form before code is +generated for them. If the transformed name is longer than 255 characters, +implementation-defined truncation may happen. + +The transformation is independent of the syntactical context in which the +identifier is used but only the following private identifiers are mangled: + +- Any name used as the name of a variable that is assigned or read or any + name of an attribute being accessed. + + The :attr:`~definition.__name__` attribute of nested functions, classes, and + type aliases is however not mangled. + +- The name of imported modules, e.g., ``__spam`` in ``import __spam``. + If the module is part of a package (i.e., its name contains a dot), + the name is *not* mangled, e.g., the ``__foo`` in ``import __foo.bar`` + is not mangled. + +- The name of an imported member, e.g., ``__f`` in ``from spam import __f``. + +The transformation rule is defined as follows: + +- The class name, with leading underscores removed and a single leading + underscore inserted, is inserted in front of the identifier, e.g., the + identifier ``__spam`` occurring in a class named ``Foo``, ``_Foo`` or + ``__Foo`` is transformed to ``_Foo__spam``. + +- If the class name consists only of underscores, the transformation is the + identity, e.g., the identifier ``__spam`` occurring in a class named ``_`` + or ``__`` is left as is. + +.. _atom-literals: + +Literals +-------- + +.. index:: single: literal + +A :dfn:`literal` is a textual representation of a value. +Python supports numeric, string and bytes literals. +:ref:`Format strings <f-strings>` and :ref:`template strings <t-strings>` +are treated as string literals. + +Numeric literals consist of a single :token:`NUMBER <python-grammar:NUMBER>` +token, which names an integer, floating-point number, or an imaginary number. +See the :ref:`numbers` section in Lexical analysis documentation for details. + +String and bytes literals may consist of several tokens. +See section :ref:`string-concatenation` for details. + +Note that negative and complex numbers, like ``-3`` or ``3+4.2j``, +are syntactically not literals, but :ref:`unary <unary>` or +:ref:`binary <binary>` arithmetic operations involving the ``-`` or ``+`` +operator. + +Evaluation of a literal yields an object of the given type +(:class:`int`, :class:`float`, :class:`complex`, :class:`str`, +:class:`bytes`, or :class:`~string.templatelib.Template`) with the given value. +The value may be approximated in the case of floating-point +and imaginary literals. + +The formal grammar for literals is: + +.. grammar-snippet:: + :group: python-grammar + + literal: `strings` | `NUMBER` + +.. _literals-identity: + +.. index:: + triple: immutable; data; type + pair: immutable; object + +Literals and object identity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +All literals correspond to immutable data types, and hence the object's identity +is less important than its value. Multiple evaluations of literals with the +same value (either the same occurrence in the program text or a different +occurrence) may obtain the same object or a different object with the same +value. + +.. admonition:: CPython implementation detail + + For example, in CPython, *small* integers with the same value evaluate + to the same object:: + + >>> x = 7 + >>> y = 7 + >>> x is y + True + + However, large integers evaluate to different objects:: + + >>> x = 123456789 + >>> y = 123456789 + >>> x is y + False + + This behavior may change in future versions of CPython. + In particular, the boundary between "small" and "large" integers has + already changed in the past. + + CPython will emit a :py:exc:`SyntaxWarning` when you compare literals + using ``is``:: + + >>> x = 7 + >>> x is 7 + <input>:1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? + True + + See :ref:`faq-identity-with-is` for more information. + +:ref:`Template strings <t-strings>` are immutable but may reference mutable +objects as :class:`~string.templatelib.Interpolation` values. +For the purposes of this section, two t-strings have the "same value" if +both their structure and the *identity* of the values match. + +.. impl-detail:: + + Currently, each evaluation of a template string results in + a different object. + + +.. _string-concatenation: + +String literal concatenation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Multiple adjacent string or bytes literals, possibly +using different quoting conventions, are allowed, and their meaning is the same +as their concatenation:: + + >>> "hello" 'world' + "helloworld" + +This feature is defined at the syntactical level, so it only works with literals. +To concatenate string expressions at run time, the '+' operator may be used:: + + >>> greeting = "Hello" + >>> space = " " + >>> name = "Blaise" + >>> print(greeting + space + name) # not: print(greeting space name) + Hello Blaise + +Literal concatenation can freely mix raw strings, triple-quoted strings, +and formatted string literals. +For example:: + + >>> "Hello" r', ' f"{name}!" + "Hello, Blaise!" + +This feature can be used to reduce the number of backslashes +needed, to split long strings conveniently across long lines, or even to add +comments to parts of strings. For example:: + + re.compile("[A-Za-z_]" # letter or underscore + "[A-Za-z0-9_]*" # letter, digit or underscore + ) + +However, bytes literals may only be combined with other byte literals; +not with string literals of any kind. +Also, template string literals may only be combined with other template +string literals:: + + >>> t"Hello" t"{name}!" + Template(strings=('Hello', '!'), interpolations=(...)) + +Formally: + +.. grammar-snippet:: + :group: python-grammar + + strings: (`STRING` | `fstring`)+ | `tstring`+ + + +.. index:: + single: parenthesized form + single: () (parentheses) + +.. _parenthesized-forms: +.. _parenthesized: + +Parenthesized groups +-------------------- + +A :dfn:`parenthesized group` is an expression enclosed in parentheses. +The group evaluates to the same value as the expression inside. + +Groups are used to override or clarify +:ref:`operator precedence <operator-precedence>`, +in the same way as in math notation. +For example:: + + >>> 3 << 2 | 4 + 12 + >>> 3 << (2 | 4) # Override precedence of the | (bitwise OR) + 192 + >>> (3 << 2) | 4 # Same as without parentheses (but more clear) + 12 + +Note that not everything in parentheses is a *group*. +Specifically, a parenthesized group must include exactly one expression, +and cannot end with a comma. +See :ref:`tuple displays <tuple-display>` and +:ref:`generator expressions <genexpr>` for other parenthesized forms. + +Formally, the syntax for groups is: + +.. grammar-snippet:: + :group: python-grammar + + group: '(' `assignment_expression` ')' + +.. _displays-for-lists-sets-and-dictionaries: +.. _displays: + +Container displays +------------------ + +.. index:: single: comprehensions + +For constructing builtin containers (lists, sets, tuples or dictionaries), +Python provides special syntax called :dfn:`displays`. +There are subtle differences between the four kinds of displays, +detailed in the following sections. +All displays, however, consist of comma-separated items enclosed in paired +delimiters. + +For example, a *list display* is a series of expressions enclosed in +square brackets:: + + >>> ["one", "two", "three"] + ['one', 'two', 'three'] + >>> [1 + 2, 2 + 3] + [3, 5] + +In list, tuple and dictionary (but not set) displays, the series may be empty:: + + >>> [] # empty list + [] + >>> () # empty tuple + () + >>> {} # empty dictionary + {} + +.. index:: pair: trailing; comma + +If the series is not empty, the items may be followed by an additional comma, +which has no effect:: + + >>> ["one", "two", "three",] # note comma after "three" + ['one', 'two', 'three'] + +.. note:: + + The trailing comma is often used for displays that span multiple lines + (using :ref:`implicit line joining <implicit-joining>`), + so when a future programmer adds a new entry at the end, they do not + need to modify an existing line:: + + >>> [ + ... 'one', + ... 'two', + ... 'three', + ... ] + ['one', 'two', 'three'] + +At runtime, when a display is evaluated, the listed items are evaluated from +left to right and placed into a new container of the appropriate type. + +.. index:: + pair: iterable; unpacking + single: * (asterisk); in expression lists + +For tuple, list and set (but not dict) displays, any item in the display may +be prefixed with an asterisk (``*``). +This denotes :ref:`iterable unpacking <iterable-unpacking>`. +At runtime, the asterisk-prefixed expression must evaluate to an iterable, +whose contents are inserted into the container at the location of +the unpacking. For example:: + + >>> numbers = (1, 2) + >>> [*numbers, 'word', *numbers] + [1, 2, 'word', 1, 2] + +Dictionary displays use a similar mechanism called +*dictionary unpacking*, denoted with a double +asterisk (``**``). +See :ref:`dict` for details. + +A more advanced form of displays are :dfn:`comprehensions`, where items are +computed via a set of looping and filtering instructions. +See the :ref:`comprehensions` section for details. + +.. versionadded:: 3.5 + Iterable and dictionary unpacking in displays, originally proposed + by :pep:`448`. + + +.. _lists: + +List displays +^^^^^^^^^^^^^ + +.. index:: + pair: list; display + pair: list; comprehensions + pair: empty; list + pair: object; list + single: [] (square brackets); list expression + single: , (comma); expression list + +A :dfn:`list display` is a possibly empty series of expressions enclosed in +square brackets. For example:: + + >>> ["one", "two", "three"] + ['one', 'two', 'three'] + >>> ["one"] # One-element list + ['one'] + >>> [] # empty list + [] + +See :ref:`displays` for general information on displays. + +The formal grammar for list displays is: + +.. grammar-snippet:: + :group: python-grammar + + list: '[' [`flexible_expression_list`] ']' + + +.. _set: + +Set displays +^^^^^^^^^^^^ + +.. index:: + pair: set; display + pair: set; comprehensions + pair: object; set + single: {} (curly brackets); set expression + single: , (comma); expression list + +A :dfn:`set display` is a *non-empty* series of expressions enclosed in +curly braces. For example:: + + >>> {"one", "two", "three"} + {'one', 'three', 'two'} + >>> {"one"} # One-element set + {'one'} + +See :ref:`displays` for general information on displays. + +There is no special syntax for the empty set. +The ``{}`` literal is a :ref:`dictionary display <dict>` that constructs an +empty dictionary. +Call :class:`set() <set>` with no arguments to get an empty set. + +The formal grammar for set displays is: + +.. grammar-snippet:: + :group: python-grammar + + set: '{' `flexible_expression_list` '}' + + +.. index:: + single: tuple display + single: comma + single: , (comma) + +.. _tuple-display: + +.. index:: pair: empty; tuple + +Tuple displays +^^^^^^^^^^^^^^ + +A :dfn:`tuple display` is a series of expressions enclosed in +parentheses. For example:: + + >>> (1, 2) + (1, 2) + >>> () # an empty tuple + () + +See :ref:`displays` for general information on displays. + +To avoid ambiguity, if a tuple display has exactly one element, +it requires a trailing comma. +Without it, you get a :ref:`parenthesized group <parenthesized>`:: + + >>> ('single',) # single-element tuple + ('single',) + >>> ('single') # no comma: single string + 'single' + +To put it in other words, a tuple display is a parenthesized list of either: + +- two or more comma-separated expressions, or +- zero or more expressions, each followed by a comma. + +Since tuples are immutable, :ref:`object identity rules for literals <literals-identity>` +also apply to tuples: at runtime, two occurrences of tuples with the same +values may or may not yield the same object. + +.. note:: + + Python's syntax also includes :ref:`expression lists <exprlists>`, + where a comma-separated list of expressions is *not* enclosed in parentheses + but evaluates to tuple. + + In other words, when it comes to tuple syntax, the comma is more important + that the use of parentheses. + Only the empty tuple is spelled without a comma. + + +The formal grammar for tuple displays is: + +.. grammar-snippet:: + :group: python-grammar + + tuple: + | '(' `flexible_expression` (',' `flexible_expression`)+ [','] ')' + | '(' `flexible_expression` ',' ')' + | '(' ')' + +.. _dict: + +Dictionary displays +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: dictionary; display + pair: dictionary; comprehensions + key, value, key/value pair + pair: object; dictionary + single: {} (curly brackets); dictionary expression + single: : (colon); in dictionary expressions + single: , (comma); in dictionary displays + +A :dfn:`dictionary display` is a possibly empty series of :dfn:`dict items` +enclosed in curly braces. +Each dict item is a colon-separated pair of expressions: the :dfn:`key` +and its associated :dfn:`value`. +For example:: + + >>> {1: 'one', 2: 'two'} + {1: 'one', 2: 'two'} + +At runtime, when a dictionary comprehension is evaluated, the expressions +are evaluated from left to right. +Each key object is used as a key into the dictionary to store the +corresponding value. +This means that you can specify the same key multiple times in the +comprehension, and the final dictionary's value for a given key will be the +last one given. +For example:: + + >>> { + ... 1: 'this will be overridden', + ... 2: 'two', + ... 1: 'also overridden', + ... 1: 'one', + ... } + {1: 'one', 2: 'two'} + +.. index:: + unpacking; dictionary + single: **; in dictionary displays + +.. _dict-unpacking: + +Instead of a key-value pair, a dict item may be an expression prefixed by +a double asterisk ``**``. This denotes :dfn:`dictionary unpacking`. +At runtime, the expression must evaluate to a :term:`mapping`; +each item of the mapping is added to the new dictionary. +As with key-value pairs, later values replace values already set by +earlier items and unpackings. +This may be used to override a set of defaults:: + + >>> defaults = {'color': 'blue', 'count': 8} + >>> overrides = {'color': 'yellow'} + >>> {**defaults, **overrides} + {'color': 'yellow', 'count': 8} + +.. versionadded:: 3.5 + Unpacking into dictionary displays, originally proposed by :pep:`448`. + +The formal grammar for dict displays is: + +.. grammar-snippet:: + :group: python-grammar + + dict: '{' [`double_starred_kvpairs`] '}' + double_starred_kvpairs: ','.`double_starred_kvpair`+ [','] + double_starred_kvpair: '**' `or_expr` | `kvpair` + kvpair: `expression` ':' `expression` + + +.. index:: + single: comprehensions + single: for; in comprehensions + +.. _comprehensions: + +Comprehensions +-------------- + +List, set and dictionary :dfn:`comprehensions` are a form of +:ref:`container displays <displays>` where items are computed via a set of +looping and filtering instructions rather than listed explicitly. + +In its simplest form, a comprehension consists of a single expression +followed by a :keyword:`!for` clause. +The :keyword:`!for` clause has the same syntax as the header of a +:ref:`for statement <for>`, without a trailing colon. + +For example, a list of the first ten squares is:: + + >>> [x**2 for x in range(10)] + [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] + +At run time, a list comprehension creates a new list. +The expression after :keyword:`!in` must evaluate to an :term:`iterable`. +For each element of this iterable, the element is bound to the :keyword:`!for` +clause's target as in a :keyword:`!for` statement, then the expression +before :keyword:`!for` is evaluated with the target in scope and the result +is added to the new list. +Thus, the example above is roughly equivalent to defining and calling +the following function:: + + def make_list_of_squares(iterable): + result = [] + for x in iterable: + result.append(x**2) + return result + + make_list_of_squares(range(10)) + +Set comprehensions work similarly. +For example, here is a set of lowercase letters:: + + >>> {x.lower() for x in ['a', 'A', 'b', 'C']} + {'c', 'a', 'b'} + +At run time, this corresponds roughly to calling this function:: + + def make_lowercase_set(iterable): + result = set(iterable) + for x in iterable: + result.append(x.lower()) + return result + + make_lowercase_set(['a', 'A', 'b', 'C']) + +Dictionary comprehensions start with a colon-separated key-value pair instead +of an expression. For example:: + + >>> {func.__name__: func for func in [print, hex, any]} + {'print': <built-in function print>, + 'hex': <built-in function hex>, + 'any': <built-in function any>} + +At run time, this corresponds roughly to:: + + def make_dict_mapping_names_to_functions(iterable): + result = {} + for func in iterable: + result[func.__name__] = func + return result + + iterable([print, hex, any]) + +As in other kinds of dictionary displays, the same key may be specified +multiple times. +Earlier values are overwritten by ones that are evaluated later. + +There are no *tuple comprehensions*. +A similar syntax is instead used for :ref:`generator expressions <genexpr>`, +from which you can construct a tuple like this:: + + >>> tuple(x**2 for x in range(10)) + (0, 1, 4, 9, 16, 25, 36, 49, 64, 81) + +.. versionchanged:: 3.8 + Prior to Python 3.8, in dict comprehensions, the evaluation order of key + and value was not well-defined. In CPython, the value was evaluated before + the key. Starting with 3.8, the key is evaluated before the value, as + proposed by :pep:`572`. + + +.. index:: single: if; in comprehensions + +Filtering in comprehensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :keyword:`!for` clause may be followed by an :keyword:`!if` clause +with an expression. + +For example, a list of names from the :mod:`math` module +that start with ``f`` is:: + + >>> [name for name in vars(math) if name.startswith('f')] + ['fabs', 'factorial', 'floor', 'fma', 'fmod', 'frexp', 'fsum'] + +At run time, the expression after :keyword:`!if` is evaluated before +each element is added to the resulting container, and if it is false, +the element is skipped. +Thus, the above example roughly corresponds to defining and calling the +following function:: + + def get_math_f_names(iterable): + result = [] + for name in iterable: + if name.startswith('f'): + result.append(name) + return result + + get_math_f_names(vars(math)) + +Filtering is a special case of more complex comprehensions. +See the next section for a more formal description. + + +.. _complex-comprehensions: + +Complex comprehensions +^^^^^^^^^^^^^^^^^^^^^^ + +Generally, a comprehension's initial :keyword:`!for` clause may be followed by +zero or more additional :keyword:`!for` or :keyword:`!if` clauses. +For example, here is a list of names exposed by two Python modules, +filtered to only include names that start with ``a``:: + + >>> import array + >>> import math + >>> [ + ... name + ... for module in [array, math] + ... for name in vars(module) + ... if name.startswith('a') + ... ] + ['array', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh'] + +At run time, this roughly corresponds to defining and calling:: + + def get_a_names(iterable): + result = [] + for module in iterable: + for name in vars(module): + if name.startswith('a'): + result.append(name) + return result + + get_a_names([array, math]) + +The elements of the new container are those that would be produced by +considering each of the :keyword:`!for` or :keyword:`!if` clauses a block, +nesting from left to right, and evaluating the expression to produce an +element (or dictionary entry) each time the innermost block is reached. + +Aside from the iterable expression in the leftmost :keyword:`!for` clause, +the comprehension is executed in a separate implicitly nested scope. +This ensures that names assigned to in the target list don't "leak" into +the enclosing scope. +For example:: + + >>> x = 'old value' + >>> [x**2 for x in range(10)] # this `x` is local to the comprehension + >>> x + 'old value' + +The iterable expression in the leftmost :keyword:`!for` clause is evaluated +directly in the enclosing scope and then passed as an argument to the implicitly +nested scope. + +Subsequent :keyword:`!for` clauses and any filter condition in the +leftmost :keyword:`!for` clause cannot be evaluated in the enclosing scope as +they may depend on the values obtained from the leftmost iterable. + +To ensure the comprehension always results in a container of the appropriate +type, ``yield`` and ``yield from`` expressions are prohibited in the implicitly +nested scope. + +:ref:`Assignment expressions <assignment-expressions>` are not allowed +inside comprehension iterable expressions (that is, the expressions after +the :keyword:`!in` keyword), nor anywhere within comprehensions that +appear directly in a class definition. + +.. versionchanged:: 3.8 + ``yield`` and ``yield from`` prohibited in the implicitly nested scope. + + +.. _unpacking-comprehensions: + +Unpacking in comprehensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If the expression of a list or set comprehension is starred, the result will +be :ref:`unpacked <iterable-unpacking>` to produce +zero or more elements. + +This is often used for "flattening" lists, for example:: + + >>> students = ['Petr', 'Blaise', 'Jarka'] + >>> teachers = ['Salim', 'Bartosz'] + >>> lists_of_people = [students, teachers] + >>> [*people for people in lists_of_people] + ['Petr', 'Blaise', 'Jarka', 'Salim', 'Bartosz'] + +At run time, this comprehension roughly corresponds to:: + + def flatten_names(lists_of_people): + result = [] + for people in lists_of_people: + result.extend(people) + return result + +In dict comprehensions, a double-starred expression will be evaluated and +then unpacked using :ref:`dictionary unpacking <dict-unpacking>`, +inserting zero or more key/value pairs into the new dictionary. +As in other kinds of dictionary displays, if the same key is specified +multiple times, the associated value in the resulting dictionary +will be the last one specified. + +For example:: + + >>> system_defaults = {'color': 'blue', 'count': 8} + >>> user_defaults = {'color': 'yellow'} + >>> overrides = {'count': 5} + + >>> configuration_sets = [system_defaults, user_defaults, overrides] + + >>> {**d for d in configuration_sets} + {'color': 'yellow', 'count': 5} + +.. versionadded:: 3.15 + + Unpacking in comprehensions using the ``*`` and ``**`` operators + was introduced in :pep:`798`. + + +.. index:: + single: async for; in comprehensions + single: await; in comprehensions + +Asynchronous comprehensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In an :keyword:`async def` function, an :keyword:`!async for` +clause may be used to iterate over a :term:`asynchronous iterator`. +A comprehension in an :keyword:`!async def` function may consist of either a +:keyword:`!for` or :keyword:`!async for` clause following the leading +expression, may contain additional :keyword:`!for` or :keyword:`!async for` +clauses, and may also use :keyword:`await` expressions. + +If a comprehension contains :keyword:`!async for` clauses, or if it contains +:keyword:`!await` expressions or other asynchronous comprehensions anywhere except +the iterable expression in the leftmost :keyword:`!for` clause, it is called an +:dfn:`asynchronous comprehension`. An asynchronous comprehension may suspend the +execution of the coroutine function in which it appears. + +.. versionadded:: 3.6 + + Asynchronous comprehensions were introduced in :pep:`530`. + +.. versionchanged:: 3.11 + Asynchronous comprehensions are now allowed inside comprehensions in + asynchronous functions. Outer comprehensions implicitly become + asynchronous. + +.. _comprehension-grammar: + +Formal grammar for comprehensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The formal grammar for comprehensions is: + +.. grammar-snippet:: + :group: python-grammar + + listcomp: '[' `comprehension` ']' + setcomp: '{' `comprehension` '}' + comprehension: `flexible_expression` `for_if_clause`+ + + dictcomp: + | '{' `kvpair` `for_if_clause`+ '}' + | '{' '**' `expression` `for_if_clause`+ '}' + + for_if_clause: + | ['async'] 'for' `target_list` 'in' `or_test` ('if' `or_test`)* + + +.. _genexpr: + +Generator expressions +--------------------- + +.. index:: + pair: generator; expression + pair: object; generator + single: () (parentheses); generator expression + +The syntax for :dfn:`generator expressions` is the same as for +list :ref:`comprehensions <comprehensions>`, except that they are enclosed in +parentheses instead of brackets. +For example:: + + >>> iterator = (x ** 2 for x in range(10)) + >>> iterator + <generator object <genexpr> at ...> + +At runtime, a generator expression evaluates to a :term:`generator iterator` +which yields the same values as the corresponding list comprehension:: + + >>> list(iterator) + [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] + +Thus, the example above is roughly equivalent to defining and calling +the following generator function:: + + def make_generator_of_squares(iterator): + for x in iterator: + yield x ** 2 + + make_generator_of_squares(iter(range(10))) + +The enclosing parentheses can be omitted in calls when the generator +expression is the only positional argument and there are no keyword +arguments. +See the :ref:`Calls section <calls>` for details. +For example:: + + # The parentheses after `sum` are part of the call syntax: + >>> sum(x ** 2 for x in range(10)) + 285 + + # The generator needs its own parentheses if it's not the only argument: + >>> sum((x ** 2 for x in range(10)), start=1000) + 1285 + +The iterable expression in the leftmost :keyword:`!for` clause is +evaluated immediately, so that an error raised by this expression will be +emitted at the point where the generator expression is defined, +rather than at the point where the first value is retrieved:: + + >>> (x ** 2 for x in nonexistent_iterable) + Traceback (most recent call last): + ... + NameError: name 'nonexistent_iterable' is not defined + +After the expression is evaluated, an iterator is created +from the result, as if :py:func:`iter` was called on it. +Any error raised when creating the iterator is also emitted immediately:: + + >>> (x ** 2 for x in None) + Traceback (most recent call last): + ... + TypeError: 'NoneType' object is not iterable + +All other expressions are evaluated lazily, in the same fashion as normal +generators (that is, when the iterator is asked to yield a value):: + + >>> iterator = (nonexistent_value for x in range(10)) + >>> iterator + <generator object <genexpr> at ...> + >>> list(iterator) + Traceback (most recent call last): + ... + NameError: name 'nonexistent_value' is not defined + +:: + + >>> iterator = (x * y for x in range(10) for y in nonexistent_iterable) + >>> iterator + <generator object <genexpr> at ...> + >>> list(iterator) + Traceback (most recent call last): + ... + NameError: name 'nonexistent_iterable' is not defined + +To avoid interfering with the expected operation of the generator expression +itself, ``yield`` and ``yield from`` expressions are prohibited inside +the implicitly nested scope. + +If a generator expression contains either :keyword:`!async for` +clauses or :keyword:`await` expressions it is called an +:dfn:`asynchronous generator expression`. +An asynchronous generator expression returns a new asynchronous generator +object, which is an asynchronous iterator (see :ref:`async-iterators`). + +The formal grammar for generator expressions is: + +.. grammar-snippet:: + :group: python-grammar + + generator_expression: "(" `comprehension` ")" + +.. versionadded:: 3.6 + Asynchronous generator expressions were introduced. + +.. versionchanged:: 3.7 + Prior to Python 3.7, asynchronous generator expressions could + only appear in :keyword:`async def` coroutines. Starting + with 3.7, any function can use asynchronous generator expressions. + +.. versionchanged:: 3.8 + ``yield`` and ``yield from`` prohibited in the implicitly nested scope. + + +.. _yieldexpr: + +Yield expressions +----------------- + +.. index:: + pair: keyword; yield + pair: keyword; from + pair: yield; expression + pair: generator; function + +.. productionlist:: python-grammar + yield_atom: "(" `yield_expression` ")" + yield_from: "yield" "from" `expression` + yield_expression: "yield" `yield_list` | `yield_from` + +The yield expression is used when defining a :term:`generator` function +or an :term:`asynchronous generator` function and +thus can only be used in the body of a function definition. Using a yield +expression in a function's body causes that function to be a generator function, +and using it in an :keyword:`async def` function's body causes that +coroutine function to be an asynchronous generator function. For example:: + + def gen(): # defines a generator function + yield 123 + + async def agen(): # defines an asynchronous generator function + yield 123 + +Due to their side effects on the containing scope, ``yield`` expressions +are not permitted as part of the implicitly defined scopes used to +implement comprehensions and generator expressions. + +.. versionchanged:: 3.8 + Yield expressions prohibited in the implicitly nested scopes used to + implement comprehensions and generator expressions. + +Generator functions are described below, while asynchronous generator +functions are described separately in section +:ref:`asynchronous-generator-functions`. + +When a generator function is called, it returns an iterator known as a +generator. That generator then controls the execution of the generator +function. The execution starts when one of the generator's methods is called. +At that time, the execution proceeds to the first yield expression, where it is +suspended again, returning the value of :token:`~python-grammar:yield_list` +to the generator's caller, +or ``None`` if :token:`~python-grammar:yield_list` is omitted. +By suspended, we mean that all local state is +retained, including the current bindings of local variables, the instruction +pointer, the internal evaluation stack, and the state of any exception handling. +When the execution is resumed by calling one of the generator's methods, the +function can proceed exactly as if the yield expression were just another +external call. The value of the yield expression after resuming depends on the +method which resumed the execution. If :meth:`~generator.__next__` is used +(typically via either a :keyword:`for` or the :func:`next` builtin) then the +result is :const:`None`. Otherwise, if :meth:`~generator.send` is used, then +the result will be the value passed in to that method. + +.. index:: single: coroutine + +All of this makes generator functions quite similar to coroutines; they yield +multiple times, they have more than one entry point and their execution can be +suspended. The only difference is that a generator function cannot control +where the execution should continue after it yields; the control is always +transferred to the generator's caller. + +Yield expressions are allowed anywhere in a :keyword:`try` construct. If the +generator is not resumed before it is +finalized (by reaching a zero reference count or by being garbage collected), +the generator-iterator's :meth:`~generator.close` method will be called, +allowing any pending :keyword:`finally` clauses to execute. + +.. index:: + single: from; yield from expression + +When ``yield from <expr>`` is used, the supplied expression must be an +iterable. The values produced by iterating that iterable are passed directly +to the caller of the current generator's methods. Any values passed in with +:meth:`~generator.send` and any exceptions passed in with +:meth:`~generator.throw` are passed to the underlying iterator if it has the +appropriate methods. If this is not the case, then :meth:`~generator.send` +will raise :exc:`AttributeError` or :exc:`TypeError`, while +:meth:`~generator.throw` will just raise the passed in exception immediately. + +When the underlying iterator is complete, the :attr:`~StopIteration.value` +attribute of the raised :exc:`StopIteration` instance becomes the value of +the yield expression. It can be either set explicitly when raising +:exc:`StopIteration`, or automatically when the subiterator is a generator +(by returning a value from the subgenerator). + +.. versionchanged:: 3.3 + Added ``yield from <expr>`` to delegate control flow to a subiterator. + +The parentheses may be omitted when the yield expression is the sole expression +on the right hand side of an assignment statement. + +.. seealso:: + + :pep:`255` - Simple Generators + The proposal for adding generators and the :keyword:`yield` statement to Python. + + :pep:`342` - Coroutines via Enhanced Generators + The proposal to enhance the API and syntax of generators, making them + usable as simple coroutines. + + :pep:`380` - Syntax for Delegating to a Subgenerator + The proposal to introduce the :token:`~python-grammar:yield_from` syntax, + making delegation to subgenerators easy. + + :pep:`525` - Asynchronous Generators + The proposal that expanded on :pep:`492` by adding generator capabilities to + coroutine functions. + +.. index:: single: yield; examples + +Examples +^^^^^^^^ + +Here is a simple example that demonstrates the behavior of generators and +generator functions:: + + >>> def echo(value=None): + ... print("Execution starts when 'next()' is called for the first time.") + ... try: + ... while True: + ... try: + ... value = (yield value) + ... except Exception as e: + ... value = e + ... finally: + ... print("Don't forget to clean up when 'close()' is called.") + ... + >>> generator = echo(1) + >>> print(next(generator)) + Execution starts when 'next()' is called for the first time. + 1 + >>> print(next(generator)) + None + >>> print(generator.send(2)) + 2 + >>> generator.throw(TypeError, "spam") + TypeError('spam',) + >>> generator.close() + Don't forget to clean up when 'close()' is called. + +For examples using ``yield from``, see :ref:`pep-380` in "What's New in +Python." + +.. _asynchronous-generator-functions: + +Asynchronous generator functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The presence of a yield expression in a function or method defined using +:keyword:`async def` further defines the function as an +:term:`asynchronous generator` function. + +When an asynchronous generator function is called, it returns an +asynchronous iterator known as an asynchronous generator object. +That object then controls the execution of the generator function. +An asynchronous generator object is typically used in an +:keyword:`async for` statement in a coroutine function analogously to +how a generator object would be used in a :keyword:`for` statement. + +Calling one of the asynchronous generator's methods returns an :term:`awaitable` +object, and the execution starts when this object is awaited on. At that time, +the execution proceeds to the first yield expression, where it is suspended +again, returning the value of :token:`~python-grammar:yield_list` to the +awaiting coroutine. As with a generator, suspension means that all local state +is retained, including the current bindings of local variables, the instruction +pointer, the internal evaluation stack, and the state of any exception handling. +When the execution is resumed by awaiting on the next object returned by the +asynchronous generator's methods, the function can proceed exactly as if the +yield expression were just another external call. The value of the yield +expression after resuming depends on the method which resumed the execution. If +:meth:`~agen.__anext__` is used then the result is :const:`None`. Otherwise, if +:meth:`~agen.asend` is used, then the result will be the value passed in to that +method. + +If an asynchronous generator happens to exit early by :keyword:`break`, the caller +task being cancelled, or other exceptions, the generator's async cleanup code +will run and possibly raise exceptions or access context variables in an +unexpected context--perhaps after the lifetime of tasks it depends, or +during the event loop shutdown when the async-generator garbage collection hook +is called. +To prevent this, the caller must explicitly close the async generator by calling +:meth:`~agen.aclose` method to finalize the generator and ultimately detach it +from the event loop. + +In an asynchronous generator function, yield expressions are allowed anywhere +in a :keyword:`try` construct. However, if an asynchronous generator is not +resumed before it is finalized (by reaching a zero reference count or by +being garbage collected), then a yield expression within a :keyword:`!try` +construct could result in a failure to execute pending :keyword:`finally` +clauses. In this case, it is the responsibility of the event loop or +scheduler running the asynchronous generator to call the asynchronous +generator-iterator's :meth:`~agen.aclose` method and run the resulting +coroutine object, thus allowing any pending :keyword:`!finally` clauses +to execute. + +To take care of finalization upon event loop termination, an event loop should +define a *finalizer* function which takes an asynchronous generator-iterator and +presumably calls :meth:`~agen.aclose` and executes the coroutine. +This *finalizer* may be registered by calling :func:`sys.set_asyncgen_hooks`. +When first iterated over, an asynchronous generator-iterator will store the +registered *finalizer* to be called upon finalization. For a reference example +of a *finalizer* method see the implementation of +``asyncio.Loop.shutdown_asyncgens`` in :source:`Lib/asyncio/base_events.py`. + +The expression ``yield from <expr>`` is a syntax error when used in an +asynchronous generator function. + +.. _primaries: + +Primaries +========= + +.. index:: single: primary + +Primaries represent the most tightly bound operations of the language. Their +syntax is: + +.. productionlist:: python-grammar + primary: `atom` | `attributeref` | `subscription` | `call` + + +.. _attribute-references: + +Attribute references +-------------------- + +.. index:: + pair: attribute; reference + single: . (dot); attribute reference + +An attribute reference is a primary followed by a period and a name: + +.. productionlist:: python-grammar + attributeref: `primary` "." `identifier` + +.. index:: + pair: exception; AttributeError + pair: object; module + pair: object; list + +The primary must evaluate to an object of a type that supports attribute +references, which most objects do. This object is then asked to produce the +attribute whose name is the identifier. The type and value produced is +determined by the object. Multiple evaluations of the same attribute +reference may yield different objects. + +This production can be customized by overriding the +:meth:`~object.__getattribute__` method or the :meth:`~object.__getattr__` +method. The :meth:`!__getattribute__` method is called first and either +returns a value or raises :exc:`AttributeError` if the attribute is not +available. + +If an :exc:`AttributeError` is raised and the object has a :meth:`!__getattr__` +method, that method is called as a fallback. + +.. _subscriptions: + +Subscriptions and slicings +-------------------------- + +.. index:: + single: subscription + single: [] (square brackets); subscription + +.. index:: + pair: object; sequence + pair: object; mapping + pair: object; string + pair: object; tuple + pair: object; list + pair: object; dictionary + pair: sequence; item + +The :dfn:`subscription` syntax is usually used for selecting an element from a +:ref:`container <sequence-types>` -- for example, to get a value from +a :class:`dict`:: + + >>> digits_by_name = {'one': 1, 'two': 2} + >>> digits_by_name['two'] # Subscripting a dictionary using the key 'two' + 2 + +In the subscription syntax, the object being subscribed -- a +:ref:`primary <primaries>` -- is followed by a :dfn:`subscript` in +square brackets. +In the simplest case, the subscript is a single expression. + +Depending on the type of the object being subscribed, the subscript is +sometimes called a :term:`key` (for mappings), :term:`index` (for sequences), +or *type argument* (for :term:`generic types <generic type>`). +Syntactically, these are all equivalent:: + + >>> colors = ['red', 'blue', 'green', 'black'] + >>> colors[3] # Subscripting a list using the index 3 + 'black' + + >>> list[str] # Parameterizing the list type using the type argument str + list[str] + +At runtime, the interpreter will evaluate the primary and +the subscript, and call the primary's :meth:`~object.__getitem__` or +:meth:`~object.__class_getitem__` :term:`special method` with the subscript +as argument. +For more details on which of these methods is called, see +:ref:`classgetitem-versus-getitem`. + +To show how subscription works, we can define a custom object that +implements :meth:`~object.__getitem__` and prints out the value of +the subscript:: + + >>> class SubscriptionDemo: + ... def __getitem__(self, key): + ... print(f'subscripted with: {key!r}') + ... + >>> demo = SubscriptionDemo() + >>> demo[1] + subscripted with: 1 + >>> demo['a' * 3] + subscripted with: 'aaa' + +See :meth:`~object.__getitem__` documentation for how built-in types handle +subscription. + +Subscriptions may also be used as targets in :ref:`assignment <assignment>` or +:ref:`deletion <del>` statements. +In these cases, the interpreter will call the subscripted object's +:meth:`~object.__setitem__` or :meth:`~object.__delitem__` +:term:`special method`, respectively, instead of :meth:`~object.__getitem__`. + +.. code-block:: + + >>> colors = ['red', 'blue', 'green', 'black'] + >>> colors[3] = 'white' # Setting item at index + >>> colors + ['red', 'blue', 'green', 'white'] + >>> del colors[3] # Deleting item at index 3 + >>> colors + ['red', 'blue', 'green'] + +All advanced forms of *subscript* documented in the following sections +are also usable for assignment and deletion. + + +.. index:: + single: slicing + single: slice + single: : (colon); slicing + single: , (comma); slicing + +.. index:: + pair: object; sequence + pair: object; string + pair: object; tuple + pair: object; list + +.. _slicings: + +Slicings +^^^^^^^^ + +A more advanced form of subscription, :dfn:`slicing`, is commonly used +to extract a portion of a :ref:`sequence <datamodel-sequences>`. +In this form, the subscript is a :term:`slice`: up to three +expressions separated by colons. +Any of the expressions may be omitted, but a slice must contain at least one +colon:: + + >>> number_names = ['zero', 'one', 'two', 'three', 'four', 'five'] + >>> number_names[1:3] + ['one', 'two'] + >>> number_names[1:] + ['one', 'two', 'three', 'four', 'five'] + >>> number_names[:3] + ['zero', 'one', 'two'] + >>> number_names[:] + ['zero', 'one', 'two', 'three', 'four', 'five'] + >>> number_names[::2] + ['zero', 'two', 'four'] + >>> number_names[:-3] + ['zero', 'one', 'two'] + >>> del number_names[4:] + >>> number_names + ['zero', 'one', 'two', 'three'] + +When a slice is evaluated, the interpreter constructs a :class:`slice` object +whose :attr:`~slice.start`, :attr:`~slice.stop` and +:attr:`~slice.step` attributes, respectively, are the results of the +expressions between the colons. +Any missing expression evaluates to :const:`None`. +This :class:`!slice` object is then passed to the :meth:`~object.__getitem__` +or :meth:`~object.__class_getitem__` :term:`special method`, as above. :: + + # continuing with the SubscriptionDemo instance defined above: + >>> demo[2:3] + subscripted with: slice(2, 3, None) + >>> demo[::'spam'] + subscripted with: slice(None, None, 'spam') + + +Comma-separated subscripts +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The subscript can also be given as two or more comma-separated expressions +or slices:: + + # continuing with the SubscriptionDemo instance defined above: + >>> demo[1, 2, 3] + subscripted with: (1, 2, 3) + >>> demo[1:2, 3] + subscripted with: (slice(1, 2, None), 3) + +This form is commonly used with numerical libraries for slicing +multi-dimensional data. +In this case, the interpreter constructs a :class:`tuple` of the results of the +expressions or slices, and passes this tuple to the :meth:`~object.__getitem__` +or :meth:`~object.__class_getitem__` :term:`special method`, as above. + +The subscript may also be given as a single expression or slice followed +by a comma, to specify a one-element tuple:: + + >>> demo['spam',] + subscripted with: ('spam',) + + +"Starred" subscriptions +^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.11 + Expressions in *tuple_slices* may be starred. See :pep:`646`. + +The subscript can also contain a starred expression. +In this case, the interpreter unpacks the result into a tuple, and passes +this tuple to :meth:`~object.__getitem__` or :meth:`~object.__class_getitem__`:: + + # continuing with the SubscriptionDemo instance defined above: + >>> demo[*range(10)] + subscripted with: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) + +Starred expressions may be combined with comma-separated expressions +and slices:: + + >>> demo['a', 'b', *range(3), 'c'] + subscripted with: ('a', 'b', 0, 1, 2, 'c') + + +Formal subscription grammar +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. grammar-snippet:: + :group: python-grammar + + subscription: `primary` '[' `subscript` ']' + subscript: `single_subscript` | `tuple_subscript` + single_subscript: `proper_slice` | `assignment_expression` + proper_slice: [`expression`] ":" [`expression`] [ ":" [`expression`] ] + tuple_subscript: ','.(`single_subscript` | `starred_expression`)+ [','] + +Recall that the ``|`` operator :ref:`denotes ordered choice <notation>`. +Specifically, in :token:`!subscript`, if both alternatives would match, the +first (:token:`!single_subscript`) has priority. + +.. index:: + pair: object; callable + single: call + single: argument; call semantics + single: () (parentheses); call + single: , (comma); argument list + single: = (equals); in function calls + +.. _calls: + +Calls +----- + +A call calls a callable object (e.g., a :term:`function`) with a possibly empty +series of :term:`arguments <argument>`: + +.. productionlist:: python-grammar + call: `primary` "(" [`argument_list` [","] | `comprehension`] ")" + argument_list: `positional_arguments` ["," `starred_and_keywords`] + : ["," `keywords_arguments`] + : | `starred_and_keywords` ["," `keywords_arguments`] + : | `keywords_arguments` + positional_arguments: `positional_item` ("," `positional_item`)* + positional_item: `assignment_expression` | "*" `expression` + starred_and_keywords: ("*" `expression` | `keyword_item`) + : ("," "*" `expression` | "," `keyword_item`)* + keywords_arguments: (`keyword_item` | "**" `expression`) + : ("," `keyword_item` | "," "**" `expression`)* + keyword_item: `identifier` "=" `expression` + +An optional trailing comma may be present after the positional and keyword arguments +but does not affect the semantics. + +.. index:: + single: parameter; call semantics + +The primary must evaluate to a callable object (user-defined functions, built-in +functions, methods of built-in objects, class objects, methods of class +instances, and all objects having a :meth:`~object.__call__` method are callable). All +argument expressions are evaluated before the call is attempted. Please refer +to section :ref:`function` for the syntax of formal :term:`parameter` lists. + +.. XXX update with kwonly args PEP + +If keyword arguments are present, they are first converted to positional +arguments, as follows. First, a list of unfilled slots is created for the +formal parameters. If there are N positional arguments, they are placed in the +first N slots. Next, for each keyword argument, the identifier is used to +determine the corresponding slot (if the identifier is the same as the first +formal parameter name, the first slot is used, and so on). If the slot is +already filled, a :exc:`TypeError` exception is raised. Otherwise, the +argument is placed in the slot, filling it (even if the expression is +``None``, it fills the slot). When all arguments have been processed, the slots +that are still unfilled are filled with the corresponding default value from the +function definition. (Default values are calculated, once, when the function is +defined; thus, a mutable object such as a list or dictionary used as default +value will be shared by all calls that don't specify an argument value for the +corresponding slot; this should usually be avoided.) If there are any unfilled +slots for which no default value is specified, a :exc:`TypeError` exception is +raised. Otherwise, the list of filled slots is used as the argument list for +the call. + +.. impl-detail:: + + An implementation may provide built-in functions whose positional parameters + do not have names, even if they are 'named' for the purpose of documentation, + and which therefore cannot be supplied by keyword. In CPython, this is the + case for functions implemented in C that use :c:func:`PyArg_ParseTuple` to + parse their arguments. + +If there are more positional arguments than there are formal parameter slots, a +:exc:`TypeError` exception is raised, unless a formal parameter using the syntax +``*identifier`` is present; in this case, that formal parameter receives a tuple +containing the excess positional arguments (or an empty tuple if there were no +excess positional arguments). + +If any keyword argument does not correspond to a formal parameter name, a +:exc:`TypeError` exception is raised, unless a formal parameter using the syntax +``**identifier`` is present; in this case, that formal parameter receives a +dictionary containing the excess keyword arguments (using the keywords as keys +and the argument values as corresponding values), or a (new) empty dictionary if +there were no excess keyword arguments. + +.. index:: + single: * (asterisk); in function calls + single: unpacking; in function calls + +If the syntax ``*expression`` appears in the function call, ``expression`` must +evaluate to an :term:`iterable`. Elements from these iterables are +treated as if they were additional positional arguments. For the call +``f(x1, x2, *y, x3, x4)``, if *y* evaluates to a sequence *y1*, ..., *yM*, +this is equivalent to a call with M+4 positional arguments *x1*, *x2*, +*y1*, ..., *yM*, *x3*, *x4*. + +A consequence of this is that although the ``*expression`` syntax may appear +*after* explicit keyword arguments, it is processed *before* the +keyword arguments (and any ``**expression`` arguments -- see below). So:: + + >>> def f(a, b): + ... print(a, b) + ... + >>> f(b=1, *(2,)) + 2 1 + >>> f(a=1, *(2,)) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + TypeError: f() got multiple values for keyword argument 'a' + >>> f(1, *(2,)) + 1 2 + +It is unusual for both keyword arguments and the ``*expression`` syntax to be +used in the same call, so in practice this confusion does not often arise. + +.. index:: + single: **; in function calls + +If the syntax ``**expression`` appears in the function call, ``expression`` must +evaluate to a :term:`mapping`, the contents of which are treated as +additional keyword arguments. If a parameter matching a key has already been +given a value (by an explicit keyword argument, or from another unpacking), +a :exc:`TypeError` exception is raised. + +When ``**expression`` is used, each key in this mapping must be +a string. +Each value from the mapping is assigned to the first formal parameter +eligible for keyword assignment whose name is equal to the key. +A key need not be a Python identifier (e.g. ``"max-temp °F"`` is acceptable, +although it will not match any formal parameter that could be declared). +If there is no match to a formal parameter +the key-value pair is collected by the ``**`` parameter, if there is one, +or if there is not, a :exc:`TypeError` exception is raised. + +Formal parameters using the syntax ``*identifier`` or ``**identifier`` cannot be +used as positional argument slots or as keyword argument names. + +.. versionchanged:: 3.5 + Function calls accept any number of ``*`` and ``**`` unpackings, + positional arguments may follow iterable unpackings (``*``), + and keyword arguments may follow dictionary unpackings (``**``). + Originally proposed by :pep:`448`. + +A call always returns some value, possibly ``None``, unless it raises an +exception. How this value is computed depends on the type of the callable +object. + +If it is--- + +a user-defined function: + .. index:: + pair: function; call + triple: user-defined; function; call + pair: object; user-defined function + pair: object; function + + The code block for the function is executed, passing it the argument list. The + first thing the code block will do is bind the formal parameters to the + arguments; this is described in section :ref:`function`. When the code block + executes a :keyword:`return` statement, this specifies the return value of the + function call. If execution reaches the end of the code block without + executing a :keyword:`return` statement, the return value is ``None``. + +a built-in function or method: + .. index:: + pair: function; call + pair: built-in function; call + pair: method; call + pair: built-in method; call + pair: object; built-in method + pair: object; built-in function + pair: object; method + pair: object; function + + The result is up to the interpreter; see :ref:`built-in-funcs` for the + descriptions of built-in functions and methods. + +a class object: + .. index:: + pair: object; class + pair: class object; call + + A new instance of that class is returned. + +a class instance method: + .. index:: + pair: object; class instance + pair: object; instance + pair: class instance; call + + The corresponding user-defined function is called, with an argument list that is + one longer than the argument list of the call: the instance becomes the first + argument. + +a class instance: + .. index:: + pair: instance; call + single: __call__() (object method) + + The class must define a :meth:`~object.__call__` method; the effect is then the same as + if that method was called. + + +.. index:: pair: keyword; await +.. _await: + +Await expression +================ + +Suspend the execution of :term:`coroutine` on an :term:`awaitable` object. +Can only be used inside a :term:`coroutine function`. + +.. productionlist:: python-grammar + await_expr: "await" `primary` + +.. versionadded:: 3.5 + + +.. _power: + +The power operator +================== + +.. index:: + pair: power; operation + pair: operator; ** + +The power operator binds more tightly than unary operators on its left; it binds +less tightly than unary operators on its right. The syntax is: + +.. productionlist:: python-grammar + power: (`await_expr` | `primary`) ["**" `u_expr`] + +Thus, in an unparenthesized sequence of power and unary operators, the operators +are evaluated from right to left (this does not constrain the evaluation order +for the operands): ``-1**2`` results in ``-1``. + +The power operator has the same semantics as the built-in :func:`pow` function, +when called with two arguments: it yields its left argument raised to the power +of its right argument. +Numeric arguments are first :ref:`converted to a common type <stdtypes-mixed-arithmetic>`, +and the result is of that type. + +For int operands, the result has the same type as the operands unless the second +argument is negative; in that case, all arguments are converted to float and a +float result is delivered. For example, ``10**2`` returns ``100``, but +``10**-2`` returns ``0.01``. + +Raising ``0.0`` to a negative power results in a :exc:`ZeroDivisionError`. +Raising a negative number to a fractional power results in a :class:`complex` +number. (In earlier versions it raised a :exc:`ValueError`.) + +This operation can be customized using the special :meth:`~object.__pow__` and +:meth:`~object.__rpow__` methods. + +.. _unary: + +Unary arithmetic and bitwise operations +======================================= + +.. index:: + triple: unary; arithmetic; operation + triple: unary; bitwise; operation + +All unary arithmetic and bitwise operations have the same priority: + +.. productionlist:: python-grammar + u_expr: `power` | "-" `u_expr` | "+" `u_expr` | "~" `u_expr` + +.. index:: + single: negation + single: minus + single: operator; - (minus) + single: - (minus); unary operator + +The unary ``-`` (minus) operator yields the negation of its numeric argument; the +operation can be overridden with the :meth:`~object.__neg__` special method. + +.. index:: + single: plus + single: operator; + (plus) + single: + (plus); unary operator + +The unary ``+`` (plus) operator yields its numeric argument unchanged; the +operation can be overridden with the :meth:`~object.__pos__` special method. + +.. index:: + single: inversion + pair: operator; ~ (tilde) + +The unary ``~`` (invert) operator yields the bitwise inversion of its integer +argument. The bitwise inversion of ``x`` is defined as ``-(x+1)``. It only +applies to integral numbers or to custom objects that override the +:meth:`~object.__invert__` special method. + + + +.. index:: pair: exception; TypeError + +In all three cases, if the argument does not have the proper type, a +:exc:`TypeError` exception is raised. + + +.. _binary: + +Binary arithmetic operations +============================ + +.. index:: triple: binary; arithmetic; operation + +The binary arithmetic operations have the conventional priority levels. Note +that some of these operations also apply to certain non-numeric types. Apart +from the power operator, there are only two levels, one for multiplicative +operators and one for additive operators: + +.. productionlist:: python-grammar + m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "@" `m_expr` | + : `m_expr` "//" `u_expr` | `m_expr` "/" `u_expr` | + : `m_expr` "%" `u_expr` + a_expr: `m_expr` | `a_expr` "+" `m_expr` | `a_expr` "-" `m_expr` + +.. index:: + single: multiplication + pair: operator; * (asterisk) + +The ``*`` (multiplication) operator yields the product of its arguments. The +arguments must either both be numbers, or one argument must be an integer and +the other must be a sequence. In the former case, the numbers are +:ref:`converted to a common real type <stdtypes-mixed-arithmetic>` and then +multiplied together. In the latter case, sequence repetition is performed; +a negative repetition factor yields an empty sequence. + +This operation can be customized using the special :meth:`~object.__mul__` and +:meth:`~object.__rmul__` methods. + +.. versionchanged:: 3.14 + If only one operand is a complex number, the other operand is converted + to a floating-point number. + +.. index:: + single: matrix multiplication + pair: operator; @ (at) + +The ``@`` (at) operator is intended to be used for matrix multiplication. No +builtin Python types implement this operator. + +This operation can be customized using the special :meth:`~object.__matmul__` and +:meth:`~object.__rmatmul__` methods. + +.. versionadded:: 3.5 + +.. index:: + pair: exception; ZeroDivisionError + single: division + pair: operator; / (slash) + pair: operator; // + +The ``/`` (division) and ``//`` (floor division) operators yield the quotient of +their arguments. The numeric arguments are first +:ref:`converted to a common type <stdtypes-mixed-arithmetic>`. +Division of integers yields a float, while floor division of integers results in an +integer; the result is that of mathematical division with the 'floor' function +applied to the result. Division by zero raises the :exc:`ZeroDivisionError` +exception. + +The division operation can be customized using the special :meth:`~object.__truediv__` +and :meth:`~object.__rtruediv__` methods. +The floor division operation can be customized using the special +:meth:`~object.__floordiv__` and :meth:`~object.__rfloordiv__` methods. + +.. index:: + single: modulo + pair: operator; % (percent) + +The ``%`` (modulo) operator yields the remainder from the division of the first +argument by the second. The numeric arguments are first +:ref:`converted to a common type <stdtypes-mixed-arithmetic>`. +A zero right argument raises the :exc:`ZeroDivisionError` exception. The +arguments may be floating-point numbers, e.g., ``3.14%0.7`` equals ``0.34`` +(since ``3.14`` equals ``4*0.7 + 0.34``.) The modulo operator always yields a +result with the same sign as its second operand (or zero); the absolute value of +the result is strictly smaller than the absolute value of the second operand +[#]_. + +The floor division and modulo operators are connected by the following +identity: ``x == (x//y)*y + (x%y)``. Floor division and modulo are also +connected with the built-in function :func:`divmod`: ``divmod(x, y) == (x//y, +x%y)``. [#]_. + +In addition to performing the modulo operation on numbers, the ``%`` operator is +also overloaded by string objects to perform old-style string formatting (also +known as interpolation). The syntax for string formatting is described in the +Python Library Reference, section :ref:`old-string-formatting`. + +The *modulo* operation can be customized using the special :meth:`~object.__mod__` +and :meth:`~object.__rmod__` methods. + +The floor division operator, the modulo operator, and the :func:`divmod` +function are not defined for complex numbers. Instead, convert to a +floating-point number using the :func:`abs` function if appropriate. + +.. index:: + single: addition + single: operator; + (plus) + single: + (plus); binary operator + +The ``+`` (addition) operator yields the sum of its arguments. The arguments +must either both be numbers or both be sequences of the same type. In the +former case, the numbers are +:ref:`converted to a common real type <stdtypes-mixed-arithmetic>` and then +added together. +In the latter case, the sequences are concatenated. + +This operation can be customized using the special :meth:`~object.__add__` and +:meth:`~object.__radd__` methods. + +.. versionchanged:: 3.14 + If only one operand is a complex number, the other operand is converted + to a floating-point number. + +.. index:: + single: subtraction + single: operator; - (minus) + single: - (minus); binary operator + +The ``-`` (subtraction) operator yields the difference of its arguments. +The numeric arguments are first +:ref:`converted to a common real type <stdtypes-mixed-arithmetic>`. + +This operation can be customized using the special :meth:`~object.__sub__` and +:meth:`~object.__rsub__` methods. + +.. versionchanged:: 3.14 + If only one operand is a complex number, the other operand is converted + to a floating-point number. + + +.. _shifting: + +Shifting operations +=================== + +.. index:: + pair: shifting; operation + pair: operator; << + pair: operator; >> + +The shifting operations have lower priority than the arithmetic operations: + +.. productionlist:: python-grammar + shift_expr: `a_expr` | `shift_expr` ("<<" | ">>") `a_expr` + +These operators accept integers as arguments. They shift the first argument to +the left or right by the number of bits given by the second argument. + +The left shift operation can be customized using the special :meth:`~object.__lshift__` +and :meth:`~object.__rlshift__` methods. +The right shift operation can be customized using the special :meth:`~object.__rshift__` +and :meth:`~object.__rrshift__` methods. + +.. index:: pair: exception; ValueError + +A right shift by *n* bits is defined as floor division by ``pow(2,n)``. A left +shift by *n* bits is defined as multiplication with ``pow(2,n)``. + + +.. _bitwise: + +Binary bitwise operations +========================= + +.. index:: triple: binary; bitwise; operation + +Each of the three bitwise operations has a different priority level: + +.. productionlist:: python-grammar + and_expr: `shift_expr` | `and_expr` "&" `shift_expr` + xor_expr: `and_expr` | `xor_expr` "^" `and_expr` + or_expr: `xor_expr` | `or_expr` "|" `xor_expr` + +.. index:: + pair: bitwise; and + pair: operator; & (ampersand) + +The ``&`` operator yields the bitwise AND of its arguments, which must be +integers or one of them must be a custom object overriding :meth:`~object.__and__` or +:meth:`~object.__rand__` special methods. + +.. index:: + pair: bitwise; xor + pair: exclusive; or + pair: operator; ^ (caret) + +The ``^`` operator yields the bitwise XOR (exclusive OR) of its arguments, which +must be integers or one of them must be a custom object overriding :meth:`~object.__xor__` or +:meth:`~object.__rxor__` special methods. + +.. index:: + pair: bitwise; or + pair: inclusive; or + pair: operator; | (vertical bar) + +The ``|`` operator yields the bitwise (inclusive) OR of its arguments, which +must be integers or one of them must be a custom object overriding :meth:`~object.__or__` or +:meth:`~object.__ror__` special methods. + + +.. _comparisons: + +Comparisons +=========== + +.. index:: + single: comparison + pair: C; language + pair: operator; < (less) + pair: operator; > (greater) + pair: operator; <= + pair: operator; >= + pair: operator; == + pair: operator; != + +Unlike C, all comparison operations in Python have the same priority, which is +lower than that of any arithmetic, shifting or bitwise operation. Also unlike +C, expressions like ``a < b < c`` have the interpretation that is conventional +in mathematics: + +.. productionlist:: python-grammar + comparison: `or_expr` (`comp_operator` `or_expr`)* + comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!=" + : | "is" ["not"] | ["not"] "in" + +Comparisons yield boolean values: ``True`` or ``False``. Custom +:dfn:`rich comparison methods` may return non-boolean values. In this case +Python will call :func:`bool` on such value in boolean contexts. + +.. index:: pair: chaining; comparisons + +Comparisons can be chained arbitrarily, e.g., ``x < y <= z`` is equivalent to +``x < y and y <= z``, except that ``y`` is evaluated only once (but in both +cases ``z`` is not evaluated at all when ``x < y`` is found to be false). + +Formally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*, *op2*, ..., +*opN* are comparison operators, then ``a op1 b op2 c ... y opN z`` is equivalent +to ``a op1 b and b op2 c and ... y opN z``, except that each expression is +evaluated at most once. + +Note that ``a op1 b op2 c`` doesn't imply any kind of comparison between *a* and +*c*, so that, e.g., ``x < y > z`` is perfectly legal (though perhaps not +pretty). + +.. _expressions-value-comparisons: + +Value comparisons +----------------- + +The operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare the +values of two objects. The objects do not need to have the same type. + +Chapter :ref:`objects` states that objects have a value (in addition to type +and identity). The value of an object is a rather abstract notion in Python: +For example, there is no canonical access method for an object's value. Also, +there is no requirement that the value of an object should be constructed in a +particular way, e.g. comprised of all its data attributes. Comparison operators +implement a particular notion of what the value of an object is. One can think +of them as defining the value of an object indirectly, by means of their +comparison implementation. + +Because all types are (direct or indirect) subtypes of :class:`object`, they +inherit the default comparison behavior from :class:`object`. Types can +customize their comparison behavior by implementing +:dfn:`rich comparison methods` like :meth:`~object.__lt__`, described in +:ref:`customization`. + +The default behavior for equality comparison (``==`` and ``!=``) is based on +the identity of the objects. Hence, equality comparison of instances with the +same identity results in equality, and equality comparison of instances with +different identities results in inequality. A motivation for this default +behavior is the desire that all objects should be reflexive (i.e. ``x is y`` +implies ``x == y``). + +A default order comparison (``<``, ``>``, ``<=``, and ``>=``) is not provided; +an attempt raises :exc:`TypeError`. A motivation for this default behavior is +the lack of a similar invariant as for equality. + +The behavior of the default equality comparison, that instances with different +identities are always unequal, may be in contrast to what types will need that +have a sensible definition of object value and value-based equality. Such +types will need to customize their comparison behavior, and in fact, a number +of built-in types have done that. + +The following list describes the comparison behavior of the most important +built-in types. + +* Numbers of built-in numeric types (:ref:`typesnumeric`) and of the standard + library types :class:`fractions.Fraction` and :class:`decimal.Decimal` can be + compared within and across their types, with the restriction that complex + numbers do not support order comparison. Within the limits of the types + involved, they compare mathematically (algorithmically) correct without loss + of precision. + + The not-a-number values ``float('NaN')`` and ``decimal.Decimal('NaN')`` are + special. Any ordered comparison of a number to a not-a-number value is false. + A counter-intuitive implication is that not-a-number values are not equal to + themselves. For example, if ``x = float('NaN')``, ``3 < x``, ``x < 3`` and + ``x == x`` are all false, while ``x != x`` is true. This behavior is + compliant with IEEE 754. + +* ``None`` and :data:`NotImplemented` are singletons. :PEP:`8` advises that + comparisons for singletons should always be done with ``is`` or ``is not``, + never the equality operators. + +* Binary sequences (instances of :class:`bytes` or :class:`bytearray`) can be + compared within and across their types. They compare lexicographically using + the numeric values of their elements. + +* Strings (instances of :class:`str`) compare lexicographically using the + numerical Unicode code points (the result of the built-in function + :func:`ord`) of their characters. [#]_ + + Strings and binary sequences cannot be directly compared. + +* Sequences (instances of :class:`tuple`, :class:`list`, or :class:`range`) can + be compared only within each of their types, with the restriction that ranges + do not support order comparison. Equality comparison across these types + results in inequality, and ordering comparison across these types raises + :exc:`TypeError`. + + Sequences compare lexicographically using comparison of corresponding + elements. The built-in containers typically assume identical objects are + equal to themselves. That lets them bypass equality tests for identical + objects to improve performance and to maintain their internal invariants. + + Lexicographical comparison between built-in collections works as follows: + + - For two collections to compare equal, they must be of the same type, have + the same length, and each pair of corresponding elements must compare + equal (for example, ``[1,2] == (1,2)`` is false because the type is not the + same). + + - Collections that support order comparison are ordered the same as their + first unequal elements (for example, ``[1,2,x] <= [1,2,y]`` has the same + value as ``x <= y``). If a corresponding element does not exist, the + shorter collection is ordered first (for example, ``[1,2] < [1,2,3]`` is + true). + +* Mappings (instances of :class:`dict`) compare equal if and only if they have + equal ``(key, value)`` pairs. Equality comparison of the keys and values + enforces reflexivity. + + Order comparisons (``<``, ``>``, ``<=``, and ``>=``) raise :exc:`TypeError`. + +* Sets (instances of :class:`set` or :class:`frozenset`) can be compared within + and across their types. + + They define order + comparison operators to mean subset and superset tests. Those relations do + not define total orderings (for example, the two sets ``{1,2}`` and ``{2,3}`` + are not equal, nor subsets of one another, nor supersets of one + another). Accordingly, sets are not appropriate arguments for functions + which depend on total ordering (for example, :func:`min`, :func:`max`, and + :func:`sorted` produce undefined results given a list of sets as inputs). + + Comparison of sets enforces reflexivity of its elements. + +* Most other built-in types have no comparison methods implemented, so they + inherit the default comparison behavior. + +User-defined classes that customize their comparison behavior should follow +some consistency rules, if possible: + +* Equality comparison should be reflexive. + In other words, identical objects should compare equal: + + ``x is y`` implies ``x == y`` + +* Comparison should be symmetric. + In other words, the following expressions should have the same result: + + ``x == y`` and ``y == x`` + + ``x != y`` and ``y != x`` + + ``x < y`` and ``y > x`` + + ``x <= y`` and ``y >= x`` + +* Comparison should be transitive. + The following (non-exhaustive) examples illustrate that: + + ``x > y and y > z`` implies ``x > z`` + + ``x < y and y <= z`` implies ``x < z`` + +* Inverse comparison should result in the boolean negation. + In other words, the following expressions should have the same result: + + ``x == y`` and ``not x != y`` + + ``x < y`` and ``not x >= y`` (for total ordering) + + ``x > y`` and ``not x <= y`` (for total ordering) + + The last two expressions apply to totally ordered collections (e.g. to + sequences, but not to sets or mappings). See also the + :deco:`~functools.total_ordering` decorator. + +* The :func:`hash` result should be consistent with equality. + Objects that are equal should either have the same hash value, + or be marked as unhashable. + +Python does not enforce these consistency rules. In fact, the not-a-number +values are an example for not following these rules. + + +.. _in: +.. _not in: +.. _membership-test-details: + +Membership test operations +-------------------------- + +The operators :keyword:`in` and :keyword:`not in` test for membership. ``x in +s`` evaluates to ``True`` if *x* is a member of *s*, and ``False`` otherwise. +``x not in s`` returns the negation of ``x in s``. All built-in sequences and +set types support this as well as dictionary, for which :keyword:`!in` tests +whether the dictionary has a given key. For container types such as list, tuple, +set, frozenset, dict, or collections.deque, the expression ``x in y`` is equivalent +to ``any(x is e or x == e for e in y)``. + +For the string and bytes types, ``x in y`` is ``True`` if and only if *x* is a +substring of *y*. An equivalent test is ``y.find(x) != -1``. Empty strings are +always considered to be a substring of any other string, so ``"" in "abc"`` will +return ``True``. + +For user-defined classes which define the :meth:`~object.__contains__` method, ``x in +y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and +``False`` otherwise. + +For user-defined classes which do not define :meth:`~object.__contains__` but do define +:meth:`~object.__iter__`, ``x in y`` is ``True`` if some value ``z``, for which the +expression ``x is z or x == z`` is true, is produced while iterating over ``y``. +If an exception is raised during the iteration, it is as if :keyword:`in` raised +that exception. + +Lastly, the old-style iteration protocol is tried: if a class defines +:meth:`~object.__getitem__`, ``x in y`` is ``True`` if and only if there is a non-negative +integer index *i* such that ``x is y[i] or x == y[i]``, and no lower integer index +raises the :exc:`IndexError` exception. (If any other exception is raised, it is as +if :keyword:`in` raised that exception). + +.. index:: + pair: operator; in + pair: operator; not in + pair: membership; test + pair: object; sequence + +The operator :keyword:`not in` is defined to have the inverse truth value of +:keyword:`in`. + +.. index:: + pair: operator; is + pair: operator; is not + pair: identity; test + + +.. _is: +.. _is not: + +Identity comparisons +-------------------- + +The operators :keyword:`is` and :keyword:`is not` test for an object's identity: ``x +is y`` is true if and only if *x* and *y* are the same object. An Object's identity +is determined using the :meth:`id` function. ``x is not y`` yields the inverse +truth value. [#]_ + + +.. _booleans: +.. _and: +.. _or: +.. _not: + +Boolean operations +================== + +.. index:: + pair: Conditional; expression + pair: Boolean; operation + +.. productionlist:: python-grammar + or_test: `and_test` | `or_test` "or" `and_test` + and_test: `not_test` | `and_test` "and" `not_test` + not_test: `comparison` | "not" `not_test` + +In the context of Boolean operations, and also when expressions are used by +control flow statements, the following values are interpreted as false: +``False``, ``None``, zero of any numeric type, and empty strings and containers +(including strings, tuples, lists, dictionaries, sets and frozensets). All +other values are interpreted as true. User-defined objects can customize their +truth value by providing a :meth:`~object.__bool__` method. + +.. index:: pair: operator; not + +The operator :keyword:`not` yields ``True`` if its argument is false, ``False`` +otherwise. + +.. index:: pair: operator; and + +The expression ``x and y`` first evaluates *x*; if *x* is false, its value is +returned; otherwise, *y* is evaluated and the resulting value is returned. + +.. index:: pair: operator; or + +The expression ``x or y`` first evaluates *x*; if *x* is true, its value is +returned; otherwise, *y* is evaluated and the resulting value is returned. + +Note that neither :keyword:`and` nor :keyword:`or` restrict the value and type +they return to ``False`` and ``True``, but rather return the last evaluated +argument. This is sometimes useful, e.g., if ``s`` is a string that should be +replaced by a default value if it is empty, the expression ``s or 'foo'`` yields +the desired value. Because :keyword:`not` has to create a new value, it +returns a boolean value regardless of the type of its argument +(for example, ``not 'foo'`` produces ``False`` rather than ``''``.) + + +.. index:: + single: := (colon equals) + single: assignment expression + single: walrus operator + single: named expression + pair: assignment; expression + +.. _assignment-expressions: + +Assignment expressions +====================== + +.. productionlist:: python-grammar + assignment_expression: [`identifier` ":="] `expression` + +An assignment expression (sometimes also called a "named expression" or +"walrus") assigns an :token:`~python-grammar:expression` to an +:token:`~python-grammar:identifier`, while also returning the value of the +:token:`~python-grammar:expression`. + +One common use case is when handling matched regular expressions: + +.. code-block:: python + + if matching := pattern.search(data): + do_something(matching) + +Or, when processing a file stream in chunks: + +.. code-block:: python + + while chunk := file.read(9000): + process(chunk) + +Assignment expressions must be surrounded by parentheses when +used as expression statements and when used as sub-expressions in +slicing, conditional, lambda, +keyword-argument, and comprehension-if expressions and +in ``assert``, ``with``, and ``assignment`` statements. +In all other places where they can be used, parentheses are not required, +including in ``if`` and ``while`` statements. + +.. versionadded:: 3.8 + See :pep:`572` for more details about assignment expressions. + + +.. _if_expr: + +Conditional expressions +======================= + +.. index:: + pair: conditional; expression + pair: ternary; operator + single: if; conditional expression + single: else; conditional expression + +.. productionlist:: python-grammar + conditional_expression: `or_test` ["if" `or_test` "else" `expression`] + expression: `conditional_expression` | `lambda_expr` + +A conditional expression (sometimes called a "ternary operator") is an +alternative to the if-else statement. As it is an expression, it returns a value +and can appear as a sub-expression. + +The expression ``x if C else y`` first evaluates the condition, *C* rather than *x*. +If *C* is true, *x* is evaluated and its value is returned; otherwise, *y* is +evaluated and its value is returned. + +See :pep:`308` for more details about conditional expressions. + + +.. _lambdas: +.. _lambda: + +Lambdas +======= + +.. index:: + pair: lambda; expression + pair: lambda; form + pair: anonymous; function + single: : (colon); lambda expression + +.. productionlist:: python-grammar + lambda_expr: "lambda" [`parameter_list`] ":" `expression` + +Lambda expressions (sometimes called lambda forms) are used to create anonymous +functions. The expression ``lambda parameters: expression`` yields a function +object. The unnamed object behaves like a function object defined with: + +.. code-block:: none + + def <lambda>(parameters): + return expression + +See section :ref:`function` for the syntax of parameter lists. Note that +functions created with lambda expressions cannot contain statements or +annotations. + + +.. index:: + single: comma + single: , (comma) + +.. _exprlists: + +Expression lists +================ + +.. index:: + pair: expression; list + single: , (comma); expression list + +.. productionlist:: python-grammar + starred_expression: "*" `or_expr` | `expression` + flexible_expression: `assignment_expression` | `starred_expression` + flexible_expression_list: `flexible_expression` ("," `flexible_expression`)* [","] + starred_expression_list: `starred_expression` ("," `starred_expression`)* [","] + expression_list: `expression` ("," `expression`)* [","] + yield_list: `expression_list` | `starred_expression` "," [`starred_expression_list`] + +.. index:: pair: object; tuple + +Except when part of a list or set display, an expression list +containing at least one comma yields a tuple. The length of +the tuple is the number of expressions in the list. The expressions are +evaluated from left to right. + +.. index:: pair: trailing; comma + +A trailing comma is required only to create a one-item tuple, +such as ``1,``; it is optional in all other cases. +A single expression without a +trailing comma doesn't create a tuple, but rather yields the value of that +expression. (To create an empty tuple, use an empty pair of parentheses: +``()``.) + + +.. _iterable-unpacking: + +.. index:: + pair: iterable; unpacking + single: * (asterisk); in expression lists + +Iterable unpacking +------------------ + +In an expression list or tuple, list or set display, any expression +may be prefixed with an asterisk (``*``). +This denotes :dfn:`iterable unpacking`. + +At runtime, the asterisk-prefixed expression must evaluate +to an :term:`iterable`. +The iterable is expanded into a sequence of items, +which are included in the new tuple, list, or set, at the site of +the unpacking. + +.. versionadded:: 3.5 + Iterable unpacking in expression lists, originally proposed by :pep:`448`. + +.. versionadded:: 3.11 + Any item in an expression list may be starred. See :pep:`646`. + + +.. _evalorder: + +Evaluation order +================ + +.. index:: pair: evaluation; order + +Python evaluates expressions from left to right. Notice that while evaluating +an assignment, the right-hand side is evaluated before the left-hand side. + +In the following lines, expressions will be evaluated in the arithmetic order of +their suffixes:: + + expr1, expr2, expr3, expr4 + (expr1, expr2, expr3, expr4) + {expr1: expr2, expr3: expr4} + expr1 + expr2 * (expr3 - expr4) + expr1(expr2, expr3, *expr4, **expr5) + expr3, expr4 = expr1, expr2 + + +.. _operator-summary: +.. _operator-precedence: + +Operator precedence +=================== + +.. index:: + pair: operator; precedence + +The following table summarizes the operator precedence in Python, from highest +precedence (most binding) to lowest precedence (least binding). Operators in +the same box have the same precedence. Unless the syntax is explicitly given, +operators are binary. Operators in the same box group left to right (except for +exponentiation and conditional expressions, which group from right to left). + +Note that comparisons, membership tests, and identity tests, all have the same +precedence and have a left-to-right chaining feature as described in the +:ref:`comparisons` section. + + ++-----------------------------------------------+-------------------------------------+ +| Operator | Description | ++===============================================+=====================================+ +| ``(expressions...)``, | Binding or parenthesized | +| | expression, | +| ``[expressions...]``, | list display, | +| ``{key: value...}``, | dictionary display, | +| ``{expressions...}`` | set display | ++-----------------------------------------------+-------------------------------------+ +| ``x[index]``, ``x[index:index]`` | Subscription (including slicing), | +| ``x(arguments...)``, ``x.attribute`` | call, attribute reference | ++-----------------------------------------------+-------------------------------------+ +| :keyword:`await x <await>` | Await expression | ++-----------------------------------------------+-------------------------------------+ +| ``**`` | Exponentiation [#]_ | ++-----------------------------------------------+-------------------------------------+ +| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT | ++-----------------------------------------------+-------------------------------------+ +| ``*``, ``@``, ``/``, ``//``, ``%`` | Multiplication, matrix | +| | multiplication, division, floor | +| | division, remainder [#]_ | ++-----------------------------------------------+-------------------------------------+ +| ``+``, ``-`` | Addition and subtraction | ++-----------------------------------------------+-------------------------------------+ +| ``<<``, ``>>`` | Shifts | ++-----------------------------------------------+-------------------------------------+ +| ``&`` | Bitwise AND | ++-----------------------------------------------+-------------------------------------+ +| ``^`` | Bitwise XOR | ++-----------------------------------------------+-------------------------------------+ +| ``|`` | Bitwise OR | ++-----------------------------------------------+-------------------------------------+ +| :keyword:`in`, :keyword:`not in`, | Comparisons, including membership | +| :keyword:`is`, :keyword:`is not`, ``<``, | tests and identity tests | +| ``<=``, ``>``, ``>=``, ``!=``, ``==`` | | ++-----------------------------------------------+-------------------------------------+ +| :keyword:`not x <not>` | Boolean NOT | ++-----------------------------------------------+-------------------------------------+ +| :keyword:`and` | Boolean AND | ++-----------------------------------------------+-------------------------------------+ +| :keyword:`or` | Boolean OR | ++-----------------------------------------------+-------------------------------------+ +| :keyword:`if <if_expr>` -- :keyword:`!else` | Conditional expression | ++-----------------------------------------------+-------------------------------------+ +| :keyword:`lambda` | Lambda expression | ++-----------------------------------------------+-------------------------------------+ +| ``:=`` | Assignment expression | ++-----------------------------------------------+-------------------------------------+ + + +.. rubric:: Footnotes + +.. [#] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it may not be + true numerically due to roundoff. For example, and assuming a platform on which + a Python float is an IEEE 754 double-precision number, in order that ``-1e-100 % + 1e100`` have the same sign as ``1e100``, the computed result is ``-1e-100 + + 1e100``, which is numerically exactly equal to ``1e100``. The function + :func:`math.fmod` returns a result whose sign matches the sign of the + first argument instead, and so returns ``-1e-100`` in this case. Which approach + is more appropriate depends on the application. + +.. [#] If x is very close to an exact integer multiple of y, it's possible for + ``x//y`` to be one larger than ``(x-x%y)//y`` due to rounding. In such + cases, Python returns the latter result, in order to preserve that + ``divmod(x,y)[0] * y + x % y`` be very close to ``x``. + +.. [#] The Unicode standard distinguishes between :dfn:`code points` + (e.g. U+0041) and :dfn:`abstract characters` (e.g. "LATIN CAPITAL LETTER A"). + While most abstract characters in Unicode are only represented using one + code point, there is a number of abstract characters that can in addition be + represented using a sequence of more than one code point. For example, the + abstract character "LATIN CAPITAL LETTER C WITH CEDILLA" can be represented + as a single :dfn:`precomposed character` at code position U+00C7, or as a + sequence of a :dfn:`base character` at code position U+0043 (LATIN CAPITAL + LETTER C), followed by a :dfn:`combining character` at code position U+0327 + (COMBINING CEDILLA). + + The comparison operators on strings compare at the level of Unicode code + points. This may be counter-intuitive to humans. For example, + ``"\u00C7" == "\u0043\u0327"`` is ``False``, even though both strings + represent the same abstract character "LATIN CAPITAL LETTER C WITH CEDILLA". + + To compare strings at the level of abstract characters (that is, in a way + intuitive to humans), use :func:`unicodedata.normalize`. + +.. [#] Due to automatic garbage-collection, free lists, and the dynamic nature of + descriptors, you may notice seemingly unusual behaviour in certain uses of + the :keyword:`is` operator, like those involving comparisons between instance + methods, or constants. Check their documentation for more info. + +.. [#] The power operator ``**`` binds less tightly than an arithmetic or + bitwise unary operator on its right, that is, ``2**-1`` is ``0.5``. + +.. [#] The ``%`` operator is also used for string formatting; the same + precedence applies. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/grammar.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/grammar.rst new file mode 100644 index 00000000..0ce8e42d --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/grammar.rst @@ -0,0 +1,28 @@ +.. _full-grammar-specification: + +Full Grammar specification +========================== + +This is the full Python grammar, derived directly from the grammar +used to generate the CPython parser (see :source:`Grammar/python.gram`). +The version here omits details related to code generation and +error recovery. + +The notation used here is the same as in the preceding docs, +and is described in the :ref:`notation <notation>` section, +except for an extra complication: + +* ``~`` ("cut"): commit to the current alternative; fail the rule + if the alternative fails to parse + + Python mainly uses cuts for optimizations or improved error + messages. They often appear to be useless in the listing below. + + .. see gh-143054, and CutValidator in the source, if you want to change this: + + Cuts currently don't appear inside parentheses, brackets, lookaheads + and similar. + Their behavior in these contexts is deliberately left unspecified. + +.. literalinclude:: ../../Grammar/python.gram + :language: peg diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/import.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/import.rst new file mode 100644 index 00000000..2ff88cb6 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/import.rst @@ -0,0 +1,992 @@ + +.. _importsystem: + +***************** +The import system +***************** + +.. index:: single: import machinery + +Python code in one :term:`module` gains access to the code in another module +by the process of :term:`importing` it. The :keyword:`import` statement is +the most common way of invoking the import machinery, but it is not the only +way. Functions such as :func:`importlib.import_module` and built-in +:func:`__import__` can also be used to invoke the import machinery. + +The :keyword:`import` statement combines two operations; it searches for the +named module, then it binds the results of that search to a name in the local +scope. The search operation of the :keyword:`!import` statement is defined as +a call to the :func:`__import__` function, with the appropriate arguments. +The return value of :func:`__import__` is used to perform the name +binding operation of the :keyword:`!import` statement. See the +:keyword:`!import` statement for the exact details of that name binding +operation. + +A direct call to :func:`__import__` performs only the module search and, if +found, the module creation operation. While certain side-effects may occur, +such as the importing of parent packages, and the updating of various caches +(including :data:`sys.modules`), only the :keyword:`import` statement performs +a name binding operation. + +When an :keyword:`import` statement is executed, the standard builtin +:func:`__import__` function is called. Other mechanisms for invoking the +import system (such as :func:`importlib.import_module`) may choose to bypass +:func:`__import__` and use their own solutions to implement import semantics. + +When a module is first imported, Python searches for the module and if found, +it creates a module object [#fnmo]_, initializing it. If the named module +cannot be found, a :exc:`ModuleNotFoundError` is raised. Python implements various +strategies to search for the named module when the import machinery is +invoked. These strategies can be modified and extended by using various hooks +described in the sections below. + +.. versionchanged:: 3.3 + The import system has been updated to fully implement the second phase + of :pep:`302`. There is no longer any implicit import machinery - the full + import system is exposed through :data:`sys.meta_path`. In addition, + native namespace package support has been implemented (see :pep:`420`). + + +:mod:`importlib` +================ + +The :mod:`importlib` module provides a rich API for interacting with the +import system. For example :func:`importlib.import_module` provides a +recommended, simpler API than built-in :func:`__import__` for invoking the +import machinery. Refer to the :mod:`importlib` library documentation for +additional detail. + + + +Packages +======== + +.. index:: + single: package + +Python has only one type of module object, and all modules are of this type, +regardless of whether the module is implemented in Python, C, or something +else. To help organize modules and provide a naming hierarchy, Python has a +concept of :term:`packages <package>`. + +You can think of packages as the directories on a file system and modules as +files within directories, but don't take this analogy too literally since +packages and modules need not originate from the file system. For the +purposes of this documentation, we'll use this convenient analogy of +directories and files. Like file system directories, packages are organized +hierarchically, and packages may themselves contain subpackages, as well as +regular modules. + +It's important to keep in mind that all packages are modules, but not all +modules are packages. Or put another way, packages are just a special kind of +module. Specifically, any module that contains a ``__path__`` attribute is +considered a package. + +All modules have a name. Subpackage names are separated from their parent +package name by a dot, akin to Python's standard attribute access syntax. Thus +you might have a package called :mod:`email`, which in turn has a subpackage +called :mod:`email.mime` and a module within that subpackage called +:mod:`email.mime.text`. + + +Regular packages +---------------- + +.. index:: + pair: package; regular + +Python defines two types of packages, :term:`regular packages <regular +package>` and :term:`namespace packages <namespace package>`. Regular +packages are traditional packages as they existed in Python 3.2 and earlier. +A regular package is typically implemented as a directory containing an +``__init__.py`` file. When a regular package is imported, this +``__init__.py`` file is implicitly executed, and the objects it defines are +bound to names in the package's namespace. The ``__init__.py`` file can +contain the same Python code that any other module can contain, and Python +will add some additional attributes to the module when it is imported. + +For example, the following file system layout defines a top level ``parent`` +package with three subpackages:: + + parent/ + __init__.py + one/ + __init__.py + two/ + __init__.py + three/ + __init__.py + +Importing ``parent.one`` will implicitly execute ``parent/__init__.py`` and +``parent/one/__init__.py``. Subsequent imports of ``parent.two`` or +``parent.three`` will execute ``parent/two/__init__.py`` and +``parent/three/__init__.py`` respectively. + +A subdirectory inside a regular package that does not contain an +``__init__.py`` file is treated as an implicit +:ref:`namespace package <reference-namespace-package>` (a "namespace +subpackage") rooted in that parent. See :pep:`420` for the underlying +specification. + + +.. _reference-namespace-package: + +Namespace packages +------------------ + +.. index:: + pair: package; namespace + pair: package; portion + +A namespace package is a composite of various :term:`portions <portion>`, +where each portion contributes a subpackage to the parent package. Portions +may reside in different locations on the file system. Portions may also be +found in zip files, on the network, or anywhere else that Python searches +during import. Namespace packages may or may not correspond directly to +objects on the file system; they may be virtual modules that have no concrete +representation. + +Namespace packages do not use an ordinary list for their ``__path__`` +attribute. They instead use a custom iterable type which will automatically +perform a new search for package portions on the next import attempt within +that package if the path of their parent package (or :data:`sys.path` for a +top level package) changes. + +With namespace packages, there is no ``parent/__init__.py`` file. In fact, +there may be multiple ``parent`` directories found during import search, where +each one is provided by a different portion. Thus ``parent/one`` may not be +physically located next to ``parent/two``. In this case, Python will create a +namespace package for the top-level ``parent`` package whenever it or one of +its subpackages is imported. + +Namespace packages may also be nested inside a regular package. When the +import system searches a regular package's ``__path__`` and encounters a +subdirectory that does not contain an ``__init__.py`` file, that +subdirectory becomes a :term:`portion` contributing to a namespace +subpackage of the enclosing regular package. + +See also :pep:`420` for the namespace package specification. + + +Searching +========= + +To begin the search, Python needs the :term:`fully qualified <qualified name>` +name of the module (or package, but for the purposes of this discussion, the +difference is immaterial) being imported. This name may come from various +arguments to the :keyword:`import` statement, or from the parameters to the +:func:`importlib.import_module` or :func:`__import__` functions. + +This name will be used in various phases of the import search, and it may be +the dotted path to a submodule, e.g. ``foo.bar.baz``. In this case, Python +first tries to import ``foo``, then ``foo.bar``, and finally ``foo.bar.baz``. +If any of the intermediate imports fail, a :exc:`ModuleNotFoundError` is raised. + + +The module cache +---------------- + +.. index:: + single: sys.modules + +The first place checked during import search is :data:`sys.modules`. This +mapping serves as a cache of all modules that have been previously imported, +including the intermediate paths. So if ``foo.bar.baz`` was previously +imported, :data:`sys.modules` will contain entries for ``foo``, ``foo.bar``, +and ``foo.bar.baz``. Each key will have as its value the corresponding module +object. + +During import, the module name is looked up in :data:`sys.modules` and if +present, the associated value is the module satisfying the import, and the +process completes. However, if the value is ``None``, then a +:exc:`ModuleNotFoundError` is raised. If the module name is missing, Python will +continue searching for the module. + +:data:`sys.modules` is writable. Deleting a key may not destroy the +associated module (as other modules may hold references to it), +but it will invalidate the cache entry for the named module, causing +Python to search anew for the named module upon its next +import. The key can also be assigned to ``None``, forcing the next import +of the module to result in a :exc:`ModuleNotFoundError`. + +Beware though, as if you keep a reference to the module object, +invalidate its cache entry in :data:`sys.modules`, and then re-import the +named module, the two module objects will *not* be the same. By contrast, +:func:`importlib.reload` will reuse the *same* module object, and simply +reinitialise the module contents by rerunning the module's code. + + +.. _finders-and-loaders: + +Finders and loaders +------------------- + +.. index:: + single: finder + single: loader + single: module spec + +If the named module is not found in :data:`sys.modules`, then Python's import +protocol is invoked to find and load the module. This protocol consists of +two conceptual objects, :term:`finders <finder>` and :term:`loaders <loader>`. +A finder's job is to determine whether it can find the named module using +whatever strategy it knows about. Objects that implement both of these +interfaces are referred to as :term:`importers <importer>` - they return +themselves when they find that they can load the requested module. + +Python includes a number of default finders and importers. The first one +knows how to locate built-in modules, and the second knows how to locate +frozen modules. A third default finder searches an :term:`import path` +for modules. The :term:`import path` is a list of locations that may +name file system paths or zip files. It can also be extended to search +for any locatable resource, such as those identified by URLs. + +The import machinery is extensible, so new finders can be added to extend the +range and scope of module searching. + +Finders do not actually load modules. If they can find the named module, they +return a :dfn:`module spec`, an encapsulation of the module's import-related +information, which the import machinery then uses when loading the module. + +The following sections describe the protocol for finders and loaders in more +detail, including how you can create and register new ones to extend the +import machinery. + +.. versionchanged:: 3.4 + In previous versions of Python, finders returned :term:`loaders <loader>` + directly, whereas now they return module specs which *contain* loaders. + Loaders are still used during import but have fewer responsibilities. + +Import hooks +------------ + +.. index:: + single: import hooks + single: meta hooks + single: path hooks + pair: hooks; import + pair: hooks; meta + pair: hooks; path + +The import machinery is designed to be extensible; the primary mechanism for +this are the *import hooks*. There are two types of import hooks: *meta +hooks* and *import path hooks*. + +Meta hooks are called at the start of import processing, before any other +import processing has occurred, other than :data:`sys.modules` cache look up. +This allows meta hooks to override :data:`sys.path` processing, frozen +modules, or even built-in modules. Meta hooks are registered by adding new +finder objects to :data:`sys.meta_path`, as described below. + +Import path hooks are called as part of :data:`sys.path` (or +``package.__path__``) processing, at the point where their associated path +item is encountered. Import path hooks are registered by adding new callables +to :data:`sys.path_hooks` as described below. + + +The meta path +------------- + +.. index:: + single: sys.meta_path + pair: finder; find_spec + +When the named module is not found in :data:`sys.modules`, Python next +searches :data:`sys.meta_path`, which contains a list of meta path finder +objects. These finders are queried in order to see if they know how to handle +the named module. Meta path finders must implement a method called +:meth:`~importlib.abc.MetaPathFinder.find_spec` which takes three arguments: +a name, an import path, and (optionally) a target module. The meta path +finder can use any strategy it wants to determine whether it can handle +the named module or not. + +If the meta path finder knows how to handle the named module, it returns a +spec object. If it cannot handle the named module, it returns ``None``. If +:data:`sys.meta_path` processing reaches the end of its list without returning +a spec, then a :exc:`ModuleNotFoundError` is raised. Any other exceptions +raised are simply propagated up, aborting the import process. + +The :meth:`~importlib.abc.MetaPathFinder.find_spec` method of meta path +finders is called with two or three arguments. The first is the fully +qualified name of the module being imported, for example ``foo.bar.baz``. +The second argument is the path entries to use for the module search. For +top-level modules, the second argument is ``None``, but for submodules or +subpackages, the second argument is the value of the parent package's +``__path__`` attribute. If the appropriate ``__path__`` attribute cannot +be accessed, a :exc:`ModuleNotFoundError` is raised. The third argument +is an existing module object that will be the target of loading later. +The import system passes in a target module only during reload. + +The meta path may be traversed multiple times for a single import request. +For example, assuming none of the modules involved has already been cached, +importing ``foo.bar.baz`` will first perform a top level import, calling +``mpf.find_spec("foo", None, None)`` on each meta path finder (``mpf``). After +``foo`` has been imported, ``foo.bar`` will be imported by traversing the +meta path a second time, calling +``mpf.find_spec("foo.bar", foo.__path__, None)``. Once ``foo.bar`` has been +imported, the final traversal will call +``mpf.find_spec("foo.bar.baz", foo.bar.__path__, None)``. + +Some meta path finders only support top level imports. These importers will +always return ``None`` when anything other than ``None`` is passed as the +second argument. + +Python's default :data:`sys.meta_path` has three meta path finders, one that +knows how to import built-in modules, one that knows how to import frozen +modules, and one that knows how to import modules from an :term:`import path` +(i.e. the :term:`path based finder`). + +.. versionchanged:: 3.4 + The :meth:`~importlib.abc.MetaPathFinder.find_spec` method of meta path + finders replaced :meth:`!find_module`, which + is now deprecated. While it will continue to work without change, the + import machinery will try it only if the finder does not implement + :meth:`~importlib.abc.MetaPathFinder.find_spec`. + +.. versionchanged:: 3.10 + Use of :meth:`!find_module` by the import system + now raises :exc:`ImportWarning`. + +.. versionchanged:: 3.12 + :meth:`!find_module` has been removed. + Use :meth:`~importlib.abc.MetaPathFinder.find_spec` instead. + + +Loading +======= + +If and when a module spec is found, the import machinery will use it (and +the loader it contains) when loading the module. Here is an approximation +of what happens during the loading portion of import:: + + module = None + if spec.loader is not None and hasattr(spec.loader, 'create_module'): + # It is assumed 'exec_module' will also be defined on the loader. + module = spec.loader.create_module(spec) + if module is None: + module = ModuleType(spec.name) + # The import-related module attributes get set here: + _init_module_attrs(spec, module) + + if spec.loader is None: + # unsupported + raise ImportError + + sys.modules[spec.name] = module + try: + spec.loader.exec_module(module) + except BaseException: + try: + del sys.modules[spec.name] + except KeyError: + pass + raise + return sys.modules[spec.name] + +Note the following details: + +* If there is an existing module object with the given name in + :data:`sys.modules`, import will have already returned it. + +* The module will exist in :data:`sys.modules` before the loader + executes the module code. This is crucial because the module code may + (directly or indirectly) import itself; adding it to :data:`sys.modules` + beforehand prevents unbounded recursion in the worst case and multiple + loading in the best. + +* If loading fails, the failing module -- and only the failing module -- + gets removed from :data:`sys.modules`. Any module already in the + :data:`sys.modules` cache, and any module that was successfully loaded + as a side-effect, must remain in the cache. This contrasts with + reloading where even the failing module is left in :data:`sys.modules`. + +* After the module is created but before execution, the import machinery + sets the import-related module attributes ("_init_module_attrs" in + the pseudo-code example above), as summarized in a + :ref:`later section <import-mod-attrs>`. + +* Module execution is the key moment of loading in which the module's + namespace gets populated. Execution is entirely delegated to the + loader, which gets to decide what gets populated and how. + +* The module created during loading and passed to exec_module() may + not be the one returned at the end of import [#fnlo]_. + +.. versionchanged:: 3.4 + The import system has taken over the boilerplate responsibilities of + loaders. These were previously performed by the + ``importlib.abc.Loader.load_module`` method. + +.. versionchanged:: 3.15 + The ``load_module`` method is no longer used. + +Loaders +------- + +Module loaders provide the critical function of loading: module execution. +The import machinery calls the :meth:`importlib.abc.Loader.exec_module` +method with a single argument, the module object to execute. Any value +returned from :meth:`~importlib.abc.Loader.exec_module` is ignored. + +Loaders must satisfy the following requirements: + +* If the module is a Python module (as opposed to a built-in module or a + dynamically loaded extension), the loader should execute the module's code + in the module's global name space (``module.__dict__``). + +* If the loader cannot execute the module, it should raise an + :exc:`ImportError`, although any other exception raised during + :meth:`~importlib.abc.Loader.exec_module` will be propagated. + +In many cases, the finder and loader can be the same object; in such cases the +:meth:`~importlib.abc.MetaPathFinder.find_spec` method would just return a +spec with the loader set to ``self``. + +Module loaders may opt in to creating the module object during loading +by implementing a :meth:`~importlib.abc.Loader.create_module` method. +It takes one argument, the module spec, and returns the new module object +to use during loading. ``create_module()`` does not need to set any attributes +on the module object. If the method returns ``None``, the +import machinery will create the new module itself. + +.. versionadded:: 3.4 + The :meth:`~importlib.abc.Loader.create_module` method of loaders. + +.. versionchanged:: 3.4 + The ``importlib.abc.Loader.load_module`` method was replaced by + :meth:`~importlib.abc.Loader.exec_module` and the import + machinery assumed all the boilerplate responsibilities of loading. + + For compatibility with existing loaders, the import machinery will use + the ``load_module()`` method of loaders if it exists and the loader does + not also implement ``exec_module()``. However, ``load_module()`` has been + deprecated and loaders should implement ``exec_module()`` instead. + + The ``load_module()`` method must implement all the boilerplate loading + functionality described above in addition to executing the module. All + the same constraints apply, with some additional clarification: + + * If there is an existing module object with the given name in + :data:`sys.modules`, the loader must use that existing module. + (Otherwise, :func:`importlib.reload` will not work correctly.) If the + named module does not exist in :data:`sys.modules`, the loader + must create a new module object and add it to :data:`sys.modules`. + + * The module *must* exist in :data:`sys.modules` before the loader + executes the module code, to prevent unbounded recursion or multiple + loading. + + * If loading fails, the loader must remove any modules it has inserted + into :data:`sys.modules`, but it must remove **only** the failing + module(s), and only if the loader itself has loaded the module(s) + explicitly. + +.. versionchanged:: 3.5 + A :exc:`DeprecationWarning` is raised when ``exec_module()`` is defined but + ``create_module()`` is not. + +.. versionchanged:: 3.6 + An :exc:`ImportError` is raised when ``exec_module()`` is defined but + ``create_module()`` is not. + +.. versionchanged:: 3.10 + Use of ``load_module()`` will raise :exc:`ImportWarning`. + +Submodules +---------- + +When a submodule is loaded using any mechanism (e.g. ``importlib`` APIs, the +``import`` or ``import-from`` statements, or built-in ``__import__()``) a +binding is placed in the parent module's namespace to the submodule object. +For example, if package ``spam`` has a submodule ``foo``, after importing +``spam.foo``, ``spam`` will have an attribute ``foo`` which is bound to the +submodule. Let's say you have the following directory structure:: + + spam/ + __init__.py + foo.py + +and ``spam/__init__.py`` has the following line in it:: + + from .foo import Foo + +then executing the following puts name bindings for ``foo`` and ``Foo`` in the +``spam`` module:: + + >>> import spam + >>> spam.foo + <module 'spam.foo' from '/tmp/imports/spam/foo.py'> + >>> spam.Foo + <class 'spam.foo.Foo'> + +Given Python's familiar name binding rules this might seem surprising, but +it's actually a fundamental feature of the import system. The invariant +holding is that if you have ``sys.modules['spam']`` and +``sys.modules['spam.foo']`` (as you would after the above import), the latter +must appear as the ``foo`` attribute of the former. + +.. _module-specs: + +Module specs +------------ + +The import machinery uses a variety of information about each module +during import, especially before loading. Most of the information is +common to all modules. The purpose of a module's spec is to encapsulate +this import-related information on a per-module basis. + +Using a spec during import allows state to be transferred between import +system components, e.g. between the finder that creates the module spec +and the loader that executes it. Most importantly, it allows the +import machinery to perform the boilerplate operations of loading, +whereas without a module spec the loader had that responsibility. + +The module's spec is exposed as :attr:`module.__spec__`. Setting +:attr:`!__spec__` appropriately applies equally to +:ref:`modules initialized during interpreter startup <programs>`. +The one exception is ``__main__``, where :attr:`!__spec__` is +:ref:`set to None in some cases <main_spec>`. + +See :class:`~importlib.machinery.ModuleSpec` for details on the contents of +the module spec. + +.. versionadded:: 3.4 + +.. _package-path-rules: + +__path__ attributes on modules +------------------------------ + +The :attr:`~module.__path__` attribute should be a (possibly empty) +:term:`sequence` of strings enumerating the locations where the package's +submodules will be found. By definition, if a module has a :attr:`!__path__` +attribute, it is a :term:`package`. + +A package's :attr:`~module.__path__` attribute is used during imports of its +subpackages. +Within the import machinery, it functions much the same as :data:`sys.path`, +i.e. providing a list of locations to search for modules during import. +However, :attr:`!__path__` is typically much more constrained than +:data:`!sys.path`. + +The same rules used for :data:`sys.path` also apply to a package's +:attr:`!__path__`. :data:`sys.path_hooks` (described below) are +consulted when traversing a package's :attr:`!__path__`. + +A package's ``__init__.py`` file may set or alter the package's +:attr:`~module.__path__` +attribute, and this was typically the way namespace packages were implemented +prior to :pep:`420`. With the adoption of :pep:`420`, namespace packages no +longer need to supply ``__init__.py`` files containing only :attr:`!__path__` +manipulation code; the import machinery automatically sets :attr:`!__path__` +correctly for the namespace package. + +Module reprs +------------ + +By default, all modules have a usable repr, however depending on the +attributes set above, and in the module's spec, you can more explicitly +control the repr of module objects. + +If the module has a spec (``__spec__``), the import machinery will try +to generate a repr from it. If that fails or there is no spec, the import +system will craft a default repr using whatever information is available +on the module. It will try to use the ``module.__name__``, +``module.__file__``, and ``module.__loader__`` as input into the repr, +with defaults for whatever information is missing. + +Here are the exact rules used: + +* If the module has a ``__spec__`` attribute, the information in the spec + is used to generate the repr. The "name", "loader", "origin", and + "has_location" attributes are consulted. + +* If the module has a ``__file__`` attribute, this is used as part of the + module's repr. + +* If the module has no ``__file__`` but does have a ``__loader__`` that is not + ``None``, then the loader's repr is used as part of the module's repr. + +* Otherwise, just use the module's ``__name__`` in the repr. + +.. versionchanged:: 3.12 + Use of :meth:`!module_repr`, having been deprecated since Python 3.4, was + removed in Python 3.12 and is no longer called during the resolution of a + module's repr. + +.. _pyc-invalidation: + +Cached bytecode invalidation +---------------------------- + +Before Python loads cached bytecode from a ``.pyc`` file, it checks whether the +cache is up-to-date with the source ``.py`` file. By default, Python does this +by storing the source's last-modified timestamp and size in the cache file when +writing it. At runtime, the import system then validates the cache file by +checking the stored metadata in the cache file against the source's +metadata. + +Python also supports "hash-based" cache files, which store a hash of the source +file's contents rather than its metadata. There are two variants of hash-based +``.pyc`` files: checked and unchecked. For checked hash-based ``.pyc`` files, +Python validates the cache file by hashing the source file and comparing the +resulting hash with the hash in the cache file. If a checked hash-based cache +file is found to be invalid, Python regenerates it and writes a new checked +hash-based cache file. For unchecked hash-based ``.pyc`` files, Python simply +assumes the cache file is valid if it exists. Hash-based ``.pyc`` files +validation behavior may be overridden with the :option:`--check-hash-based-pycs` +flag. + +.. versionchanged:: 3.7 + Added hash-based ``.pyc`` files. Previously, Python only supported + timestamp-based invalidation of bytecode caches. + + +The Path Based Finder +===================== + +.. index:: + single: path based finder + +As mentioned previously, Python comes with several default meta path finders. +One of these, called the :term:`path based finder` +(:class:`~importlib.machinery.PathFinder`), searches an :term:`import path`, +which contains a list of :term:`path entries <path entry>`. Each path +entry names a location to search for modules. + +The path based finder itself doesn't know how to import anything. Instead, it +traverses the individual path entries, associating each of them with a +path entry finder that knows how to handle that particular kind of path. + +The default set of path entry finders implement all the semantics for finding +modules on the file system, handling special file types such as Python source +code (``.py`` files), Python byte code (``.pyc`` files) and +shared libraries (e.g. ``.so`` files). When supported by the :mod:`zipimport` +module in the standard library, the default path entry finders also handle +loading all of these file types (other than shared libraries) from zipfiles. + +Within a single :term:`path entry`, the default path entry finders check for a +:term:`regular package` first, then for extension modules, then for source +files, and finally for bytecode files. For example, if the same directory +contains both ``spam/__init__.py`` and ``spam.py``, ``import spam`` will +import the package from ``spam/__init__.py``. A directory without an +``__init__.py`` file is treated as a :term:`namespace package` portion only if +no matching module is found. Note that this does not override the order of the +:term:`import path`. + +Path entries need not be limited to file system locations. They can refer to +URLs, database queries, or any other location that can be specified as a +string. + +The path based finder provides additional hooks and protocols so that you +can extend and customize the types of searchable path entries. For example, +if you wanted to support path entries as network URLs, you could write a hook +that implements HTTP semantics to find modules on the web. This hook (a +callable) would return a :term:`path entry finder` supporting the protocol +described below, which was then used to get a loader for the module from the +web. + +A word of warning: this section and the previous both use the term *finder*, +distinguishing between them by using the terms :term:`meta path finder` and +:term:`path entry finder`. These two types of finders are very similar, +support similar protocols, and function in similar ways during the import +process, but it's important to keep in mind that they are subtly different. +In particular, meta path finders operate at the beginning of the import +process, as keyed off the :data:`sys.meta_path` traversal. + +By contrast, path entry finders are in a sense an implementation detail +of the path based finder, and in fact, if the path based finder were to be +removed from :data:`sys.meta_path`, none of the path entry finder semantics +would be invoked. + + +Path entry finders +------------------ + +.. index:: + single: sys.path + single: sys.path_hooks + single: sys.path_importer_cache + single: PYTHONPATH + +The :term:`path based finder` is responsible for finding and loading +Python modules and packages whose location is specified with a string +:term:`path entry`. Most path entries name locations in the file system, +but they need not be limited to this. + +As a meta path finder, the :term:`path based finder` implements the +:meth:`~importlib.abc.MetaPathFinder.find_spec` protocol previously +described, however it exposes additional hooks that can be used to +customize how modules are found and loaded from the :term:`import path`. + +Three variables are used by the :term:`path based finder`, :data:`sys.path`, +:data:`sys.path_hooks` and :data:`sys.path_importer_cache`. The ``__path__`` +attributes on package objects are also used. These provide additional ways +that the import machinery can be customized. + +:data:`sys.path` contains a list of strings providing search locations for +modules and packages. It is initialized from the :envvar:`PYTHONPATH` +environment variable and various other installation- and +implementation-specific defaults. Entries in :data:`sys.path` can name +directories on the file system, zip files, and potentially other "locations" +(see the :mod:`site` module) that should be searched for modules, such as +URLs, or database queries. Only strings should be present on +:data:`sys.path`; all other data types are ignored. + +The :term:`path based finder` is a :term:`meta path finder`, so the import +machinery begins the :term:`import path` search by calling the path +based finder's :meth:`~importlib.machinery.PathFinder.find_spec` method as +described previously. When the ``path`` argument to +:meth:`~importlib.machinery.PathFinder.find_spec` is given, it will be a +list of string paths to traverse - typically a package's ``__path__`` +attribute for an import within that package. If the ``path`` argument is +``None``, this indicates a top level import and :data:`sys.path` is used. + +The path based finder iterates over every entry in the search path, and +for each of these, looks for an appropriate :term:`path entry finder` +(:class:`~importlib.abc.PathEntryFinder`) for the +path entry. Because this can be an expensive operation (e.g. there may be +``stat()`` call overheads for this search), the path based finder maintains +a cache mapping path entries to path entry finders. This cache is maintained +in :data:`sys.path_importer_cache` (despite the name, this cache actually +stores finder objects rather than being limited to :term:`importer` objects). +In this way, the expensive search for a particular :term:`path entry` +location's :term:`path entry finder` need only be done once. User code is +free to remove cache entries from :data:`sys.path_importer_cache` forcing +the path based finder to perform the path entry search again. + +If the path entry is not present in the cache, the path based finder iterates +over every callable in :data:`sys.path_hooks`. Each of the :term:`path entry +hooks <path entry hook>` in this list is called with a single argument, the +path entry to be searched. This callable may either return a :term:`path +entry finder` that can handle the path entry, or it may raise +:exc:`ImportError`. An :exc:`ImportError` is used by the path based finder to +signal that the hook cannot find a :term:`path entry finder` +for that :term:`path entry`. The +exception is ignored and :term:`import path` iteration continues. The hook +should expect either a string or bytes object; the encoding of bytes objects +is up to the hook (e.g. it may be a file system encoding, UTF-8, or something +else), and if the hook cannot decode the argument, it should raise +:exc:`ImportError`. + +If :data:`sys.path_hooks` iteration ends with no :term:`path entry finder` +being returned, then the path based finder's +:meth:`~importlib.machinery.PathFinder.find_spec` method will store ``None`` +in :data:`sys.path_importer_cache` (to indicate that there is no finder for +this path entry) and return ``None``, indicating that this +:term:`meta path finder` could not find the module. + +If a :term:`path entry finder` *is* returned by one of the :term:`path entry +hook` callables on :data:`sys.path_hooks`, then the following protocol is used +to ask the finder for a module spec, which is then used when loading the +module. + +The current working directory -- denoted by an empty string -- is handled +slightly differently from other entries on :data:`sys.path`. First, if the +current working directory cannot be determined or is found not to exist, no +value is stored in :data:`sys.path_importer_cache`. Second, the value for the +current working directory is looked up fresh for each module lookup. Third, +the path used for :data:`sys.path_importer_cache` and returned by +:meth:`importlib.machinery.PathFinder.find_spec` will be the actual current +working directory and not the empty string. + +Path entry finder protocol +-------------------------- + +In order to support imports of modules and initialized packages and also to +contribute portions to namespace packages, path entry finders must implement +the :meth:`~importlib.abc.PathEntryFinder.find_spec` method. + +:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two arguments: the +fully qualified name of the module being imported, and the (optional) target +module. ``find_spec()`` returns a fully populated spec for the module. +This spec will always have "loader" set (with one exception). + +To indicate to the import machinery that the spec represents a namespace +:term:`portion`, the path entry finder sets ``submodule_search_locations`` to +a list containing the portion. + +.. versionchanged:: 3.4 + :meth:`~importlib.abc.PathEntryFinder.find_spec` replaced + :meth:`!find_loader` and + :meth:`!find_module`, both of which + are now deprecated, but will be used if ``find_spec()`` is not defined. + + Older path entry finders may implement one of these two deprecated methods + instead of ``find_spec()``. The methods are still respected for the + sake of backward compatibility. However, if ``find_spec()`` is + implemented on the path entry finder, the legacy methods are ignored. + + :meth:`!find_loader` takes one argument, the + fully qualified name of the module being imported. ``find_loader()`` + returns a 2-tuple where the first item is the loader and the second item + is a namespace :term:`portion`. + + For backwards compatibility with other implementations of the import + protocol, many path entry finders also support the same, + traditional ``find_module()`` method that meta path finders support. + However path entry finder ``find_module()`` methods are never called + with a ``path`` argument (they are expected to record the appropriate + path information from the initial call to the path hook). + + The ``find_module()`` method on path entry finders is deprecated, + as it does not allow the path entry finder to contribute portions to + namespace packages. If both ``find_loader()`` and ``find_module()`` + exist on a path entry finder, the import system will always call + ``find_loader()`` in preference to ``find_module()``. + +.. versionchanged:: 3.10 + Calls to :meth:`!find_module` and + :meth:`!find_loader` by the import + system will raise :exc:`ImportWarning`. + +.. versionchanged:: 3.12 + ``find_module()`` and ``find_loader()`` have been removed. + + +Replacing the standard import system +==================================== + +The most reliable mechanism for replacing the entire import system is to +delete the default contents of :data:`sys.meta_path`, replacing them +entirely with a custom meta path hook. + +If it is acceptable to only alter the behaviour of import statements +without affecting other APIs that access the import system, then replacing +the builtin :func:`__import__` function may be sufficient. + +To selectively prevent the import of some modules from a hook early on the +meta path (rather than disabling the standard import system entirely), +it is sufficient to raise :exc:`ModuleNotFoundError` directly from +:meth:`~importlib.abc.MetaPathFinder.find_spec` instead of returning +``None``. The latter indicates that the meta path search should continue, +while raising an exception terminates it immediately. + +.. _relativeimports: + +Package Relative Imports +======================== + +Relative imports use leading dots. A single leading dot indicates a relative +import, starting with the current package. Two or more leading dots indicate a +relative import to the parent(s) of the current package, one level per dot +after the first. For example, given the following package layout:: + + package/ + __init__.py + subpackage1/ + __init__.py + moduleX.py + moduleY.py + subpackage2/ + __init__.py + moduleZ.py + moduleA.py + +In either ``subpackage1/moduleX.py`` or ``subpackage1/__init__.py``, +the following are valid relative imports:: + + from .moduleY import spam + from .moduleY import spam as ham + from . import moduleY + from ..subpackage1 import moduleY + from ..subpackage2.moduleZ import eggs + from ..moduleA import foo + +Absolute imports may use either the ``import <>`` or ``from <> import <>`` +syntax, but relative imports may only use the second form; the reason +for this is that:: + + import XXX.YYY.ZZZ + +should expose ``XXX.YYY.ZZZ`` as a usable expression, but .moduleY is +not a valid expression. + + +.. _import-dunder-main: + +Special considerations for __main__ +=================================== + +The :mod:`__main__` module is a special case relative to Python's import +system. As noted :ref:`elsewhere <programs>`, the ``__main__`` module +is directly initialized at interpreter startup, much like :mod:`sys` and +:mod:`builtins`. However, unlike those two, it doesn't strictly +qualify as a built-in module. This is because the manner in which +``__main__`` is initialized depends on the flags and other options with +which the interpreter is invoked. + +.. _main_spec: + +__main__.__spec__ +----------------- + +Depending on how :mod:`__main__` is initialized, ``__main__.__spec__`` +gets set appropriately or to ``None``. + +When Python is started with the :option:`-m` option, ``__spec__`` is set +to the module spec of the corresponding module or package. ``__spec__`` is +also populated when the ``__main__`` module is loaded as part of executing a +directory, zipfile or other :data:`sys.path` entry. + +In :ref:`the remaining cases <using-on-interface-options>` +``__main__.__spec__`` is set to ``None``, as the code used to populate the +:mod:`__main__` does not correspond directly with an importable module: + +- interactive prompt +- :option:`-c` option +- running from stdin +- running directly from a source or bytecode file + +Note that ``__main__.__spec__`` is always ``None`` in the last case, +*even if* the file could technically be imported directly as a module +instead. Use the :option:`-m` switch if valid module metadata is desired +in :mod:`__main__`. + +Note also that even when ``__main__`` corresponds with an importable module +and ``__main__.__spec__`` is set accordingly, they're still considered +*distinct* modules. This is due to the fact that blocks guarded by +``if __name__ == "__main__":`` checks only execute when the module is used +to populate the ``__main__`` namespace, and not during normal import. + + +References +========== + +The import machinery has evolved considerably since Python's early days. The +original `specification for packages +<https://www.python.org/doc/essays/packages/>`_ is still available to read, +although some details have changed since the writing of that document. + +The original specification for :data:`sys.meta_path` was :pep:`302`, with +subsequent extension in :pep:`420`. + +:pep:`420` introduced :term:`namespace packages <namespace package>` for +Python 3.3. :pep:`420` also introduced the :meth:`!find_loader` protocol as an +alternative to :meth:`!find_module`. + +:pep:`366` describes the addition of the ``__package__`` attribute for +explicit relative imports in main modules. + +:pep:`328` introduced absolute and explicit relative imports and initially +proposed ``__name__`` for semantics :pep:`366` would eventually specify for +``__package__``. + +:pep:`338` defines executing modules as scripts. + +:pep:`451` adds the encapsulation of per-module import state in spec +objects. It also off-loads most of the boilerplate responsibilities of +loaders back onto the import machinery. These changes allow the +deprecation of several APIs in the import system and also addition of new +methods to finders and loaders. + +.. rubric:: Footnotes + +.. [#fnmo] See :class:`types.ModuleType`. + +.. [#fnlo] The importlib implementation avoids using the return value + directly. Instead, it gets the module object by looking the module name up + in :data:`sys.modules`. The indirect effect of this is that an imported + module may replace itself in :data:`sys.modules`. This is + implementation-specific behavior that is not guaranteed to work in other + Python implementations. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/index.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/index.rst new file mode 100644 index 00000000..a66673b1 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/index.rst @@ -0,0 +1,29 @@ +.. _reference-index: + +################################# + The Python Language Reference +################################# + +This reference manual describes the syntax and "core semantics" of the +language. It is terse, but attempts to be exact and complete. The semantics of +non-essential built-in object types and of the built-in functions and modules +are described in :ref:`library-index`. For an informal introduction to the +language, see :ref:`tutorial-index`. For C or C++ programmers, two additional +manuals exist: :ref:`extending-index` describes the high-level picture of how to +write a Python extension module, and the :ref:`c-api-index` describes the +interfaces available to C/C++ programmers in detail. + +.. toctree:: + :maxdepth: 2 + :numbered: + + introduction.rst + lexical_analysis.rst + datamodel.rst + executionmodel.rst + import.rst + expressions.rst + simple_stmts.rst + compound_stmts.rst + toplevel_components.rst + grammar.rst diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/introduction.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/introduction.rst new file mode 100644 index 00000000..c62240b1 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/introduction.rst @@ -0,0 +1,219 @@ + +.. _introduction: + +************ +Introduction +************ + +This reference manual describes the Python programming language. It is not +intended as a tutorial. + +While I am trying to be as precise as possible, I chose to use English rather +than formal specifications for everything except syntax and lexical analysis. +This should make the document more understandable to the average reader, but +will leave room for ambiguities. Consequently, if you were coming from Mars and +tried to re-implement Python from this document alone, you might have to guess +things and in fact you would probably end up implementing quite a different +language. On the other hand, if you are using Python and wonder what the precise +rules about a particular area of the language are, you should definitely be able +to find them here. If you would like to see a more formal definition of the +language, maybe you could volunteer your time --- or invent a cloning machine +:-). + +It is dangerous to add too many implementation details to a language reference +document --- the implementation may change, and other implementations of the +same language may work differently. On the other hand, CPython is the one +Python implementation in widespread use (although alternate implementations +continue to gain support), and its particular quirks are sometimes worth being +mentioned, especially where the implementation imposes additional limitations. +Therefore, you'll find short "implementation notes" sprinkled throughout the +text. + +Every Python implementation comes with a number of built-in and standard +modules. These are documented in :ref:`library-index`. A few built-in modules +are mentioned when they interact in a significant way with the language +definition. + + +.. _implementations: + +Alternate Implementations +========================= + +Though there is one Python implementation which is by far the most popular, +there are some alternate implementations which are of particular interest to +different audiences. + +Known implementations include: + +CPython + This is the original and most-maintained implementation of Python, written in C. + New language features generally appear here first. + +Jython + Python implemented in Java. This implementation can be used as a scripting + language for Java applications, or can be used to create applications using the + Java class libraries. It is also often used to create tests for Java libraries. + More information can be found at `the Jython website <https://www.jython.org/>`_. + +Python for .NET + This implementation actually uses the CPython implementation, but is a managed + .NET application and makes .NET libraries available. It was created by Brian + Lloyd. For more information, see the `Python for .NET home page + <https://pythonnet.github.io/>`_. + +IronPython + An alternate Python for .NET. Unlike Python.NET, this is a complete Python + implementation that generates IL, and compiles Python code directly to .NET + assemblies. It was created by Jim Hugunin, the original creator of Jython. For + more information, see `the IronPython website <https://ironpython.net/>`_. + +PyPy + An implementation of Python written completely in Python. It supports several + advanced features not found in other implementations like stackless support + and a Just in Time compiler. One of the goals of the project is to encourage + experimentation with the language itself by making it easier to modify the + interpreter (since it is written in Python). Additional information is + available on `the PyPy project's home page <https://pypy.org/>`_. + +Each of these implementations varies in some way from the language as documented +in this manual, or introduces specific information beyond what's covered in the +standard Python documentation. Please refer to the implementation-specific +documentation to determine what else you need to know about the specific +implementation you're using. + + +.. _notation: + +Notation +======== + +.. index:: BNF, grammar, syntax, notation + +The descriptions of lexical analysis and syntax use a grammar notation that +is a mixture of +`EBNF <https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form>`_ +and `PEG <https://en.wikipedia.org/wiki/Parsing_expression_grammar>`_. +For example: + +.. grammar-snippet:: + :group: notation + + name: `letter` (`letter` | `digit` | "_")* + letter: "a"..."z" | "A"..."Z" + digit: "0"..."9" + +In this example, the first line says that a ``name`` is a ``letter`` followed +by a sequence of zero or more ``letter``\ s, ``digit``\ s, and underscores. +A ``letter`` in turn is any of the single characters ``'a'`` through +``'z'`` and ``A`` through ``Z``; a ``digit`` is a single character from ``0`` +to ``9``. + +Each rule begins with a name (which identifies the rule that's being defined) +followed by a colon, ``:``. +The definition to the right of the colon uses the following syntax elements: + +* ``name``: A name refers to another rule. + Where possible, it is a link to the rule's definition. + + * ``TOKEN``: An uppercase name refers to a :term:`token`. + For the purposes of grammar definitions, tokens are the same as rules. + +* ``"text"``, ``'text'``: Text in single or double quotes must match literally + (without the quotes). The type of quote is chosen according to the meaning + of ``text``: + + * ``'if'``: A name in single quotes denotes a :ref:`keyword <keywords>`. + * ``"case"``: A name in double quotes denotes a + :ref:`soft-keyword <soft-keywords>`. + * ``'@'``: A non-letter symbol in single quotes denotes an + :py:data:`~token.OP` token, that is, a :ref:`delimiter <delimiters>` or + :ref:`operator <operators>`. + +* ``e1 e2``: Items separated only by whitespace denote a sequence. + Here, ``e1`` must be followed by ``e2``. +* ``e1 | e2``: A vertical bar is used to separate alternatives. + It denotes PEG's "ordered choice": if ``e1`` matches, ``e2`` is + not considered. + In traditional PEG grammars, this is written as a slash, ``/``, rather than + a vertical bar. + See :pep:`617` for more background and details. +* ``e*``: A star means zero or more repetitions of the preceding item. +* ``e+``: Likewise, a plus means one or more repetitions. +* ``[e]``: A phrase enclosed in square brackets means zero or + one occurrences. In other words, the enclosed phrase is optional. +* ``e?``: A question mark has exactly the same meaning as square brackets: + the preceding item is optional. +* ``(e)``: Parentheses are used for grouping. + +The following notation is only used in +:ref:`lexical definitions <notation-lexical-vs-syntactic>`. + +* ``"a"..."z"``: Two literal characters separated by three dots mean a choice + of any single character in the given (inclusive) range of ASCII characters. +* ``<...>``: A phrase between angular brackets gives an informal description + of the matched symbol (for example, ``<any ASCII character except "\">``), + or an abbreviation that is defined in nearby text (for example, ``<Lu>``). + +.. _lexical-lookaheads: + +Some definitions also use *lookaheads*, which indicate that an element +must (or must not) match at a given position, but without consuming any input: + +* ``&e``: a positive lookahead (that is, ``e`` is required to match) +* ``!e``: a negative lookahead (that is, ``e`` is required *not* to match) + +The unary operators (``*``, ``+``, ``?``) bind as tightly as possible; +the vertical bar (``|``) binds most loosely. + +White space is only meaningful to separate tokens. + +Rules are normally contained on a single line, but rules that are too long +may be wrapped: + +.. grammar-snippet:: + :group: notation + + literal: stringliteral | bytesliteral + | integer | floatnumber | imagnumber + +Alternatively, rules may be formatted with the first line ending at the colon, +and each alternative beginning with a vertical bar on a new line. +For example: + + +.. grammar-snippet:: + :group: notation-alt + + literal: + | stringliteral + | bytesliteral + | integer + | floatnumber + | imagnumber + +This does *not* mean that there is an empty first alternative. + +.. index:: lexical definitions + +.. _notation-lexical-vs-syntactic: + +Lexical and Syntactic definitions +--------------------------------- + +There is some difference between *lexical* and *syntactic* analysis: +the :term:`lexical analyzer` operates on the individual characters of the +input source, while the *parser* (syntactic analyzer) operates on the stream +of :term:`tokens <token>` generated by the lexical analysis. +However, in some cases the exact boundary between the two phases is a +CPython implementation detail. + +The practical difference between the two is that in *lexical* definitions, +all whitespace is significant. +The lexical analyzer :ref:`discards <whitespace>` all whitespace that is not +converted to tokens like :data:`token.INDENT` or :data:`~token.NEWLINE`. +*Syntactic* definitions then use these tokens, rather than source characters. + +This documentation uses the same BNF grammar for both styles of definitions. +All uses of BNF in the next chapter (:ref:`lexical`) are lexical definitions; +uses in subsequent chapters are syntactic definitions. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/lexical_analysis.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/lexical_analysis.rst new file mode 100644 index 00000000..f3ed1539 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/lexical_analysis.rst @@ -0,0 +1,1590 @@ + +.. _lexical: + +**************** +Lexical analysis +**************** + +.. index:: lexical analysis, parser, token + +A Python program is read by a *parser*. Input to the parser is a stream of +:term:`tokens <token>`, generated by the *lexical analyzer* (also known as +the *tokenizer*). +This chapter describes how the lexical analyzer produces these tokens. + +The lexical analyzer determines the program text's :ref:`encoding <encodings>` +(UTF-8 by default), and decodes the text into +:ref:`source characters <lexical-source-character>`. +If the text cannot be decoded, a :exc:`SyntaxError` is raised. + +Next, the lexical analyzer uses the source characters to generate a stream of tokens. +The type of a generated token generally depends on the next source character to +be processed. Similarly, other special behavior of the analyzer depends on +the first source character that hasn't yet been processed. +The following table gives a quick summary of these source characters, +with links to sections that contain more information. + +.. list-table:: + :header-rows: 1 + + * - Character + - Next token (or other relevant documentation) + + * - * space + * tab + * formfeed + - * :ref:`Whitespace <whitespace>` + + * - * CR, LF + - * :ref:`New line <line-structure>` + * :ref:`Indentation <indentation>` + + * - * backslash (``\``) + - * :ref:`Explicit line joining <explicit-joining>` + * (Also significant in :ref:`string escape sequences <escape-sequences>`) + + * - * hash (``#``) + - * :ref:`Comment <comments>` + + * - * quote (``'``, ``"``) + - * :ref:`String literal <strings>` + + * - * ASCII letter (``a``-``z``, ``A``-``Z``) + * non-ASCII character + - * :ref:`Name <identifiers>` + * Prefixed :ref:`string or bytes literal <strings>` + + * - * underscore (``_``) + - * :ref:`Name <identifiers>` + * (Can also be part of :ref:`numeric literals <numbers>`) + + * - * number (``0``-``9``) + - * :ref:`Numeric literal <numbers>` + + * - * dot (``.``) + - * :ref:`Numeric literal <numbers>` + * :ref:`Operator <operators>` + + * - * question mark (``?``) + * dollar (``$``) + * + .. (the following uses zero-width space characters to render + .. a literal backquote) + + backquote (``​`​``) + * control character + - * Error (outside string literals and comments) + + * - * other printing character + - * :ref:`Operator or delimiter <operators>` + + * - * end of file + - * :ref:`End marker <endmarker-token>` + + +.. _line-structure: + +Line structure +============== + +.. index:: line structure + +A Python program is divided into a number of *logical lines*. + + +.. _logical-lines: + +Logical lines +------------- + +.. index:: logical line, physical line, line joining, NEWLINE token + +The end of a logical line is represented by the token :data:`~token.NEWLINE`. +Statements cannot cross logical line boundaries except where :data:`!NEWLINE` +is allowed by the syntax (e.g., between statements in compound statements). +A logical line is constructed from one or more *physical lines* by following +the :ref:`explicit <explicit-joining>` or :ref:`implicit <implicit-joining>` +*line joining* rules. + + +.. _physical-lines: + +Physical lines +-------------- + +A physical line is a sequence of characters terminated by one the following +end-of-line sequences: + +* the Unix form using ASCII LF (linefeed), +* the Windows form using the ASCII sequence CR LF (return followed by linefeed), +* the '`Classic Mac OS`__' form using the ASCII CR (return) character. + + __ https://en.wikipedia.org/wiki/Classic_Mac_OS + +Regardless of platform, each of these sequences is replaced by a single +ASCII LF (linefeed) character. +(This is done even inside :ref:`string literals <strings>`.) +Each line can use any of the sequences; they do not need to be consistent +within a file. + +The end of input also serves as an implicit terminator for the final +physical line. + +Formally: + +.. grammar-snippet:: + :group: python-grammar + + newline: <ASCII LF> | <ASCII CR> <ASCII LF> | <ASCII CR> + + +.. _comments: + +Comments +-------- + +.. index:: comment, hash character + single: # (hash); comment + +A comment starts with a hash character (``#``) that is not part of a string +literal, and ends at the end of the physical line. A comment signifies the end +of the logical line unless the implicit line joining rules are invoked. Comments +are ignored by the syntax. + + +.. _encodings: + +Encoding declarations +--------------------- + +.. index:: source character set, encoding declarations (source file) + single: # (hash); source encoding declaration + +If a comment in the first or second line of the Python script matches the +regular expression ``coding[=:]\s*([-\w.]+)``, this comment is processed as an +encoding declaration; the first group of this expression names the encoding of +the source code file. The encoding declaration must appear on a line of its +own. If it is the second line, the first line must also be a comment-only line. +The recommended forms of an encoding expression are :: + + # -*- coding: <encoding-name> -*- + +which is recognized also by GNU Emacs, and :: + + # vim:fileencoding=<encoding-name> + +which is recognized by Bram Moolenaar's VIM. + +If no encoding declaration is found, the default encoding is UTF-8. If the +implicit or explicit encoding of a file is UTF-8, an initial UTF-8 byte-order +mark (``b'\xef\xbb\xbf'``) is ignored rather than being a syntax error. + +If an encoding is declared, the encoding name must be recognized by Python +(see :ref:`standard-encodings`). The +encoding is used for all lexical analysis, including string literals, comments +and identifiers. + +.. _lexical-source-character: + +All lexical analysis, including string literals, comments +and identifiers, works on Unicode text decoded using the source encoding. +Any Unicode code point, except the NUL control character, can appear in +Python source. + +.. grammar-snippet:: + :group: python-grammar + + source_character: <any Unicode code point, except NUL> + + +.. _explicit-joining: + +Explicit line joining +--------------------- + +.. index:: physical line, line joining, line continuation, backslash character + +Two or more physical lines may be joined into logical lines using backslash +characters (``\``), as follows: when a physical line ends in a backslash that is +not part of a string literal or comment, it is joined with the following forming +a single logical line, deleting the backslash and the following end-of-line +character. For example:: + + if 1900 < year < 2100 and 1 <= month <= 12 \ + and 1 <= day <= 31 and 0 <= hour < 24 \ + and 0 <= minute < 60 and 0 <= second < 60: # Looks like a valid date + return 1 + +A line ending in a backslash cannot carry a comment. A backslash does not +continue a comment. A backslash does not continue a token except for string +literals (i.e., tokens other than string literals cannot be split across +physical lines using a backslash). A backslash is illegal elsewhere on a line +outside a string literal. + + +.. _implicit-joining: + +Implicit line joining +--------------------- + +Expressions in parentheses, square brackets or curly braces can be split over +more than one physical line without using backslashes. For example:: + + month_names = ['Januari', 'Februari', 'Maart', # These are the + 'April', 'Mei', 'Juni', # Dutch names + 'Juli', 'Augustus', 'September', # for the months + 'Oktober', 'November', 'December'] # of the year + +Implicitly continued lines can carry comments. The indentation of the +continuation lines is not important. Blank continuation lines are allowed. +There is no NEWLINE token between implicit continuation lines. Implicitly +continued lines can also occur within triple-quoted strings (see below); in that +case they cannot carry comments. + + +.. _blank-lines: + +Blank lines +----------- + +.. index:: single: blank line + +A logical line that contains only spaces, tabs, formfeeds and possibly a +comment, is ignored (i.e., no :data:`~token.NEWLINE` token is generated). +During interactive input of statements, handling of a blank line may differ +depending on the implementation of the read-eval-print loop. +In the standard interactive interpreter, an entirely blank logical line (that +is, one containing not even whitespace or a comment) terminates a multi-line +statement. + + +.. _indentation: + +Indentation +----------- + +.. index:: indentation, leading whitespace, space, tab, grouping, statement grouping + +Leading whitespace (spaces and tabs) at the beginning of a logical line is used +to compute the indentation level of the line, which in turn is used to determine +the grouping of statements. + +Tabs are replaced (from left to right) by one to eight spaces such that the +total number of characters up to and including the replacement is a multiple of +eight (this is intended to be the same rule as used by Unix). The total number +of spaces preceding the first non-blank character then determines the line's +indentation. Indentation cannot be split over multiple physical lines using +backslashes; the whitespace up to the first backslash determines the +indentation. + +Indentation is rejected as inconsistent if a source file mixes tabs and spaces +in a way that makes the meaning dependent on the worth of a tab in spaces; a +:exc:`TabError` is raised in that case. + +**Cross-platform compatibility note:** because of the nature of text editors on +non-UNIX platforms, it is unwise to use a mixture of spaces and tabs for the +indentation in a single source file. It should also be noted that different +platforms may explicitly limit the maximum indentation level. + +A formfeed character may be present at the start of the line; it will be ignored +for the indentation calculations above. Formfeed characters occurring elsewhere +in the leading whitespace have an undefined effect (for instance, they may reset +the space count to zero). + +.. index:: INDENT token, DEDENT token + +The indentation levels of consecutive lines are used to generate +:data:`~token.INDENT` and :data:`~token.DEDENT` tokens, using a stack, +as follows. + +Before the first line of the file is read, a single zero is pushed on the stack; +this will never be popped off again. The numbers pushed on the stack will +always be strictly increasing from bottom to top. At the beginning of each +logical line, the line's indentation level is compared to the top of the stack. +If it is equal, nothing happens. If it is larger, it is pushed on the stack, and +one :data:`!INDENT` token is generated. If it is smaller, it *must* be one of the +numbers occurring on the stack; all numbers on the stack that are larger are +popped off, and for each number popped off a :data:`!DEDENT` token is generated. +At the end of the file, a :data:`!DEDENT` token is generated for each number +remaining on the stack that is larger than zero. + +Here is an example of a correctly (though confusingly) indented piece of Python +code:: + + def perm(l): + # Compute the list of all permutations of l + if len(l) <= 1: + return [l] + r = [] + for i in range(len(l)): + s = l[:i] + l[i+1:] + p = perm(s) + for x in p: + r.append(l[i:i+1] + x) + return r + +The following example shows various indentation errors:: + + def perm(l): # error: first line indented + for i in range(len(l)): # error: not indented + s = l[:i] + l[i+1:] + p = perm(l[:i] + l[i+1:]) # error: unexpected indent + for x in p: + r.append(l[i:i+1] + x) + return r # error: inconsistent dedent + +(Actually, the first three errors are detected by the parser; only the last +error is found by the lexical analyzer --- the indentation of ``return r`` does +not match a level popped off the stack.) + + +.. _whitespace: + +Whitespace between tokens +------------------------- + +Except at the beginning of a logical line or in string literals, the whitespace +characters space, tab and formfeed can be used interchangeably to separate +tokens: + +.. grammar-snippet:: + :group: python-grammar + + whitespace: ' ' | tab | formfeed + + +Whitespace is needed between two tokens only if their concatenation +could otherwise be interpreted as a different token. For example, ``ab`` is one +token, but ``a b`` is two tokens. However, ``+a`` and ``+ a`` both produce +two tokens, ``+`` and ``a``, as ``+a`` is not a valid token. + + +.. _endmarker-token: + +End marker +---------- + +At the end of non-interactive input, the lexical analyzer generates an +:data:`~token.ENDMARKER` token. + + +.. _other-tokens: + +Other tokens +============ + +Besides :data:`~token.NEWLINE`, :data:`~token.INDENT` and :data:`~token.DEDENT`, +the following categories of tokens exist: +*identifiers* and *keywords* (:data:`~token.NAME`), *literals* (such as +:data:`~token.NUMBER` and :data:`~token.STRING`), and other symbols +(*operators* and *delimiters*, :data:`~token.OP`). +Whitespace characters (other than logical line terminators, discussed earlier) +are not tokens, but serve to delimit tokens. +Where ambiguity exists, a token comprises the longest possible string that +forms a legal token, when read from left to right. + + +.. _identifiers: + +Names (identifiers and keywords) +================================ + +.. index:: identifier, name + +:data:`~token.NAME` tokens represent *identifiers*, *keywords*, and +*soft keywords*. + +Names are composed of the following characters: + +* uppercase and lowercase letters (``A-Z`` and ``a-z``), +* the underscore (``_``), +* digits (``0`` through ``9``), which cannot appear as the first character, and +* non-ASCII characters. Valid names may only contain "letter-like" and + "digit-like" characters; see :ref:`lexical-names-nonascii` for details. + +Names must contain at least one character, but have no upper length limit. +Case is significant. + +Formally, names are described by the following lexical definitions: + +.. grammar-snippet:: + :group: python-grammar + + NAME: `name_start` `name_continue`* + name_start: "a"..."z" | "A"..."Z" | "_" | <non-ASCII character> + name_continue: name_start | "0"..."9" + identifier: <`NAME`, except keywords> + +Note that not all names matched by this grammar are valid; see +:ref:`lexical-names-nonascii` for details. + + +.. _keywords: + +Keywords +-------- + +.. index:: + single: keyword + single: reserved word + +The following names are used as reserved words, or *keywords* of the +language, and cannot be used as ordinary identifiers. They must be spelled +exactly as written here: + +.. sourcecode:: text + + False await else import pass + None break except in raise + True class finally is return + and continue for lambda try + as def from nonlocal while + assert del global not with + async elif if or yield + + +.. _soft-keywords: + +Soft Keywords +------------- + +.. index:: soft keyword, keyword + +.. versionadded:: 3.10 + +Some names are only reserved under specific contexts. These are known as +*soft keywords*: + +- ``match``, ``case``, and ``_``, when used in the :keyword:`match` statement. +- ``type``, when used in the :keyword:`type` statement. +- ``lazy``, when used before an :keyword:`import` statement. + +These syntactically act as keywords in their specific contexts, +but this distinction is done at the parser level, not when tokenizing. + +As soft keywords, their use in the grammar is possible while still +preserving compatibility with existing code that uses these names as +identifier names. + +.. versionchanged:: 3.12 + ``type`` is now a soft keyword. + +.. versionchanged:: 3.15 + ``lazy`` is now a soft keyword. + +.. index:: + single: _, identifiers + single: __, identifiers +.. _id-classes: + +Reserved classes of identifiers +------------------------------- + +Certain classes of identifiers (besides keywords) have special meanings. These +classes are identified by the patterns of leading and trailing underscore +characters: + +``_*`` + Not imported by ``from module import *``. + +``_`` + In a ``case`` pattern within a :keyword:`match` statement, ``_`` is a + :ref:`soft keyword <soft-keywords>` that denotes a + :ref:`wildcard <wildcard-patterns>`. + + Separately, the interactive interpreter makes the result of the last evaluation + available in the variable ``_``. + (It is stored in the :mod:`builtins` module, alongside built-in + functions like ``print``.) + + Elsewhere, ``_`` is a regular identifier. It is often used to name + "special" items, but it is not special to Python itself. + + .. note:: + + The name ``_`` is often used in conjunction with internationalization; + refer to the documentation for the :mod:`gettext` module for more + information on this convention. + + It is also commonly used for unused variables. + +``__*__`` + System-defined names, informally known as "dunder" names. These names are + defined by the interpreter and its implementation (including the standard library). + Current system names are discussed in the :ref:`specialnames` section and elsewhere. + More will likely be defined in future versions of Python. *Any* use of ``__*__`` names, + in any context, that does not follow explicitly documented use, is subject to + breakage without warning. + +``__*`` + Class-private names. Names in this category, when used within the context of a + class definition, are re-written to use a mangled form to help avoid name + clashes between "private" attributes of base and derived classes. See section + :ref:`atom-identifiers`. + + +.. _lexical-names-nonascii: + +Non-ASCII characters in names +----------------------------- + +Names that contain non-ASCII characters need additional normalization +and validation beyond the rules and grammar explained +:ref:`above <identifiers>`. +For example, ``ř_1``, ``蛇``, or ``साँप`` are valid names, but ``r〰2``, +``€``, or ``🐍`` are not. + +This section explains the exact rules. + +All names are converted into the `normalization form`_ NFKC while parsing. +This means that, for example, some typographic variants of characters are +converted to their "basic" form. For example, ``fiⁿₐˡᵢᶻₐᵗᵢᵒₙ`` normalizes to +``finalization``, so Python treats them as the same name:: + + >>> fiⁿₐˡᵢᶻₐᵗᵢᵒₙ = 3 + >>> finalization + 3 + +.. note:: + + Normalization is done at the lexical level only. + Run-time functions that take names as *strings* generally do not normalize + their arguments. + For example, the variable defined above is accessible at run time in the + :func:`globals` dictionary as ``globals()["finalization"]`` but not + ``globals()["fiⁿₐˡᵢᶻₐᵗᵢᵒₙ"]``. + +Similarly to how ASCII-only names must contain only letters, digits and +the underscore, and cannot start with a digit, a valid name must +start with a character in the "letter-like" set ``xid_start``, +and the remaining characters must be in the "letter- and digit-like" set +``xid_continue``. + +These sets are based on the *XID_Start* and *XID_Continue* sets as defined by the +Unicode standard annex `UAX-31`_. +Python's ``xid_start`` additionally includes the underscore (``_``). +Note that Python does not necessarily conform to `UAX-31`_. + +A non-normative listing of characters in the *XID_Start* and *XID_Continue* +sets as defined by Unicode is available in the `DerivedCoreProperties.txt`_ +file in the Unicode Character Database. +For reference, the construction rules for the ``xid_*`` sets are given below. + +The set ``id_start`` is defined as the union of: + +* Unicode category ``<Lu>`` - uppercase letters (includes ``A`` to ``Z``) +* Unicode category ``<Ll>`` - lowercase letters (includes ``a`` to ``z``) +* Unicode category ``<Lt>`` - titlecase letters +* Unicode category ``<Lm>`` - modifier letters +* Unicode category ``<Lo>`` - other letters +* Unicode category ``<Nl>`` - letter numbers +* {``"_"``} - the underscore +* ``<Other_ID_Start>`` - an explicit set of characters in `PropList.txt`_ + to support backwards compatibility + +The set ``xid_start`` then closes this set under NFKC normalization, by +removing all characters whose normalization is not of the form +``id_start id_continue*``. + +The set ``id_continue`` is defined as the union of: + +* ``id_start`` (see above) +* Unicode category ``<Nd>`` - decimal numbers (includes ``0`` to ``9``) +* Unicode category ``<Pc>`` - connector punctuations +* Unicode category ``<Mn>`` - nonspacing marks +* Unicode category ``<Mc>`` - spacing combining marks +* ``<Other_ID_Continue>`` - another explicit set of characters in + `PropList.txt`_ to support backwards compatibility + +Again, ``xid_continue`` closes this set under NFKC normalization. + +Unicode categories use the version of the Unicode Character Database as +included in the :mod:`unicodedata` module. + +.. _UAX-31: https://www.unicode.org/reports/tr31/ +.. _PropList.txt: https://www.unicode.org/Public/17.0.0/ucd/PropList.txt +.. _DerivedCoreProperties.txt: https://www.unicode.org/Public/17.0.0/ucd/DerivedCoreProperties.txt +.. _normalization form: https://www.unicode.org/reports/tr15/#Norm_Forms + +.. seealso:: + + * :pep:`3131` -- Supporting Non-ASCII Identifiers + * :pep:`672` -- Unicode-related Security Considerations for Python + + +.. _literals: + +Literals +======== + +.. index:: literal, constant + +Literals are notations for constant values of some built-in types. + +In terms of lexical analysis, Python has :ref:`string, bytes <strings>` +and :ref:`numeric <numbers>` literals. + +Other "literals" are lexically denoted using :ref:`keywords <keywords>` +(``None``, ``True``, ``False``) and the special +:ref:`ellipsis token <lexical-ellipsis>` (``...``). + + +.. index:: string literal, bytes literal, ASCII + single: ' (single quote); string literal + single: " (double quote); string literal +.. _strings: + +String and Bytes literals +========================= + +String literals are text enclosed in single quotes (``'``) or double +quotes (``"``). For example: + +.. code-block:: python + + "spam" + 'eggs' + +The quote used to start the literal also terminates it, so a string literal +can only contain the other quote (except with escape sequences, see below). +For example: + +.. code-block:: python + + 'Say "Hello", please.' + "Don't do that!" + +Except for this limitation, the choice of quote character (``'`` or ``"``) +does not affect how the literal is parsed. + +Inside a string literal, the backslash (``\``) character introduces an +:dfn:`escape sequence`, which has special meaning depending on the character +after the backslash. +For example, ``\"`` denotes the double quote character, and does *not* end +the string: + +.. code-block:: pycon + + >>> print("Say \"Hello\" to everyone!") + Say "Hello" to everyone! + +See :ref:`escape sequences <escape-sequences>` below for a full list of such +sequences, and more details. + + +.. index:: triple-quoted string + single: """; string literal + single: '''; string literal + +Triple-quoted strings +--------------------- + +Strings can also be enclosed in matching groups of three single or double +quotes. +These are generally referred to as :dfn:`triple-quoted strings`:: + + """This is a triple-quoted string.""" + +In triple-quoted literals, unescaped quotes are allowed (and are +retained), except that three unescaped quotes in a row terminate the literal, +if they are of the same kind (``'`` or ``"``) used at the start:: + + """This string has "quotes" inside.""" + +Unescaped newlines are also allowed and retained:: + + '''This triple-quoted string + continues on the next line.''' + + +.. index:: + single: u'; string literal + single: u"; string literal + +String prefixes +--------------- + +String literals can have an optional :dfn:`prefix` that influences how the +content of the literal is parsed, for example: + +.. code-block:: python + + b"data" + f'{result=}' + +The allowed prefixes are: + +* ``b``: :ref:`Bytes literal <bytes-literal>` +* ``r``: :ref:`Raw string <raw-strings>` +* ``f``: :ref:`Formatted string literal <f-strings>` ("f-string") +* ``t``: :ref:`Template string literal <t-strings>` ("t-string") +* ``u``: No effect (allowed for backwards compatibility) + +See the linked sections for details on each type. + +Prefixes are case-insensitive (for example, '``B``' works the same as '``b``'). +The '``r``' prefix can be combined with '``f``', '``t``' or '``b``', so '``fr``', +'``rf``', '``tr``', '``rt``', '``br``', and '``rb``' are also valid prefixes. + +.. versionadded:: 3.3 + The ``'rb'`` prefix of raw bytes literals has been added as a synonym + of ``'br'``. + + Support for the unicode legacy literal (``u'value'``) was reintroduced + to simplify the maintenance of dual Python 2.x and 3.x codebases. + See :pep:`414` for more information. + + +Formal grammar +-------------- + +String literals, except :ref:`"f-strings" <f-strings>` and +:ref:`"t-strings" <t-strings>`, are described by the +following lexical definitions. + +These definitions use :ref:`negative lookaheads <lexical-lookaheads>` (``!``) +to indicate that an ending quote ends the literal. + +.. grammar-snippet:: + :group: python-grammar + + STRING: [`stringprefix`] (`stringcontent`) + stringprefix: <("r" | "u" | "b" | "br" | "rb"), case-insensitive> + stringcontent: + | "'''" ( !"'''" `longstringitem`)* "'''" + | '"""' ( !'"""' `longstringitem`)* '"""' + | "'" ( !"'" `stringitem`)* "'" + | '"' ( !'"' `stringitem`)* '"' + stringitem: `stringchar` | `stringescapeseq` + stringchar: <any `source_character`, except backslash and newline> + longstringitem: `stringitem` | newline + stringescapeseq: "\" <any `source_character`> + +Note that as in all lexical definitions, whitespace is significant. +In particular, the prefix (if any) must be immediately followed by the starting +quote. + +.. index:: physical line, escape sequence, Standard C, C + single: \ (backslash); escape sequence + single: \\; escape sequence + single: \a; escape sequence + single: \b; escape sequence + single: \f; escape sequence + single: \n; escape sequence + single: \r; escape sequence + single: \t; escape sequence + single: \v; escape sequence + single: \x; escape sequence + single: \N; escape sequence + single: \u; escape sequence + single: \U; escape sequence + +.. _escape-sequences: + +Escape sequences +---------------- + +Unless an '``r``' or '``R``' prefix is present, escape sequences in string and +bytes literals are interpreted according to rules similar to those used by +Standard C. The recognized escape sequences are: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * * Escape Sequence + * Meaning + * * ``\``\ <newline> + * :ref:`string-escape-ignore` + * * ``\\`` + * :ref:`Backslash <string-escape-escaped-char>` + * * ``\'`` + * :ref:`Single quote <string-escape-escaped-char>` + * * ``\"`` + * :ref:`Double quote <string-escape-escaped-char>` + * * ``\a`` + * ASCII Bell (BEL) + * * ``\b`` + * ASCII Backspace (BS) + * * ``\f`` + * ASCII Formfeed (FF) + * * ``\n`` + * ASCII Linefeed (LF) + * * ``\r`` + * ASCII Carriage Return (CR) + * * ``\t`` + * ASCII Horizontal Tab (TAB) + * * ``\v`` + * ASCII Vertical Tab (VT) + * * :samp:`\\\\{ooo}` + * :ref:`string-escape-oct` + * * :samp:`\\x{hh}` + * :ref:`string-escape-hex` + * * :samp:`\\N\\{{name}\\}` + * :ref:`string-escape-named` + * * :samp:`\\u{xxxx}` + * :ref:`Hexadecimal Unicode character <string-escape-long-hex>` + * * :samp:`\\U{xxxxxxxx}` + * :ref:`Hexadecimal Unicode character <string-escape-long-hex>` + +.. _string-escape-ignore: + +Ignored end of line +^^^^^^^^^^^^^^^^^^^ + +A backslash can be added at the end of a line to ignore the newline:: + + >>> 'This string will not include \ + ... backslashes or newline characters.' + 'This string will not include backslashes or newline characters.' + +The same result can be achieved using :ref:`triple-quoted strings <strings>`, +or parentheses and :ref:`string literal concatenation <string-concatenation>`. + +.. _string-escape-escaped-char: + +Escaped characters +^^^^^^^^^^^^^^^^^^ + +To include a backslash in a non-:ref:`raw <raw-strings>` Python string +literal, it must be doubled. The ``\\`` escape sequence denotes a single +backslash character:: + + >>> print('C:\\Program Files') + C:\Program Files + +Similarly, the ``\'`` and ``\"`` sequences denote the single and double +quote character, respectively:: + + >>> print('\' and \"') + ' and " + +.. _string-escape-oct: + +Octal character +^^^^^^^^^^^^^^^ + +The sequence :samp:`\\\\{ooo}` denotes a *character* with the octal (base 8) +value *ooo*:: + + >>> '\120' + 'P' + +Up to three octal digits (0 through 7) are accepted. + +In a bytes literal, *character* means a *byte* with the given value. +In a string literal, it means a Unicode character with the given value. + +.. versionchanged:: 3.11 + Octal escapes with value larger than ``0o377`` (255) produce a + :exc:`DeprecationWarning`. + +.. versionchanged:: 3.12 + Octal escapes with value larger than ``0o377`` (255) produce a + :exc:`SyntaxWarning`. + In a future Python version they will raise a :exc:`SyntaxError`. + +.. _string-escape-hex: + +Hexadecimal character +^^^^^^^^^^^^^^^^^^^^^ + +The sequence :samp:`\\x{hh}` denotes a *character* with the hex (base 16) +value *hh*:: + + >>> '\x50' + 'P' + +Unlike in Standard C, exactly two hex digits are required. + +In a bytes literal, *character* means a *byte* with the given value. +In a string literal, it means a Unicode character with the given value. + +.. _string-escape-named: + +Named Unicode character +^^^^^^^^^^^^^^^^^^^^^^^ + +The sequence :samp:`\\N\\{{name}\\}` denotes a Unicode character +with the given *name*:: + + >>> '\N{LATIN CAPITAL LETTER P}' + 'P' + >>> '\N{SNAKE}' + '🐍' + +This sequence cannot appear in :ref:`bytes literals <bytes-literal>`. + +.. versionchanged:: 3.3 + Support for `name aliases <https://www.unicode.org/Public/17.0.0/ucd/NameAliases.txt>`__ + has been added. + +.. _string-escape-long-hex: + +Hexadecimal Unicode characters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +These sequences :samp:`\\u{xxxx}` and :samp:`\\U{xxxxxxxx}` denote the +Unicode character with the given hex (base 16) value. +Exactly four digits are required for ``\u``; exactly eight digits are +required for ``\U``. +The latter can encode any Unicode character. + +.. code-block:: pycon + + >>> '\u1234' + 'ሴ' + >>> '\U0001f40d' + '🐍' + +These sequences cannot appear in :ref:`bytes literals <bytes-literal>`. + + +.. index:: unrecognized escape sequence + +Unrecognized escape sequences +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Unlike in Standard C, all unrecognized escape sequences are left in the string +unchanged, that is, *the backslash is left in the result*:: + + >>> print('\q') + \q + >>> list('\q') + ['\\', 'q'] + +Note that for bytes literals, the escape sequences only recognized in string +literals (``\N...``, ``\u...``, ``\U...``) fall into the category of +unrecognized escapes. + +.. versionchanged:: 3.6 + Unrecognized escape sequences produce a :exc:`DeprecationWarning`. + +.. versionchanged:: 3.12 + Unrecognized escape sequences produce a :exc:`SyntaxWarning`. + In a future Python version they will raise a :exc:`SyntaxError`. + + +.. index:: + single: b'; bytes literal + single: b"; bytes literal + + +.. _bytes-literal: + +Bytes literals +-------------- + +:dfn:`Bytes literals` are always prefixed with '``b``' or '``B``'; they produce an +instance of the :class:`bytes` type instead of the :class:`str` type. +They may only contain ASCII characters; bytes with a numeric value of 128 +or greater must be expressed with escape sequences (typically +:ref:`string-escape-hex` or :ref:`string-escape-oct`): + +.. code-block:: pycon + + >>> b'\x89PNG\r\n\x1a\n' + b'\x89PNG\r\n\x1a\n' + >>> list(b'\x89PNG\r\n\x1a\n') + [137, 80, 78, 71, 13, 10, 26, 10] + +Similarly, a zero byte must be expressed using an escape sequence (typically +``\0`` or ``\x00``). + + +.. index:: + single: r'; raw string literal + single: r"; raw string literal + +.. _raw-strings: + +Raw string literals +------------------- + +Both string and bytes literals may optionally be prefixed with a letter '``r``' +or '``R``'; such constructs are called :dfn:`raw string literals` +and :dfn:`raw bytes literals` respectively and treat backslashes as +literal characters. +As a result, in raw string literals, :ref:`escape sequences <escape-sequences>` +are not treated specially: + +.. code-block:: pycon + + >>> r'\d{4}-\d{2}-\d{2}' + '\\d{4}-\\d{2}-\\d{2}' + +Even in a raw literal, quotes can be escaped with a backslash, but the +backslash remains in the result; for example, ``r"\""`` is a valid string +literal consisting of two characters: a backslash and a double quote; ``r"\"`` +is not a valid string literal (even a raw string cannot end in an odd number of +backslashes). Specifically, *a raw literal cannot end in a single backslash* +(since the backslash would escape the following quote character). Note also +that a single backslash followed by a newline is interpreted as those two +characters as part of the literal, *not* as a line continuation. + + +.. index:: + single: formatted string literal + single: interpolated string literal + single: string; formatted literal + single: string; interpolated literal + single: f-string + single: fstring + single: f'; formatted string literal + single: f"; formatted string literal + single: {} (curly brackets); in formatted string literal + single: ! (exclamation); in formatted string literal + single: : (colon); in formatted string literal + single: = (equals); for help in debugging using string literals + +.. _f-strings: +.. _formatted-string-literals: + +f-strings +--------- + +.. versionadded:: 3.6 +.. versionchanged:: 3.7 + The :keyword:`await` and :keyword:`async for` can be used in expressions + within f-strings. +.. versionchanged:: 3.8 + Added the debug specifier (``=``) +.. versionchanged:: 3.12 + Many restrictions on expressions within f-strings have been removed. + Notably, nested strings, comments, and backslashes are now permitted. + +A :dfn:`formatted string literal` or :dfn:`f-string` is a string literal +that is prefixed with '``f``' or '``F``'. +Unlike other string literals, f-strings do not have a constant value. +They may contain *replacement fields* delimited by curly braces ``{}``. +Replacement fields contain expressions which are evaluated at run time. +For example:: + + >>> who = 'nobody' + >>> nationality = 'Spanish' + >>> f'{who.title()} expects the {nationality} Inquisition!' + 'Nobody expects the Spanish Inquisition!' + +Any doubled curly braces (``{{`` or ``}}``) outside replacement fields +are replaced with the corresponding single curly brace:: + + >>> print(f'{{...}}') + {...} + +Other characters outside replacement fields are treated like in ordinary +string literals. +This means that escape sequences are decoded (except when a literal is +also marked as a raw string), and newlines are possible in triple-quoted +f-strings:: + + >>> name = 'Galahad' + >>> favorite_color = 'blue' + >>> print(f'{name}:\t{favorite_color}') + Galahad: blue + >>> print(rf"C:\Users\{name}") + C:\Users\Galahad + >>> print(f'''Three shall be the number of the counting + ... and the number of the counting shall be three.''') + Three shall be the number of the counting + and the number of the counting shall be three. + +Expressions in formatted string literals are treated like regular +Python expressions. +Each expression is evaluated in the context where the formatted string literal +appears, in order from left to right. +An empty expression is not allowed, and both :keyword:`lambda` and +assignment expressions ``:=`` must be surrounded by explicit parentheses:: + + >>> f'{(half := 1/2)}, {half * 42}' + '0.5, 21.0' + +Reusing the outer f-string quoting type inside a replacement field is +permitted:: + + >>> a = dict(x=2) + >>> f"abc {a["x"]} def" + 'abc 2 def' + +Backslashes are also allowed in replacement fields and are evaluated the same +way as in any other context:: + + >>> a = ["a", "b", "c"] + >>> print(f"List a contains:\n{"\n".join(a)}") + List a contains: + a + b + c + +It is possible to nest f-strings:: + + >>> name = 'world' + >>> f'Repeated:{f' hello {name}' * 3}' + 'Repeated: hello world hello world hello world' + +Portable Python programs should not use more than 5 levels of nesting. + +.. impl-detail:: + + CPython does not limit nesting of f-strings. + +Replacement expressions can contain newlines in both single-quoted and +triple-quoted f-strings and they can contain comments. +Everything that comes after a ``#`` inside a replacement field +is a comment (even closing braces and quotes). +This means that replacement fields with comments must be closed in a +different line: + +.. code-block:: text + + >>> a = 2 + >>> f"abc{a # This comment }" continues until the end of the line + ... + 3}" + 'abc5' + +After the expression, replacement fields may optionally contain: + +* a *debug specifier* -- an equal sign (``=``), optionally surrounded by + whitespace on one or both sides; +* a *conversion specifier* -- ``!s``, ``!r`` or ``!a``; and/or +* a *format specifier* prefixed with a colon (``:``). + +See the :ref:`Standard Library section on f-strings <stdtypes-fstrings>` +for details on how these fields are evaluated. + +As that section explains, *format specifiers* are passed as the second argument +to the :func:`format` function to format a replacement field value. +For example, they can be used to specify a field width and padding characters +using the :ref:`Format Specification Mini-Language <formatspec>`:: + + >>> number = 14.3 + >>> f'{number:20.7f}' + ' 14.3000000' + +Top-level format specifiers may include nested replacement fields:: + + >>> field_size = 20 + >>> precision = 7 + >>> f'{number:{field_size}.{precision}f}' + ' 14.3000000' + +These nested fields may include their own conversion fields and +:ref:`format specifiers <formatspec>`:: + + >>> number = 3 + >>> f'{number:{field_size}}' + ' 3' + >>> f'{number:{field_size:05}}' + '00000000000000000003' + +However, these nested fields may not include more deeply nested replacement +fields. + +Formatted string literals cannot be used as :term:`docstrings <docstring>`, +even if they do not include expressions:: + + >>> def foo(): + ... f"Not a docstring" + ... + >>> print(foo.__doc__) + None + +.. seealso:: + + * :pep:`498` -- Literal String Interpolation + * :pep:`701` -- Syntactic formalization of f-strings + * :meth:`str.format`, which uses a related format string mechanism. + + +.. _t-strings: +.. _template-string-literals: + +t-strings +--------- + +.. versionadded:: 3.14 + +A :dfn:`template string literal` or :dfn:`t-string` is a string literal +that is prefixed with '``t``' or '``T``'. +These strings follow the same syntax rules as +:ref:`formatted string literals <f-strings>`. +For differences in evaluation rules, see the +:ref:`Standard Library section on t-strings <stdtypes-tstrings>` + + +Formal grammar for f-strings +---------------------------- + +F-strings are handled partly by the :term:`lexical analyzer`, which produces the +tokens :py:data:`~token.FSTRING_START`, :py:data:`~token.FSTRING_MIDDLE` +and :py:data:`~token.FSTRING_END`, and partly by the parser, which handles +expressions in the replacement field. +The exact way the work is split is a CPython implementation detail. + +Correspondingly, the f-string grammar is a mix of +:ref:`lexical and syntactic definitions <notation-lexical-vs-syntactic>`. + +Whitespace is significant in these situations: + +* There may be no whitespace in :py:data:`~token.FSTRING_START` (between + the prefix and quote). +* Whitespace in :py:data:`~token.FSTRING_MIDDLE` is part of the literal + string contents. +* In ``fstring_replacement_field``, if ``f_debug_specifier`` is present, + all whitespace after the opening brace until the ``f_debug_specifier``, + as well as whitespace immediately following ``f_debug_specifier``, + is retained as part of the expression. + + .. impl-detail:: + + The expression is not handled in the tokenization phase; it is + retrieved from the source code using locations of the ``{`` token + and the token after ``=``. + + +The ``FSTRING_MIDDLE`` definition uses +:ref:`negative lookaheads <lexical-lookaheads>` (``!``) +to indicate special characters (backslash, newline, ``{``, ``}``) and +sequences (``f_quote``). + +.. grammar-snippet:: + :group: python-grammar + + fstring: `FSTRING_START` `fstring_middle`* `FSTRING_END` + + FSTRING_START: `fstringprefix` ("'" | '"' | "'''" | '"""') + FSTRING_END: `f_quote` + fstringprefix: <("f" | "fr" | "rf"), case-insensitive> + f_debug_specifier: '=' + f_quote: <the quote character(s) used in FSTRING_START> + + fstring_middle: + | `fstring_replacement_field` + | `FSTRING_MIDDLE` + FSTRING_MIDDLE: + | (!"\" !`newline` !'{' !'}' !`f_quote`) `source_character` + | `stringescapeseq` + | "{{" + | "}}" + | <newline, in triple-quoted f-strings only> + fstring_replacement_field: + | '{' `f_expression` [`f_debug_specifier`] [`fstring_conversion`] + [`fstring_full_format_spec`] '}' + fstring_conversion: + | "!" ("s" | "r" | "a") + fstring_full_format_spec: + | ':' `fstring_format_spec`* + fstring_format_spec: + | `FSTRING_MIDDLE` + | `fstring_replacement_field` + f_expression: + | ','.(`conditional_expression` | "*" `or_expr`)+ [","] + | `yield_expression` + +.. note:: + + In the above grammar snippet, the ``f_quote`` and ``FSTRING_MIDDLE`` rules + are context-sensitive -- they depend on the contents of ``FSTRING_START`` + of the nearest enclosing ``fstring``. + + Constructing a more traditional formal grammar from this template is left + as an exercise for the reader. + +The grammar for t-strings is identical to the one for f-strings, with *t* +instead of *f* at the beginning of rule and token names and in the prefix. + +.. grammar-snippet:: + :group: python-grammar + + tstring: TSTRING_START tstring_middle* TSTRING_END + + <rest of the t-string grammar is omitted; see above> + + +.. _numbers: + +Numeric literals +================ + +.. index:: number, numeric literal, integer literal + floating-point literal, hexadecimal literal + octal literal, binary literal, decimal literal, imaginary literal, complex literal + +:data:`~token.NUMBER` tokens represent numeric literals, of which there are +three types: integers, floating-point numbers, and imaginary numbers. + +.. grammar-snippet:: + :group: python-grammar + + NUMBER: `integer` | `floatnumber` | `imagnumber` + +The numeric value of a numeric literal is the same as if it were passed as a +string to the :class:`int`, :class:`float` or :class:`complex` class +constructor, respectively. +Note that not all valid inputs for those constructors are also valid literals. + +Numeric literals do not include a sign; a phrase like ``-1`` is +actually an expression composed of the unary operator '``-``' and the literal +``1``. + + +.. index:: + single: 0b; integer literal + single: 0o; integer literal + single: 0x; integer literal + single: _ (underscore); in numeric literal + +.. _integers: + +Integer literals +---------------- + +Integer literals denote whole numbers. For example:: + + 7 + 3 + 2147483647 + +There is no limit for the length of integer literals apart from what can be +stored in available memory:: + + 7922816251426433759354395033679228162514264337593543950336 + +Underscores can be used to group digits for enhanced readability, +and are ignored for determining the numeric value of the literal. +For example, the following literals are equivalent:: + + 100_000_000_000 + 100000000000 + 1_00_00_00_00_000 + +Underscores can only occur between digits. +For example, ``_123``, ``321_``, and ``123__321`` are *not* valid literals. + +Integers can be specified in binary (base 2), octal (base 8), or hexadecimal +(base 16) using the prefixes ``0b``, ``0o`` and ``0x``, respectively. +Hexadecimal digits 10 through 15 are represented by letters ``A``-``F``, +case-insensitive. For example:: + + 0b100110111 + 0b_1110_0101 + 0o177 + 0o377 + 0xdeadbeef + 0xDead_Beef + +An underscore can follow the base specifier. +For example, ``0x_1f`` is a valid literal, but ``0_x1f`` and ``0x__1f`` are +not. + +Leading zeros in a non-zero decimal number are not allowed. +For example, ``0123`` is not a valid literal. +This is for disambiguation with C-style octal literals, which Python used +before version 3.0. + +Formally, integer literals are described by the following lexical definitions: + +.. grammar-snippet:: + :group: python-grammar + + integer: `decinteger` | `bininteger` | `octinteger` | `hexinteger` | `zerointeger` + decinteger: `nonzerodigit` (["_"] `digit`)* + bininteger: "0" ("b" | "B") (["_"] `bindigit`)+ + octinteger: "0" ("o" | "O") (["_"] `octdigit`)+ + hexinteger: "0" ("x" | "X") (["_"] `hexdigit`)+ + zerointeger: "0"+ (["_"] "0")* + nonzerodigit: "1"..."9" + digit: "0"..."9" + bindigit: "0" | "1" + octdigit: "0"..."7" + hexdigit: `digit` | "a"..."f" | "A"..."F" + +.. versionchanged:: 3.6 + Underscores are now allowed for grouping purposes in literals. + + +.. index:: + single: . (dot); in numeric literal + single: e; in numeric literal + single: _ (underscore); in numeric literal +.. _floating: + +Floating-point literals +----------------------- + +Floating-point (float) literals, such as ``3.14`` or ``1.5``, denote +:ref:`approximations of real numbers <datamodel-float>`. + +They consist of *integer* and *fraction* parts, each composed of decimal digits. +The parts are separated by a decimal point, ``.``:: + + 2.71828 + 4.0 + +Unlike in integer literals, leading zeros are allowed. +For example, ``077.010`` is legal, and denotes the same number as ``77.01``. + +As in integer literals, single underscores may occur between digits to help +readability:: + + 96_485.332_123 + 3.14_15_93 + +Either of these parts, but not both, can be empty. For example:: + + 10. # (equivalent to 10.0) + .001 # (equivalent to 0.001) + +Optionally, the integer and fraction may be followed by an *exponent*: +the letter ``e`` or ``E``, followed by an optional sign, ``+`` or ``-``, +and a number in the same format as the integer and fraction parts. +The ``e`` or ``E`` represents "times ten raised to the power of":: + + 1.0e3 # (represents 1.0×10³, or 1000.0) + 1.166e-5 # (represents 1.166×10⁻⁵, or 0.00001166) + 6.02214076e+23 # (represents 6.02214076×10²³, or 602214076000000000000000.) + +In floats with only integer and exponent parts, the decimal point may be +omitted:: + + 1e3 # (equivalent to 1.e3 and 1.0e3) + 0e0 # (equivalent to 0.) + +Formally, floating-point literals are described by the following +lexical definitions: + +.. grammar-snippet:: + :group: python-grammar + + floatnumber: + | `digitpart` "." [`digitpart`] [`exponent`] + | "." `digitpart` [`exponent`] + | `digitpart` `exponent` + digitpart: `digit` (["_"] `digit`)* + exponent: ("e" | "E") ["+" | "-"] `digitpart` + +.. versionchanged:: 3.6 + Underscores are now allowed for grouping purposes in literals. + + +.. index:: + single: j; in numeric literal +.. _imaginary: + +Imaginary literals +------------------ + +Python has :ref:`complex number <typesnumeric>` objects, but no complex +literals. +Instead, *imaginary literals* denote complex numbers with a zero +real part. + +For example, in math, the complex number 3+4.2\ *i* is written +as the real number 3 added to the imaginary number 4.2\ *i*. +Python uses a similar syntax, except the imaginary unit is written as ``j`` +rather than *i*:: + + 3+4.2j + +This is an expression composed +of the :ref:`integer literal <integers>` ``3``, +the :ref:`operator <operators>` '``+``', +and the :ref:`imaginary literal <imaginary>` ``4.2j``. +Since these are three separate tokens, whitespace is allowed between them:: + + 3 + 4.2j + +No whitespace is allowed *within* each token. +In particular, the ``j`` suffix, may not be separated from the number +before it. + +The number before the ``j`` has the same syntax as a floating-point literal. +Thus, the following are valid imaginary literals:: + + 4.2j + 3.14j + 10.j + .001j + 1e100j + 3.14e-10j + 3.14_15_93j + +Unlike in a floating-point literal the decimal point can be omitted if the +imaginary number only has an integer part. +The number is still evaluated as a floating-point number, not an integer:: + + 10j + 0j + 1000000000000000000000000j # equivalent to 1e+24j + +The ``j`` suffix is case-insensitive. +That means you can use ``J`` instead:: + + 3.14J # equivalent to 3.14j + +Formally, imaginary literals are described by the following lexical definition: + +.. grammar-snippet:: + :group: python-grammar + + imagnumber: (`floatnumber` | `digitpart`) ("j" | "J") + + +.. _delimiters: +.. _operators: +.. _lexical-ellipsis: + +Operators and delimiters +======================== + +.. index:: + single: operators + single: delimiters + +The following grammar defines :dfn:`operator` and :dfn:`delimiter` tokens, +that is, the generic :data:`~token.OP` token type. +A :ref:`list of these tokens and their names <token_operators_delimiters>` +is also available in the :mod:`!token` module documentation. + +.. grammar-snippet:: + :group: python-grammar + + OP: + | assignment_operator + | bitwise_operator + | comparison_operator + | enclosing_delimiter + | other_delimiter + | arithmetic_operator + | "..." + | other_op + + assignment_operator: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | + "&=" | "|=" | "^=" | "<<=" | ">>=" | "@=" | ":=" + bitwise_operator: "&" | "|" | "^" | "~" | "<<" | ">>" + comparison_operator: "<=" | ">=" | "<" | ">" | "==" | "!=" + enclosing_delimiter: "(" | ")" | "[" | "]" | "{" | "}" + other_delimiter: "," | ":" | "!" | ";" | "=" | "->" + arithmetic_operator: "+" | "-" | "**" | "*" | "//" | "/" | "%" + other_op: "." | "@" + +.. note:: + + Generally, *operators* are used to combine :ref:`expressions <expressions>`, + while *delimiters* serve other purposes. + However, there is no clear, formal distinction between the two categories. + + Some tokens can serve as either operators or delimiters, depending on usage. + For example, ``*`` is both the multiplication operator and a delimiter used + for sequence unpacking, and ``@`` is both the matrix multiplication and + a delimiter that introduces decorators. + + For some tokens, the distinction is unclear. + For example, some people consider ``.``, ``(``, and ``)`` to be delimiters, while others + see the :py:func:`getattr` operator and the function call operator(s). + + Some of Python's operators, like ``and``, ``or``, and ``not in``, use + :ref:`keyword <keywords>` tokens rather than "symbols" (operator tokens). + +A sequence of three consecutive periods (``...``) has a special +meaning as an :py:data:`Ellipsis` literal. + diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/simple_stmts.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/simple_stmts.rst new file mode 100644 index 00000000..a964b43e --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/simple_stmts.rst @@ -0,0 +1,1176 @@ + +.. _simple: + +***************** +Simple statements +***************** + +.. index:: pair: simple; statement + +A simple statement is comprised within a single logical line. Several simple +statements may occur on a single line separated by semicolons. The syntax for +simple statements is: + +.. productionlist:: python-grammar + simple_stmt: `expression_stmt` + : | `assert_stmt` + : | `assignment_stmt` + : | `augmented_assignment_stmt` + : | `annotated_assignment_stmt` + : | `pass_stmt` + : | `del_stmt` + : | `return_stmt` + : | `yield_stmt` + : | `raise_stmt` + : | `break_stmt` + : | `continue_stmt` + : | `import_stmt` + : | `future_stmt` + : | `global_stmt` + : | `nonlocal_stmt` + : | `type_stmt` + + +.. _exprstmts: + +Expression statements +===================== + +.. index:: + pair: expression; statement + pair: expression; list +.. index:: pair: expression; list + +Expression statements are used (mostly interactively) to compute and write a +value, or (usually) to call a procedure (a function that returns no meaningful +result; in Python, procedures return the value ``None``). Other uses of +expression statements are allowed and occasionally useful. The syntax for an +expression statement is: + +.. productionlist:: python-grammar + expression_stmt: `starred_expression` + +An expression statement evaluates the expression list (which may be a single +expression). + +.. index:: + pair: built-in function; repr + pair: object; None + pair: string; conversion + single: output + pair: standard; output + pair: writing; values + pair: procedure; call + +In interactive mode, if the value is not ``None``, it is converted to a string +using the built-in :func:`repr` function and the resulting string is written to +standard output on a line by itself (except if the result is ``None``, so that +procedure calls do not cause any output.) + +.. _assignment: + +Assignment statements +===================== + +.. index:: + single: = (equals); assignment statement + pair: assignment; statement + pair: binding; name + pair: rebinding; name + pair: object; mutable + pair: attribute; assignment + +Assignment statements are used to (re)bind names to values and to modify +attributes or items of mutable objects: + +.. productionlist:: python-grammar + assignment_stmt: (`target_list` "=")+ (`starred_expression` | `yield_expression`) + target_list: `target` ("," `target`)* [","] + target: `identifier` + : | "(" [`target_list`] ")" + : | "[" [`target_list`] "]" + : | `attributeref` + : | `subscription` + : | "*" `target` + +(See section :ref:`primaries` for the syntax definitions for *attributeref* +and *subscription*.) + +An assignment statement evaluates the expression list (remember that this can be +a single expression or a comma-separated list, the latter yielding a tuple) and +assigns the single resulting object to each of the target lists, from left to +right. + +.. index:: + single: target + pair: target; list + +Assignment is defined recursively depending on the form of the target (list). +When a target is part of a mutable object (an attribute reference or +subscription), the mutable object must ultimately perform the assignment and +decide about its validity, and may raise an exception if the assignment is +unacceptable. The rules observed by various types and the exceptions raised are +given with the definition of the object types (see section :ref:`types`). + +.. index:: triple: target; list; assignment + single: , (comma); in target list + single: * (asterisk); in assignment target list + single: [] (square brackets); in assignment target list + single: () (parentheses); in assignment target list + +Assignment of an object to a target list, optionally enclosed in parentheses or +square brackets, is recursively defined as follows. + +* If the target list is a single target with no trailing comma, + optionally in parentheses, the object is assigned to that target. + +* Else: + + * If the target list contains one target prefixed with an asterisk, called a + "starred" target: The object must be an iterable with at least as many items + as there are targets in the target list, minus one. The first items of the + iterable are assigned, from left to right, to the targets before the starred + target. The final items of the iterable are assigned to the targets after + the starred target. A list of the remaining items in the iterable is then + assigned to the starred target (the list can be empty). + + * Else: The object must be an iterable with the same number of items as there + are targets in the target list, and the items are assigned, from left to + right, to the corresponding targets. + +Assignment of an object to a single target is recursively defined as follows. + +* If the target is an identifier (name): + + * If the name does not occur in a :keyword:`global` or :keyword:`nonlocal` + statement in the current code block: the name is bound to the object in the + current local namespace. + + * Otherwise: the name is bound to the object in the global namespace or the + outer namespace determined by :keyword:`nonlocal`, respectively. + + .. index:: single: destructor + + The name is rebound if it was already bound. This may cause the reference + count for the object previously bound to the name to reach zero, causing the + object to be deallocated and its destructor (if it has one) to be called. + + .. index:: pair: attribute; assignment + +* If the target is an attribute reference: The primary expression in the + reference is evaluated. It should yield an object with assignable attributes; + if this is not the case, :exc:`TypeError` is raised. That object is then + asked to assign the assigned object to the given attribute; if it cannot + perform the assignment, it raises an exception (usually but not necessarily + :exc:`AttributeError`). + + .. _attr-target-note: + + Note: If the object is a class instance and the attribute reference occurs on + both sides of the assignment operator, the right-hand side expression, ``a.x`` can access + either an instance attribute or (if no instance attribute exists) a class + attribute. The left-hand side target ``a.x`` is always set as an instance attribute, + creating it if necessary. Thus, the two occurrences of ``a.x`` do not + necessarily refer to the same attribute: if the right-hand side expression refers to a + class attribute, the left-hand side creates a new instance attribute as the target of the + assignment:: + + class Cls: + x = 3 # class variable + inst = Cls() + inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3 + + This description does not necessarily apply to descriptor attributes, such as + properties created with :deco:`property`. + + .. index:: + pair: subscription; assignment + pair: object; mutable + +* If the target is a subscription: The primary expression in the reference is + evaluated. + Next, the subscript expression is evaluated. + Then, the primary's :meth:`~object.__setitem__` method is called with + two arguments: the subscript and the assigned object. + + Typically, :meth:`~object.__setitem__` is defined on mutable sequence objects + (such as lists) and mapping objects (such as dictionaries), and behaves as + follows. + + .. index:: + pair: object; sequence + pair: object; list + + If the primary is a mutable sequence object (such as a list), the subscript + must yield an integer. If it is negative, the sequence's length is added to + it. The resulting value must be a nonnegative integer less than the + sequence's length, and the sequence is asked to assign the assigned object to + its item with that index. If the index is out of range, :exc:`IndexError` is + raised (assignment to a subscripted sequence cannot add new items to a list). + + .. index:: + pair: object; mapping + pair: object; dictionary + + If the primary is a mapping object (such as a dictionary), the subscript must + have a type compatible with the mapping's key type, and the mapping is then + asked to create a key/value pair which maps the subscript to the assigned + object. This can either replace an existing key/value pair with the same key + value, or insert a new key/value pair (if no key with the same value existed). + + .. index:: pair: slicing; assignment + + If the target is a slicing: The primary expression should evaluate to + a mutable sequence object (such as a list). + The assigned object should be :term:`iterable`. + The slicing's lower and upper bounds should be integers; if they are ``None`` + (or not present), the defaults are zero and the sequence's length. + If either bound is negative, the sequence's length is added to it. The + resulting bounds are clipped to lie between zero and the sequence's length, + inclusive. Finally, the sequence object is asked to replace the slice with + the items of the assigned sequence. The length of the slice may be different + from the length of the assigned sequence, thus changing the length of the + target sequence, if the target sequence allows it. + +Although the definition of assignment implies that overlaps between the +left-hand side and the right-hand side are 'simultaneous' (for example ``a, b = +b, a`` swaps two variables), overlaps *within* the collection of assigned-to +variables occur left-to-right, sometimes resulting in confusion. For instance, +the following program prints ``[0, 2]``:: + + x = [0, 1] + i = 0 + i, x[i] = 1, 2 # i is updated, then x[i] is updated + print(x) + + +.. seealso:: + + :pep:`3132` - Extended Iterable Unpacking + The specification for the ``*target`` feature. + + +.. _augassign: + +Augmented assignment statements +------------------------------- + +.. index:: + pair: augmented; assignment + single: statement; assignment, augmented + single: +=; augmented assignment + single: -=; augmented assignment + single: *=; augmented assignment + single: /=; augmented assignment + single: %=; augmented assignment + single: &=; augmented assignment + single: ^=; augmented assignment + single: |=; augmented assignment + single: **=; augmented assignment + single: //=; augmented assignment + single: >>=; augmented assignment + single: <<=; augmented assignment + +Augmented assignment is the combination, in a single statement, of a binary +operation and an assignment statement: + +.. productionlist:: python-grammar + augmented_assignment_stmt: `augtarget` `augop` (`expression_list` | `yield_expression`) + augtarget: `identifier` | `attributeref` | `subscription` + augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" + : | ">>=" | "<<=" | "&=" | "^=" | "|=" + +(See section :ref:`primaries` for the syntax definitions of the last three +symbols.) + +An augmented assignment evaluates the target (which, unlike normal assignment +statements, cannot be an unpacking) and the expression list, performs the binary +operation specific to the type of assignment on the two operands, and assigns +the result to the original target. The target is only evaluated once. + +An augmented assignment statement like ``x += 1`` can be rewritten as ``x = x + +1`` to achieve a similar, but not exactly equal effect. In the augmented +version, ``x`` is only evaluated once. Also, when possible, the actual operation +is performed *in-place*, meaning that rather than creating a new object and +assigning that to the target, the old object is modified instead. + +Unlike normal assignments, augmented assignments evaluate the left-hand side +*before* evaluating the right-hand side. For example, ``a[i] += f(x)`` first +looks-up ``a[i]``, then it evaluates ``f(x)`` and performs the addition, and +lastly, it writes the result back to ``a[i]``. + +With the exception of assigning to tuples and multiple targets in a single +statement, the assignment done by augmented assignment statements is handled the +same way as normal assignments. Similarly, with the exception of the possible +*in-place* behavior, the binary operation performed by augmented assignment is +the same as the normal binary operations. + +For targets which are attribute references, the same :ref:`caveat about class +and instance attributes <attr-target-note>` applies as for regular assignments. + + +.. _annassign: + +Annotated assignment statements +------------------------------- + +.. index:: + pair: annotated; assignment + single: statement; assignment, annotated + single: : (colon); annotated variable + +:term:`Annotation <variable annotation>` assignment is the combination, in a single +statement, of a variable or attribute annotation and an optional assignment statement: + +.. productionlist:: python-grammar + annotated_assignment_stmt: `augtarget` ":" `expression` + : ["=" (`starred_expression` | `yield_expression`)] + +The difference from normal :ref:`assignment` is that only a single target is allowed. + +The assignment target is considered "simple" if it consists of a single +name that is not enclosed in parentheses. +For simple assignment targets, if in class or module scope, +the annotations are gathered in a lazily evaluated +:ref:`annotation scope <annotation-scopes>`. The annotations can be +evaluated using the :attr:`~object.__annotations__` attribute of a +class or module, or using the facilities in the :mod:`annotationlib` +module. + +If the assignment target is not simple (an attribute, subscript node, or +parenthesized name), the annotation is never evaluated. + +If a name is annotated in a function scope, then this name is local for +that scope. Annotations are never evaluated and stored in function scopes. + +If the right hand side is present, an annotated +assignment performs the actual assignment as if there was no annotation +present. If the right hand side is not present for an expression +target, then the interpreter evaluates the target except for the last +:meth:`~object.__setitem__` or :meth:`~object.__setattr__` call. + +.. seealso:: + + :pep:`526` - Syntax for Variable Annotations + The proposal that added syntax for annotating the types of variables + (including class variables and instance variables), instead of expressing + them through comments. + + :pep:`484` - Type hints + The proposal that added the :mod:`typing` module to provide a standard + syntax for type annotations that can be used in static analysis tools and + IDEs. + +.. versionchanged:: 3.8 + Now annotated assignments allow the same expressions in the right hand side as + regular assignments. Previously, some expressions (like un-parenthesized + tuple expressions) caused a syntax error. + +.. versionchanged:: 3.14 + Annotations are now lazily evaluated in a separate :ref:`annotation scope <annotation-scopes>`. + If the assignment target is not simple, annotations are never evaluated. + + +.. _assert: + +The :keyword:`!assert` statement +================================ + +.. index:: + ! pair: statement; assert + pair: debugging; assertions + single: , (comma); expression list + +Assert statements are a convenient way to insert debugging assertions into a +program: + +.. productionlist:: python-grammar + assert_stmt: "assert" `expression` ["," `expression`] + +The simple form, ``assert expression``, is equivalent to :: + + if __debug__: + if not expression: raise AssertionError + +The extended form, ``assert expression1, expression2``, is equivalent to :: + + if __debug__: + if not expression1: raise AssertionError(expression2) + +.. index:: + single: __debug__ + pair: exception; AssertionError + +These equivalences assume that :const:`__debug__` and :exc:`AssertionError` refer to +the built-in variables with those names. In the current implementation, the +built-in variable ``__debug__`` is ``True`` under normal circumstances, +``False`` when optimization is requested (command line option :option:`-O`). The current +code generator emits no code for an :keyword:`assert` statement when optimization is +requested at compile time. Note that it is unnecessary to include the source +code for the expression that failed in the error message; it will be displayed +as part of the stack trace. + +Assignments to :const:`__debug__` are illegal. The value for the built-in variable +is determined when the interpreter starts. + + +.. _pass: + +The :keyword:`!pass` statement +============================== + +.. index:: + pair: statement; pass + pair: null; operation + pair: null; operation + +.. productionlist:: python-grammar + pass_stmt: "pass" + +:keyword:`pass` is a null operation --- when it is executed, nothing happens. +It is useful as a placeholder when a statement is required syntactically, but no +code needs to be executed, for example:: + + def f(arg): pass # a function that does nothing (yet) + + class C: pass # a class with no methods (yet) + + +.. _del: + +The :keyword:`!del` statement +============================= + +.. index:: + ! pair: statement; del + pair: deletion; target + triple: deletion; target; list + +.. productionlist:: python-grammar + del_stmt: "del" `target_list` + +Deletion is recursively defined very similar to the way assignment is defined. +Rather than spelling it out in full details, here are some hints. + +Deletion of a target list recursively deletes each target, from left to right. + +.. index:: + pair: statement; global + pair: unbinding; name + +Deletion of a name removes the binding of that name from the local or global +namespace, depending on whether the name occurs in a :keyword:`global` statement +in the same code block. Trying to delete an unbound name raises a +:exc:`NameError` exception. + +.. index:: pair: attribute; deletion + +Deletion of attribute references and subscriptions is passed to the +primary object involved; deletion of a slicing is in general equivalent to +assignment of an empty slice of the right type (but even this is determined by +the sliced object). + +.. versionchanged:: 3.2 + Previously it was illegal to delete a name from the local namespace if it + occurs as a free variable in a nested block. + + +.. _return: + +The :keyword:`!return` statement +================================ + +.. index:: + ! pair: statement; return + pair: function; definition + pair: class; definition + +.. productionlist:: python-grammar + return_stmt: "return" [`expression_list`] + +:keyword:`return` may only occur syntactically nested in a function definition, +not within a nested class definition. + +If an expression list is present, it is evaluated, else ``None`` is substituted. + +:keyword:`return` leaves the current function call with the expression list (or +``None``) as return value. + +.. index:: pair: keyword; finally + +When :keyword:`return` passes control out of a :keyword:`try` statement with a +:keyword:`finally` clause, that :keyword:`!finally` clause is executed before +really leaving the function. + +In a generator function, the :keyword:`return` statement indicates that the +generator is done and will cause :exc:`StopIteration` to be raised. The returned +value (if any) is used as an argument to construct :exc:`StopIteration` and +becomes the :attr:`StopIteration.value` attribute. + +In an asynchronous generator function, an empty :keyword:`return` statement +indicates that the asynchronous generator is done and will cause +:exc:`StopAsyncIteration` to be raised. A non-empty :keyword:`!return` +statement is a syntax error in an asynchronous generator function. + +.. _yield: + +The :keyword:`!yield` statement +=============================== + +.. index:: + pair: statement; yield + single: generator; function + single: generator; iterator + single: function; generator + pair: exception; StopIteration + +.. productionlist:: python-grammar + yield_stmt: `yield_expression` + +A :keyword:`yield` statement is semantically equivalent to a :ref:`yield +expression <yieldexpr>`. The ``yield`` statement can be used to omit the +parentheses that would otherwise be required in the equivalent yield expression +statement. For example, the yield statements :: + + yield <expr> + yield from <expr> + +are equivalent to the yield expression statements :: + + (yield <expr>) + (yield from <expr>) + +Yield expressions and statements are only used when defining a :term:`generator` +function, and are only used in the body of the generator function. Using :keyword:`yield` +in a function definition is sufficient to cause that definition to create a +generator function instead of a normal function. + +For full details of :keyword:`yield` semantics, refer to the +:ref:`yieldexpr` section. + +.. _raise: + +The :keyword:`!raise` statement +=============================== + +.. index:: + ! pair: statement; raise + single: exception + pair: raising; exception + single: __traceback__ (exception attribute) + +.. productionlist:: python-grammar + raise_stmt: "raise" [`expression` ["from" `expression`]] + +If no expressions are present, :keyword:`raise` re-raises the +exception that is currently being handled, which is also known as the *active exception*. +If there isn't currently an active exception, a :exc:`RuntimeError` exception is raised +indicating that this is an error. + +Otherwise, :keyword:`raise` evaluates the first expression as the exception +object. It must be either a subclass or an instance of :class:`BaseException`. +If it is a class, the exception instance will be obtained when needed by +instantiating the class with no arguments. + +The :dfn:`type` of the exception is the exception instance's class, the +:dfn:`value` is the instance itself. + +.. index:: pair: object; traceback + +A traceback object is normally created automatically when an exception is raised +and attached to it as the :attr:`~BaseException.__traceback__` attribute. +You can create an exception and set your own traceback in one step using the +:meth:`~BaseException.with_traceback` exception method (which returns the +same exception instance, with its traceback set to its argument), like so:: + + raise Exception("foo occurred").with_traceback(tracebackobj) + +.. index:: pair: exception; chaining + __cause__ (exception attribute) + __context__ (exception attribute) + +The ``from`` clause is used for exception chaining: if given, the second +*expression* must be another exception class or instance. If the second +expression is an exception instance, it will be attached to the raised +exception as the :attr:`~BaseException.__cause__` attribute (which is writable). If the +expression is an exception class, the class will be instantiated and the +resulting exception instance will be attached to the raised exception as the +:attr:`!__cause__` attribute. If the raised exception is not handled, both +exceptions will be printed: + +.. code-block:: pycon + + >>> try: + ... print(1 / 0) + ... except Exception as exc: + ... raise RuntimeError("Something bad happened") from exc + ... + Traceback (most recent call last): + File "<stdin>", line 2, in <module> + print(1 / 0) + ~~^~~ + ZeroDivisionError: division by zero + + The above exception was the direct cause of the following exception: + + Traceback (most recent call last): + File "<stdin>", line 4, in <module> + raise RuntimeError("Something bad happened") from exc + RuntimeError: Something bad happened + +A similar mechanism works implicitly if a new exception is raised when +an exception is already being handled. An exception may be handled +when an :keyword:`except` or :keyword:`finally` clause, or a +:keyword:`with` statement, is used. The previous exception is then +attached as the new exception's :attr:`~BaseException.__context__` attribute: + +.. code-block:: pycon + + >>> try: + ... print(1 / 0) + ... except: + ... raise RuntimeError("Something bad happened") + ... + Traceback (most recent call last): + File "<stdin>", line 2, in <module> + print(1 / 0) + ~~^~~ + ZeroDivisionError: division by zero + + During handling of the above exception, another exception occurred: + + Traceback (most recent call last): + File "<stdin>", line 4, in <module> + raise RuntimeError("Something bad happened") + RuntimeError: Something bad happened + +Exception chaining can be explicitly suppressed by specifying :const:`None` in +the ``from`` clause: + +.. doctest:: + + >>> try: + ... print(1 / 0) + ... except: + ... raise RuntimeError("Something bad happened") from None + ... + Traceback (most recent call last): + File "<stdin>", line 4, in <module> + RuntimeError: Something bad happened + +Additional information on exceptions can be found in section :ref:`exceptions`, +and information about handling exceptions is in section :ref:`try`. + +.. versionchanged:: 3.3 + :const:`None` is now permitted as ``Y`` in ``raise X from Y``. + + Added the :attr:`~BaseException.__suppress_context__` attribute to suppress + automatic display of the exception context. + +.. versionchanged:: 3.11 + If the traceback of the active exception is modified in an :keyword:`except` + clause, a subsequent ``raise`` statement re-raises the exception with the + modified traceback. Previously, the exception was re-raised with the + traceback it had when it was caught. + +.. _break: + +The :keyword:`!break` statement +=============================== + +.. index:: + ! pair: statement; break + pair: statement; for + pair: statement; while + pair: loop; statement + +.. productionlist:: python-grammar + break_stmt: "break" + +:keyword:`break` may only occur syntactically nested in a :keyword:`for` or +:keyword:`while` loop, but not nested in a function or class definition within +that loop. + +.. index:: pair: keyword; else + pair: loop control; target + +It terminates the nearest enclosing loop, skipping the optional :keyword:`!else` +clause if the loop has one. + +If a :keyword:`for` loop is terminated by :keyword:`break`, the loop control +target keeps its current value. + +.. index:: pair: keyword; finally + +When :keyword:`break` passes control out of a :keyword:`try` statement with a +:keyword:`finally` clause, that :keyword:`!finally` clause is executed before +really leaving the loop. + + +.. _continue: + +The :keyword:`!continue` statement +================================== + +.. index:: + ! pair: statement; continue + pair: statement; for + pair: statement; while + pair: loop; statement + pair: keyword; finally + +.. productionlist:: python-grammar + continue_stmt: "continue" + +:keyword:`continue` may only occur syntactically nested in a :keyword:`for` or +:keyword:`while` loop, but not nested in a function or class definition within +that loop. It continues with the next cycle of the nearest enclosing loop. + +When :keyword:`continue` passes control out of a :keyword:`try` statement with a +:keyword:`finally` clause, that :keyword:`!finally` clause is executed before +really starting the next loop cycle. + + +.. _import: +.. _from: + +The :keyword:`!import` statement +================================ + +.. index:: + ! pair: statement; import + single: module; importing + pair: name; binding + pair: keyword; from + pair: keyword; as + pair: keyword; lazy + pair: exception; ImportError + single: , (comma); import statement + +.. productionlist:: python-grammar + import_stmt: ["lazy"] "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])* + : | ["lazy"] "from" `relative_module` "import" `identifier` ["as" `identifier`] + : ("," `identifier` ["as" `identifier`])* + : | ["lazy"] "from" `relative_module` "import" "(" `identifier` ["as" `identifier`] + : ("," `identifier` ["as" `identifier`])* [","] ")" + : | "from" `relative_module` "import" "*" + module: (`identifier` ".")* `identifier` + relative_module: "."* `module` | "."+ + +The basic import statement (no :keyword:`from` clause) is executed in two +steps: + +#. find a module, loading and initializing it if necessary +#. define a name or names in the current namespace for the scope where + the :keyword:`import` statement occurs, just as an assignment statement + would (including :keyword:`global` and :keyword:`nonlocal` semantics). + +When the statement contains multiple clauses (separated by +commas) the two steps are carried out separately for each clause, just +as though the clauses had been separated out into individual import +statements. + +The details of the first step, finding and loading modules, are described in +greater detail in the section on the :ref:`import system <importsystem>`, +which also describes the various types of packages and modules that can +be imported, as well as all the hooks that can be used to customize +the import system. Note that failures in this step may indicate either +that the module could not be located, *or* that an error occurred while +initializing the module, which includes execution of the module's code. + +If the requested module is retrieved successfully, it will be made +available in the local namespace in one of three ways: + +.. index:: single: as; import statement + +* If the module name is followed by :keyword:`!as`, then the name + following :keyword:`!as` is bound directly to the imported module. +* If no other name is specified, and the module being imported is a top + level module, the module's name is bound in the local namespace as a + reference to the imported module +* If the module being imported is *not* a top level module, then the name + of the top level package that contains the module is bound in the local + namespace as a reference to the top level package. The imported module + must be accessed using its full qualified name rather than directly + + +.. index:: + pair: name; binding + single: from; import statement + +The :keyword:`from` form uses a slightly more complex process: + +#. find the module specified in the :keyword:`from` clause, loading and + initializing it if necessary; +#. for each of the identifiers specified in the :keyword:`import` clauses: + + #. check if the imported module has an attribute by that name + #. if not, attempt to import a submodule with that name and then + check the imported module again for that attribute + #. if the attribute is not found, :exc:`ImportError` is raised. + #. otherwise, a reference to that value is stored in the current namespace, + using the name in the :keyword:`!as` clause if it is present, + otherwise using the attribute name + +Examples:: + + import foo # foo imported and bound locally + import foo.bar.baz # foo, foo.bar, and foo.bar.baz imported, foo bound locally + import foo.bar.baz as fbb # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as fbb + from foo.bar import baz # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as baz + from foo import attr # foo imported and foo.attr bound as attr + +.. index:: single: * (asterisk); import statement + +If the list of identifiers is replaced by a star (``'*'``), all public +names defined in the module are bound in the local namespace for the scope +where the :keyword:`import` statement occurs. + +.. index:: single: __all__ (optional module attribute) + +.. attribute:: module.__all__ + :no-typesetting: + +The *public names* defined by a module are determined by checking the module's +namespace for a variable named ``__all__``; if defined, it must be a sequence +of strings which are names defined or imported by that module. +Names containing non-ASCII characters must be in the `normalization form`_ +NFKC; see :ref:`lexical-names-nonascii` for details. The names +given in ``__all__`` are all considered public and are required to exist. If +``__all__`` is not defined, the set of public names includes all names found +in the module's namespace which do not begin with an underscore character +(``'_'``). ``__all__`` should contain the entire public API. It is intended +to avoid accidentally exporting items that are not part of the API (such as +library modules which were imported and used within the module). + +The wild card form of import --- ``from module import *`` --- is only allowed at +the module level. Attempting to use it in class or function definitions will +raise a :exc:`SyntaxError`. + +.. index:: + single: relative; import + +When specifying what module to import you do not have to specify the absolute +name of the module. When a module or package is contained within another +package it is possible to make a relative import within the same top package +without having to mention the package name. By using leading dots in the +specified module or package after :keyword:`from` you can specify how high to +traverse up the current package hierarchy without specifying exact names. One +leading dot means the current package where the module making the import +exists. Two dots means up one package level. Three dots is up two levels, etc. +So if you execute ``from . import mod`` from a module in the ``pkg`` package +then you will end up importing ``pkg.mod``. If you execute ``from ..subpkg2 +import mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``. +The specification for relative imports is contained in +the :ref:`relativeimports` section. + +:func:`importlib.import_module` is provided to support applications that +determine dynamically the modules to be loaded. + +.. audit-event:: import module,filename,sys.path,sys.meta_path,sys.path_hooks import + +.. _normalization form: https://www.unicode.org/reports/tr15/#Norm_Forms + +.. _lazy-imports: +.. _lazy: + +Lazy imports +------------ + +.. index:: + pair: lazy; import + single: lazy import + +The :keyword:`lazy` keyword is a :ref:`soft keyword <soft-keywords>` that +only has special meaning when it appears immediately before an +:keyword:`import` or :keyword:`from` statement. When an import statement is +preceded by the :keyword:`lazy` keyword, the import becomes *lazy*: the +module is not loaded immediately at the import statement. Instead, a lazy +proxy object is created and bound to the name. The actual module is loaded +on first use of that name. + +Lazy imports are only permitted at module scope. Using :keyword:`lazy` +inside a function, class body, or +:keyword:`try`/:keyword:`except`/:keyword:`finally` block raises a +:exc:`SyntaxError`. Star imports cannot be lazy (``lazy from module import +*`` is a syntax error), and :ref:`future statements <future>` cannot be +lazy. + +When using ``lazy from ... import``, each imported name is bound to a lazy +proxy object. The first access to any of these names triggers loading of the +entire module and resolves only that specific name to its actual value. +Other names remain as lazy proxies until they are accessed. + +Example:: + + lazy import json + import sys + + print('json' in sys.modules) # False - json module not yet loaded + + # First use triggers loading + result = json.dumps({"hello": "world"}) + + print('json' in sys.modules) # True - now loaded + +If an error occurs during module loading (such as :exc:`ImportError` or +:exc:`SyntaxError`), it is raised at the point where the lazy import is first +used, not at the import statement itself. + +See :pep:`810` for the full specification of lazy imports. + +.. versionadded:: 3.15 + +.. _lazy-modules-compat: + +Compatibility via ``__lazy_modules__`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: __lazy_modules__ + +As an alternative to using the :keyword:`lazy` keyword, a module can opt +into lazy loading for specific imports by defining a module-level +:attr:`~module.__lazy_modules__` variable. When present, it must be a +container of fully qualified module name strings. Any regular (non-``lazy``) +:keyword:`import` statement at module scope whose target appears in +:attr:`!__lazy_modules__` is treated as a lazy import, exactly as if the +:keyword:`lazy` keyword had been used. + +This provides a way to enable lazy loading for specific dependencies without +changing individual ``import`` statements. This is useful when supporting +Python versions older than 3.15 while using lazy imports in 3.15+:: + + __lazy_modules__ = ["json", "pathlib"] + + import json # loaded lazily (name is in __lazy_modules__) + import os # loaded eagerly (name not in __lazy_modules__) + + import pathlib # loaded lazily + +Relative imports are resolved to their absolute name before the lookup, so +:attr:`!__lazy_modules__` must always contain fully qualified module names. + +For ``from``-style imports, the relevant name is the module following +``from``, not the names of its members:: + + # In mypackage/mymodule.py + __lazy_modules__ = ["mypackage", "mypackage.sub.utils"] + + from . import helper # loaded lazily: . resolves to mypackage + from .sub.utils import func # loaded lazily: .sub.utils resolves to mypackage.sub.utils + import json # loaded eagerly (not in __lazy_modules__) + +Imports inside functions, class bodies, or +:keyword:`try`/:keyword:`except`/:keyword:`finally` blocks are always eager, +regardless of :attr:`!__lazy_modules__`. + +.. versionadded:: 3.15 + +.. _future: + +Future statements +----------------- + +.. index:: + pair: future; statement + single: __future__; future statement + +A :dfn:`future statement` is a directive to the compiler that a particular +module should be compiled using syntax or semantics that will be available in a +specified future release of Python where the feature becomes standard. + +The future statement is intended to ease migration to future versions of Python +that introduce incompatible changes to the language. It allows use of the new +features on a per-module basis before the release in which the feature becomes +standard. + +.. productionlist:: python-grammar + future_stmt: "from" "__future__" "import" `feature` ["as" `identifier`] + : ("," `feature` ["as" `identifier`])* + : | "from" "__future__" "import" "(" `feature` ["as" `identifier`] + : ("," `feature` ["as" `identifier`])* [","] ")" + feature: `identifier` + +A future statement must appear near the top of the module. The only lines that +can appear before a future statement are: + +* the module docstring (if any), +* comments, +* blank lines, and +* other future statements. + +The only feature that requires using the future statement is +``annotations`` (see :pep:`563`). + +All historical features enabled by the future statement are still recognized +by Python 3. The list includes ``absolute_import``, ``division``, +``generators``, ``generator_stop``, ``unicode_literals``, +``print_function``, ``nested_scopes`` and ``with_statement``. They are +all redundant because they are always enabled, and only kept for +backwards compatibility. + +A future statement is recognized and treated specially at compile time: Changes +to the semantics of core constructs are often implemented by generating +different code. It may even be the case that a new feature introduces new +incompatible syntax (such as a new reserved word), in which case the compiler +may need to parse the module differently. Such decisions cannot be pushed off +until runtime. + +For any given release, the compiler knows which feature names have been defined, +and raises a compile-time error if a future statement contains a feature not +known to it. + +The direct runtime semantics are the same as for any import statement: there is +a standard module :mod:`__future__`, described later, and it will be imported in +the usual way at the time the future statement is executed. + +The interesting runtime semantics depend on the specific feature enabled by the +future statement. + +Note that there is nothing special about the statement:: + + import __future__ [as name] + +That is not a future statement; it's an ordinary import statement with no +special semantics or syntax restrictions. + +Code compiled by calls to the built-in functions :func:`exec` and :func:`compile` +that occur in a module :mod:`!M` containing a future statement will, by default, +use the new syntax or semantics associated with the future statement. This can +be controlled by optional arguments to :func:`compile` --- see the documentation +of that function for details. + +A future statement typed at an interactive interpreter prompt will take effect +for the rest of the interpreter session. If an interpreter is started with the +:option:`-i` option, is passed a script name to execute, and the script includes +a future statement, it will be in effect in the interactive session started +after the script is executed. + +.. seealso:: + + :pep:`236` - Back to the __future__ + The original proposal for the __future__ mechanism. + + +.. _global: + +The :keyword:`!global` statement +================================ + +.. index:: + ! pair: statement; global + triple: global; name; binding + single: , (comma); identifier list + +.. productionlist:: python-grammar + global_stmt: "global" `identifier` ("," `identifier`)* + +The :keyword:`global` statement causes the listed identifiers to be interpreted +as globals. It would be impossible to assign to a global variable without +:keyword:`!global`, although free variables may refer to globals without being +declared global. + +The :keyword:`!global` statement applies to the entire current scope +(module, function body or class definition). +A :exc:`SyntaxError` is raised if a variable is used or +assigned to prior to its global declaration in the scope. + +At the module level, all variables are global, so a :keyword:`!global` +statement has no effect. +However, variables must still not be used or +assigned to prior to their :keyword:`!global` declaration. +This requirement is relaxed in the interactive prompt (:term:`REPL`). + +.. index:: + pair: built-in function; exec + pair: built-in function; eval + pair: built-in function; compile + +**Programmer's note:** :keyword:`global` is a directive to the parser. It +applies only to code parsed at the same time as the :keyword:`!global` statement. +In particular, a :keyword:`!global` statement contained in a string or code +object supplied to the built-in :func:`exec` function does not affect the code +block *containing* the function call, and code contained in such a string is +unaffected by :keyword:`!global` statements in the code containing the function +call. The same applies to the :func:`eval` and :func:`compile` functions. + + +.. _nonlocal: + +The :keyword:`!nonlocal` statement +================================== + +.. index:: pair: statement; nonlocal + single: , (comma); identifier list + +.. productionlist:: python-grammar + nonlocal_stmt: "nonlocal" `identifier` ("," `identifier`)* + +When the definition of a function or class is nested (enclosed) within +the definitions of other functions, its nonlocal scopes are the local +scopes of the enclosing functions. The :keyword:`nonlocal` statement +causes the listed identifiers to refer to names previously bound in +nonlocal scopes. It allows encapsulated code to rebind such nonlocal +identifiers. If a name is bound in more than one nonlocal scope, the +nearest binding is used. If a name is not bound in any nonlocal scope, +or if there is no nonlocal scope, a :exc:`SyntaxError` is raised. + +The :keyword:`nonlocal` statement applies to the entire scope of a function or +class body. A :exc:`SyntaxError` is raised if a variable is used or +assigned to prior to its nonlocal declaration in the scope. + +.. seealso:: + + :pep:`3104` - Access to Names in Outer Scopes + The specification for the :keyword:`nonlocal` statement. + +**Programmer's note:** :keyword:`nonlocal` is a directive to the parser +and applies only to code parsed along with it. See the note for the +:keyword:`global` statement. + + +.. _type: + +The :keyword:`!type` statement +============================== + +.. index:: pair: statement; type + +.. productionlist:: python-grammar + type_stmt: 'type' `identifier` [`type_params`] "=" `expression` + +The :keyword:`!type` statement declares a type alias, which is an instance +of :class:`typing.TypeAliasType`. + +For example, the following statement creates a type alias:: + + type Point = tuple[float, float] + +This code is roughly equivalent to:: + + annotation-def VALUE_OF_Point(): + return tuple[float, float] + Point = typing.TypeAliasType("Point", VALUE_OF_Point()) + +``annotation-def`` indicates an :ref:`annotation scope <annotation-scopes>`, which behaves +mostly like a function, but with several small differences. + +The value of the +type alias is evaluated in the annotation scope. It is not evaluated when the +type alias is created, but only when the value is accessed through the type alias's +:attr:`!__value__` attribute (see :ref:`lazy-evaluation`). +This allows the type alias to refer to names that are not yet defined. + +Type aliases may be made generic by adding a :ref:`type parameter list <type-params>` +after the name. See :ref:`generic-type-aliases` for more. + +:keyword:`!type` is a :ref:`soft keyword <soft-keywords>`. + +.. versionadded:: 3.12 + +.. seealso:: + + :pep:`695` - Type Parameter Syntax + Introduced the :keyword:`!type` statement and syntax for + generic classes and functions. diff --git a/stdlib/kvlang/reference/python/cpython/Doc/reference/toplevel_components.rst b/stdlib/kvlang/reference/python/cpython/Doc/reference/toplevel_components.rst new file mode 100644 index 00000000..bd64b1c0 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/reference/toplevel_components.rst @@ -0,0 +1,113 @@ + +.. _top-level: + +******************** +Top-level components +******************** + +.. index:: single: interpreter + +The Python interpreter can get its input from a number of sources: from a script +passed to it as standard input or as program argument, typed in interactively, +from a module source file, etc. This chapter gives the syntax used in these +cases. + + +.. _programs: + +Complete Python programs +======================== + +.. index:: single: program + +.. index:: + pair: module; sys + pair: module; __main__ + pair: module; builtins + +While a language specification need not prescribe how the language interpreter +is invoked, it is useful to have a notion of a complete Python program. A +complete Python program is executed in a minimally initialized environment: all +built-in and standard modules are available, but none have been initialized, +except for :mod:`sys` (various system services), :mod:`builtins` (built-in +functions, exceptions and ``None``) and :mod:`__main__`. The latter is used to +provide the local and global namespace for execution of the complete program. + +The syntax for a complete Python program is that for file input, described in +the next section. + +.. index:: + single: interactive mode + pair: module; __main__ + +The interpreter may also be invoked in interactive mode; in this case, it does +not read and execute a complete program but reads and executes one statement +(possibly compound) at a time. The initial environment is identical to that of +a complete program; each statement is executed in the namespace of +:mod:`__main__`. + +.. index:: + single: UNIX + single: Windows + single: command line + single: standard input + +A complete program can be passed to the interpreter +in three forms: with the :option:`-c` *string* command line option, as a file +passed as the first command line argument, or as standard input. If the file +or standard input is a tty device, the interpreter enters interactive mode; +otherwise, it executes the file as a complete program. + + +.. _file-input: + +File input +========== + +All input read from non-interactive files has the same form: + +.. grammar-snippet:: + :group: python-grammar + + file_input: (NEWLINE | `statement`)* ENDMARKER + +This syntax is used in the following situations: + +* when parsing a complete Python program (from a file or from a string); + +* when parsing a module; + +* when parsing a string passed to the :func:`exec` function; + + +.. _interactive: + +Interactive input +================= + +Input in interactive mode is parsed using the following grammar: + +.. grammar-snippet:: + :group: python-grammar + + interactive_input: [`stmt_list`] NEWLINE | `compound_stmt` NEWLINE | ENDMARKER + +Note that a (top-level) compound statement must be followed by a blank line in +interactive mode; this is needed to help the parser detect the end of the input. + + +.. _expression-input: + +Expression input +================ + +.. index:: single: input +.. index:: pair: built-in function; eval + +:func:`eval` is used for expression input. It ignores leading whitespace. The +string argument to :func:`eval` must have the following form: + +.. grammar-snippet:: + :group: python-grammar + + eval_input: `expression_list` NEWLINE* ENDMARKER diff --git a/stdlib/kvlang/reference/python/cpython/Doc/requirements.txt b/stdlib/kvlang/reference/python/cpython/Doc/requirements.txt new file mode 100644 index 00000000..b9072b4a --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Doc/requirements.txt @@ -0,0 +1,24 @@ +# Requirements to build the Python documentation +# +# Note that when updating this file, you will likely also have to update +# the Doc/constraints.txt file. + +# The Sphinx version is pinned so that new versions that introduce new warnings +# won't suddenly cause build failures. Updating the version is fine as long +# as no warnings are raised by doing so. +# Keep this version in sync with ``Doc/conf.py``. +sphinx<9.0.0 + +pygments>=2.21 + +blurb + +sphinx-linklint +sphinx-notfound-page~=1.0.0 +sphinxext-opengraph~=0.13.0 + +# The theme used by the documentation is stored separately, so we need +# to install that as well. +python-docs-theme>=2023.3.1,!=2023.7 + +-c constraints.txt diff --git a/stdlib/kvlang/reference/python/cpython/LICENSE b/stdlib/kvlang/reference/python/cpython/LICENSE new file mode 100644 index 00000000..20cf3909 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/LICENSE @@ -0,0 +1,277 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see https://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations, which became +Zope Corporation. In 2001, the Python Software Foundation (PSF, see +https://www.python.org/psf/) was formed, a non-profit organization +created specifically to own Python-related Intellectual Property. +Zope Corporation was a sponsoring member of the PSF. + +All Python releases are Open Source (see https://opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2 and above 2.1.1 2001-now PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +Python software and documentation are licensed under the +Python Software Foundation License Version 2. + +Starting with Python 3.8.6, examples, recipes, and other code in +the documentation are dual licensed under the PSF License Version 2 +and the Zero-Clause BSD license. + +Some software incorporated into Python is under different licenses. +The licenses are listed with code falling under that license. + + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001 Python Software Foundation; All Rights Reserved" +are retained in Python alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION +---------------------------------------------------------------------- + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/stdlib/kvlang/reference/python/cpython/Makefile.pre.in b/stdlib/kvlang/reference/python/cpython/Makefile.pre.in new file mode 100644 index 00000000..78a48662 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/Makefile.pre.in @@ -0,0 +1,3482 @@ +# Top-level Makefile for Python +# +# As distributed, this file is called Makefile.pre.in; it is processed +# into the real Makefile by running the script ./configure, which +# replaces things like @spam@ with values appropriate for your system. +# This means that if you edit Makefile, your changes get lost the next +# time you run the configure script. Ideally, you can do: +# +# ./configure +# make +# make test +# make install +# +# If you have a previous version of Python installed that you don't +# want to overwrite, you can use "make altinstall" instead of "make +# install". Refer to the "Installing" section in the README file for +# additional details. +# +# See also the section "Build instructions" in the README file. + +# === Variables set by makesetup === + +MODBUILT_NAMES= _MODBUILT_NAMES_ +MODSHARED_NAMES= _MODSHARED_NAMES_ +MODDISABLED_NAMES= _MODDISABLED_NAMES_ +MODOBJS= _MODOBJS_ +MODLIBS= _MODLIBS_ + +# === Variables set by configure +VERSION= @VERSION@ +srcdir= @srcdir@ +VPATH= @srcdir@ +abs_srcdir= @abs_srcdir@ +abs_builddir= @abs_builddir@ + + +CC= @CC@ +CXX= @CXX@ +LINKCC= @LINKCC@ +AR= @AR@ +READELF= @READELF@ +SOABI= @SOABI@ +ABIFLAGS= @ABIFLAGS@ +ABI_THREAD= @ABI_THREAD@ +LDVERSION= @LDVERSION@ +LIBPYTHON=@LIBPYTHON@ +GITVERSION= @GITVERSION@ +GITTAG= @GITTAG@ +GITBRANCH= @GITBRANCH@ +PGO_PROF_GEN_FLAG=@PGO_PROF_GEN_FLAG@ +PGO_PROF_USE_FLAG=@PGO_PROF_USE_FLAG@ +LLVM_PROF_MERGER=@LLVM_PROF_MERGER@ +LLVM_PROF_FILE=@LLVM_PROF_FILE@ +LLVM_PROF_ERR=@LLVM_PROF_ERR@ +DTRACE= @DTRACE@ +DFLAGS= @DFLAGS@ +DTRACE_HEADERS= @DTRACE_HEADERS@ +DTRACE_OBJS= @DTRACE_OBJS@ +DSYMUTIL= @DSYMUTIL@ +DSYMUTIL_PATH= @DSYMUTIL_PATH@ + +GNULD= @GNULD@ + +# Shell used by make (some versions default to the login shell, which is bad) +SHELL= /bin/sh -e + +# Use this to make a link between python$(VERSION) and python in $(BINDIR) +LN= @LN@ + +# Portable install script (configure doesn't always guess right) +INSTALL= @INSTALL@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ +INSTALL_SCRIPT= @INSTALL_SCRIPT@ +INSTALL_DATA= @INSTALL_DATA@ +# Shared libraries must be installed with executable mode on some systems; +# rather than figuring out exactly which, we always give them executable mode. +INSTALL_SHARED= ${INSTALL} -m 755 + +MKDIR_P= @MKDIR_P@ + +MAKESETUP= $(srcdir)/Modules/makesetup + +# Compiler options +OPT= @OPT@ +BASECFLAGS= @BASECFLAGS@ +BASECPPFLAGS= @BASECPPFLAGS@ +CONFIGURE_CFLAGS= @CFLAGS@ +# CFLAGS_NODIST is used for building the interpreter and stdlib C extensions. +# Use it when a compiler flag should _not_ be part of the distutils CFLAGS +# once Python is installed (Issue #21121). +CONFIGURE_CFLAGS_NODIST=@CFLAGS_NODIST@ +# LDFLAGS_NODIST is used in the same manner as CFLAGS_NODIST. +# Use it when a linker flag should _not_ be part of the distutils LDFLAGS +# once Python is installed (bpo-35257) +CONFIGURE_LDFLAGS_NODIST=@LDFLAGS_NODIST@ +# LDFLAGS_NOLTO is an extra flag to disable lto. It is used to speed up building +# of _bootstrap_python and _freeze_module tools, which don't need LTO. +CONFIGURE_LDFLAGS_NOLTO=@LDFLAGS_NOLTO@ +CONFIGURE_CPPFLAGS= @CPPFLAGS@ +CONFIGURE_LDFLAGS= @LDFLAGS@ +# Avoid assigning CFLAGS, LDFLAGS, etc. so users can use them on the +# command line to append to these values without stomping the pre-set +# values. +PY_CFLAGS= $(BASECFLAGS) $(OPT) $(CONFIGURE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) +PY_CFLAGS_NODIST=$(CONFIGURE_CFLAGS_NODIST) $(CFLAGS_NODIST) -I$(srcdir)/Include/internal -I$(srcdir)/Include/internal/mimalloc +# Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to +# be able to build extension modules using the directories specified in the +# environment variables +PY_CPPFLAGS= $(BASECPPFLAGS) -I. -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS) +PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS) +PY_LDFLAGS_NODIST=$(CONFIGURE_LDFLAGS_NODIST) $(LDFLAGS_NODIST) +PY_LDFLAGS_NOLTO=$(PY_LDFLAGS) $(CONFIGURE_LDFLAGS_NOLTO) $(LDFLAGS_NODIST) +NO_AS_NEEDED= @NO_AS_NEEDED@ +CCSHARED= @CCSHARED@ +# LINKFORSHARED are the flags passed to the $(CC) command that links +# the python executable -- this is only needed for a few systems +LINKFORSHARED= @LINKFORSHARED@ +ARFLAGS= @ARFLAGS@ +# Extra C flags added for building the interpreter object files. +CFLAGSFORSHARED=@CFLAGSFORSHARED@ +# C flags used for building the interpreter object files +PY_STDMODULE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED) +PY_BUILTIN_MODULE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE_BUILTIN +PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE +# Linker flags used for building the interpreter object files +# In particular, EXE_LDFLAGS is an extra flag to provide fine grain distinction between +# LDFLAGS used to build executables and shared targets. +PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST) +CONFIGURE_EXE_LDFLAGS=@EXE_LDFLAGS@ +PY_CORE_EXE_LDFLAGS:= $(if $(CONFIGURE_EXE_LDFLAGS), $(CONFIGURE_EXE_LDFLAGS) $(PY_LDFLAGS_NODIST), $(PY_CORE_LDFLAGS)) +# Strict or non-strict aliasing flags used to compile dtoa.c, see above +CFLAGS_ALIASING=@CFLAGS_ALIASING@ +# Compilation flags only for ceval.c. +CFLAGS_CEVAL=@CFLAGS_CEVAL@ + + +# Machine-dependent subdirectories +MACHDEP= @MACHDEP@ + +# Multiarch directory (may be empty) +MULTIARCH= @MULTIARCH@ +MULTIARCH_CPPFLAGS = @MULTIARCH_CPPFLAGS@ + +# Install prefix for architecture-independent files +prefix= @prefix@ + +# Install prefix for architecture-dependent files +exec_prefix= @exec_prefix@ + +# For cross compilation, we distinguish between "prefix" (where we install the +# files) and "host_prefix" (where getpath.c expects to find the files at +# runtime) +host_prefix= @host_prefix@ +host_exec_prefix= @host_exec_prefix@ + + +# Install prefix for data files +datarootdir= @datarootdir@ + +# Expanded directories +BINDIR= @bindir@ +LIBDIR= @libdir@ +MANDIR= @mandir@ +INCLUDEDIR= @includedir@ +CONFINCLUDEDIR= $(exec_prefix)/include +PLATLIBDIR= @PLATLIBDIR@ +SCRIPTDIR= $(prefix)/$(PLATLIBDIR) +# executable name for shebangs +EXENAME= $(BINDIR)/python$(LDVERSION)$(EXE) +# Variable used by ensurepip +WHEEL_PKG_DIR= @WHEEL_PKG_DIR@ + +# Detailed destination directories +BINLIBDEST= @BINLIBDEST@ +LIBDEST= @LIBDEST@ +INCLUDEPY= $(INCLUDEDIR)/python$(LDVERSION) +CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(LDVERSION) + +# Symbols used for using shared libraries +SHLIB_SUFFIX= @SHLIB_SUFFIX@ +EXT_SUFFIX= @EXT_SUFFIX@ +LDSHARED= @LDSHARED@ $(PY_LDFLAGS) +BLDSHARED= @BLDSHARED@ $(PY_CORE_LDFLAGS) +LDCXXSHARED= @LDCXXSHARED@ $(PY_LDFLAGS) +DESTSHARED= $(BINLIBDEST)/lib-dynload + +# List of exported symbols for AIX +EXPORTSYMS= @EXPORTSYMS@ +EXPORTSFROM= @EXPORTSFROM@ + +# Executable suffix (.exe on Windows and Mac OS X) +EXE= @EXEEXT@ +BUILDEXE= @BUILDEXEEXT@ + +# Name of the patch file to apply for app store compliance +APP_STORE_COMPLIANCE_PATCH=@APP_STORE_COMPLIANCE_PATCH@ + +# Short name and location for Mac OS X Python framework +UNIVERSALSDK=@UNIVERSALSDK@ +PYTHONFRAMEWORK= @PYTHONFRAMEWORK@ +PYTHONFRAMEWORKDIR= @PYTHONFRAMEWORKDIR@ +PYTHONFRAMEWORKPREFIX= @PYTHONFRAMEWORKPREFIX@ +PYTHONFRAMEWORKINSTALLDIR= @PYTHONFRAMEWORKINSTALLDIR@ +PYTHONFRAMEWORKINSTALLNAMEPREFIX= @PYTHONFRAMEWORKINSTALLNAMEPREFIX@ +RESSRCDIR= @RESSRCDIR@ +# macOS deployment target selected during configure, to be checked +# by distutils. The export statement is needed to ensure that the +# deployment target is active during build. +MACOSX_DEPLOYMENT_TARGET=@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@ +@EXPORT_MACOSX_DEPLOYMENT_TARGET@export MACOSX_DEPLOYMENT_TARGET + +# iOS Deployment target selected during configure. Unlike macOS, the iOS +# deployment target is controlled using `-mios-version-min` arguments added to +# CFLAGS and LDFLAGS by the configure script. This variable is not used during +# the build, and is only listed here so it will be included in sysconfigdata. +IPHONEOS_DEPLOYMENT_TARGET=@IPHONEOS_DEPLOYMENT_TARGET@ + +BUILD_DETAILS=@BUILD_DETAILS@ + +# Option to install to strip binaries +STRIPFLAG=-s + +# Flags to lipo to produce a 32-bit-only universal executable +LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@ + +# Flags to lipo to produce an intel-64-only universal executable +LIPO_INTEL64_FLAGS=@LIPO_INTEL64_FLAGS@ + +# Environment to run shared python without installed libraries +RUNSHARED= @RUNSHARED@ + +# ensurepip options +ENSUREPIP= @ENSUREPIP@ + +# Internal static libraries +LIBEXPAT_A= Modules/expat/libexpat.a + +# HACL* build configuration +LIBHACL_CFLAGS=@LIBHACL_CFLAGS@ +LIBHACL_LDFLAGS=@LIBHACL_LDFLAGS@ +LIBHACL_BLAKE2_SIMD128_CFLAGS=@LIBHACL_SIMD128_FLAGS@ -DHACL_CAN_COMPILE_VEC128 +LIBHACL_BLAKE2_SIMD256_CFLAGS=@LIBHACL_SIMD256_FLAGS@ -DHACL_CAN_COMPILE_VEC256 + +# Module state, compiler flags and linker flags +# Empty CFLAGS and LDFLAGS are omitted. +# states: +# * yes: module is available +# * missing: build dependency is missing +# * disabled: module is disabled +# * n/a: module is not available on the current platform +# MODULE_EGG_STATE=yes # yes, missing, disabled, n/a +# MODULE_EGG_CFLAGS= +# MODULE_EGG_LDFLAGS= +@MODULE_BLOCK@ + +# Default zoneinfo.TZPATH. Added here to expose it in sysconfig.get_config_var +TZPATH=@TZPATH@ + +# If to install mimalloc headers +INSTALL_MIMALLOC=@INSTALL_MIMALLOC@ + +# Modes for directories, executables and data files created by the +# install process. Default to user-only-writable for all file types. +DIRMODE= 755 +EXEMODE= 755 +FILEMODE= 644 + +# configure script arguments +CONFIG_ARGS= @CONFIG_ARGS@ + + +# Subdirectories with code +SRCDIRS= @SRCDIRS@ + +# Other subdirectories +SUBDIRSTOO= Include Lib Misc + +# Files and directories to be distributed +CONFIGFILES= configure configure.ac acconfig.h pyconfig.h.in Makefile.pre.in +DISTFILES= README.rst ChangeLog $(CONFIGFILES) +DISTDIRS= $(SUBDIRS) $(SUBDIRSTOO) Ext-dummy +DIST= $(DISTFILES) $(DISTDIRS) + + +LIBRARY= @LIBRARY@ +LDLIBRARY= @LDLIBRARY@ +BLDLIBRARY= @BLDLIBRARY@ +MODULE_LDFLAGS_SHARED=$(if $(LIBPYTHON),$(BLDLIBRARY)) +PY3LIBRARY= @PY3LIBRARY@ +DLLLIBRARY= @DLLLIBRARY@ +LDLIBRARYDIR= @LDLIBRARYDIR@ +INSTSONAME= @INSTSONAME@ +LIBRARY_DEPS= @LIBRARY_DEPS@ +LINK_PYTHON_DEPS=@LINK_PYTHON_DEPS@ +JIT_OBJS= @JIT_SHIM_O@ +PY_ENABLE_SHARED= @PY_ENABLE_SHARED@ +STATIC_LIBPYTHON= @STATIC_LIBPYTHON@ + + +LIBS= @LIBS@ +LIBM= @LIBM@ +LIBC= @LIBC@ +SYSLIBS= $(LIBM) $(LIBC) +SHLIBS= @SHLIBS@ + +DLINCLDIR= @DLINCLDIR@ +DYNLOADFILE= @DYNLOADFILE@ +MACHDEP_OBJS= @MACHDEP_OBJS@ +LIBOBJDIR= Python/ +LIBOBJS= @LIBOBJS@ + +PYTHON= python$(EXE) +BUILDPYTHON= python$(BUILDEXE) + +HOSTRUNNER= @HOSTRUNNER@ + +PYTHON_FOR_REGEN?=@PYTHON_FOR_REGEN@ +UPDATE_FILE=$(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/update_file.py +PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@ +# Single-platform builds depend on $(BUILDPYTHON). Cross builds use an +# external "build Python" and have an empty PYTHON_FOR_BUILD_DEPS. +PYTHON_FOR_BUILD_DEPS=@PYTHON_FOR_BUILD_DEPS@ + +# Single-platform builds use Programs/_freeze_module.c for bootstrapping and +# ./_bootstrap_python Programs/_freeze_module.py for remaining modules +# Cross builds use an external "build Python" for all modules. +PYTHON_FOR_FREEZE=@PYTHON_FOR_FREEZE@ +FREEZE_MODULE_BOOTSTRAP=@FREEZE_MODULE_BOOTSTRAP@ +FREEZE_MODULE_BOOTSTRAP_DEPS=@FREEZE_MODULE_BOOTSTRAP_DEPS@ +FREEZE_MODULE=@FREEZE_MODULE@ +FREEZE_MODULE_DEPS=@FREEZE_MODULE_DEPS@ + +_PYTHON_HOST_PLATFORM=@_PYTHON_HOST_PLATFORM@ +BUILD_GNU_TYPE= @build@ +HOST_GNU_TYPE= @host@ + +# The task to run while instrumented when building the profile-opt target. +# To speed up profile generation, we don't run the full unit test suite +# by default. The default is "-m test --pgo". To run more tests, use +# PROFILE_TASK="-m test --pgo-extended" +PROFILE_TASK= @PROFILE_TASK@ + +# report files for gcov / lcov coverage report +COVERAGE_INFO= $(abs_builddir)/coverage.info +COVERAGE_REPORT=$(abs_builddir)/lcov-report +COVERAGE_LCOV_OPTIONS=--rc lcov_branch_coverage=1 +COVERAGE_REPORT_OPTIONS=--rc lcov_branch_coverage=1 --branch-coverage --title "CPython $(VERSION) LCOV report [commit $(shell $(GITVERSION))]" + + +# === Definitions added by makesetup === + + +########################################################################## +# Modules +MODULE_OBJS= \ + Modules/config.o \ + Modules/main.o \ + Modules/gcmodule.o + +IO_H= Modules/_io/_iomodule.h + +IO_OBJS= \ + Modules/_io/_iomodule.o \ + Modules/_io/iobase.o \ + Modules/_io/fileio.o \ + Modules/_io/bufferedio.o \ + Modules/_io/textio.o \ + Modules/_io/bytesio.o \ + Modules/_io/stringio.o + + +########################################################################## +# mimalloc + +MIMALLOC_HEADERS= \ + $(srcdir)/Include/internal/pycore_mimalloc.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/atomic.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/internal.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/prim.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/track.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/types.h + + +########################################################################## +# Parser + +PEGEN_OBJS= \ + Parser/pegen.o \ + Parser/pegen_errors.o \ + Parser/action_helpers.o \ + Parser/parser.o \ + Parser/string_parser.o \ + Parser/peg_api.o + +TOKENIZER_OBJS= \ + Parser/lexer/buffer.o \ + Parser/lexer/lexer.o \ + Parser/lexer/number.o \ + Parser/lexer/state.o \ + Parser/lexer/string.o \ + Parser/tokenizer/cursor.o \ + Parser/tokenizer/decoder.o \ + Parser/tokenizer/reader.o \ + Parser/tokenizer/source.o \ + Parser/tokenizer/helpers.o + +PEGEN_HEADERS= \ + $(srcdir)/Include/internal/pycore_parser.h \ + $(srcdir)/Parser/pegen.h \ + $(srcdir)/Parser/string_parser.h + +TOKENIZER_HEADERS= \ + Parser/lexer/buffer.h \ + Parser/lexer/lexer.h \ + Parser/lexer/lexer_internal.h \ + Parser/lexer/state.h \ + Parser/tokenizer/cursor.h \ + Parser/tokenizer/reader.h \ + Parser/tokenizer/reader_internal.h \ + Parser/tokenizer/source.h \ + Parser/tokenizer/tokenizer.h \ + Parser/tokenizer/helpers.h + +POBJS= \ + Parser/token.o \ + +PARSER_OBJS= $(POBJS) $(PEGEN_OBJS) $(TOKENIZER_OBJS) Parser/myreadline.o + +PARSER_HEADERS= \ + $(PEGEN_HEADERS) \ + $(TOKENIZER_HEADERS) + +########################################################################## +# Python + +PYTHON_OBJS= \ + Python/_contextvars.o \ + Python/_warnings.o \ + Python/Python-ast.o \ + Python/Python-tokenize.o \ + Python/asdl.o \ + Python/assemble.o \ + Python/ast.o \ + Python/ast_preprocess.o \ + Python/ast_unparse.o \ + Python/bltinmodule.o \ + Python/brc.o \ + Python/ceval.o \ + Python/codecs.o \ + Python/codegen.o \ + Python/compile.o \ + Python/context.o \ + Python/critical_section.o \ + Python/crossinterp.o \ + Python/dynamic_annotations.o \ + Python/errors.o \ + Python/flowgraph.o \ + Python/frame.o \ + Python/frozenmain.o \ + Python/future.o \ + Python/gc.o \ + Python/gc_free_threading.o \ + Python/gc_gil.o \ + Python/getargs.o \ + Python/getcompiler.o \ + Python/getcopyright.o \ + Python/getplatform.o \ + Python/getversion.o \ + Python/ceval_gil.o \ + Python/hamt.o \ + Python/hashtable.o \ + Python/import.o \ + Python/importdl.o \ + Python/index_pool.o \ + Python/initconfig.o \ + Python/interpconfig.o \ + Python/instrumentation.o \ + Python/instruction_sequence.o \ + Python/intrinsics.o \ + Python/jit.o \ + Python/jit_publish.o \ + $(JIT_OBJS) \ + Python/legacy_tracing.o \ + Python/lock.o \ + Python/marshal.o \ + Python/modsupport.o \ + Python/mysnprintf.o \ + Python/mystrtoul.o \ + Python/object_stack.o \ + Python/optimizer.o \ + Python/optimizer_analysis.o \ + Python/optimizer_symbols.o \ + Python/parking_lot.o \ + Python/pathconfig.o \ + Python/preconfig.o \ + Python/pyarena.o \ + Python/pyctype.o \ + Python/pyfpe.o \ + Python/pyhash.o \ + Python/pylifecycle.o \ + Python/pymath.o \ + Python/pystate.o \ + Python/pystats.o \ + Python/pythonrun.o \ + Python/pytime.o \ + Python/qsbr.o \ + Python/bootstrap_hash.o \ + Python/specialize.o \ + Python/slots.o \ + Python/slots_generated.o \ + Python/stackrefs.o \ + Python/structmember.o \ + Python/symtable.o \ + Python/sysmodule.o \ + Python/thread.o \ + Python/traceback.o \ + Python/tracemalloc.o \ + Python/typecache.o \ + Python/uniqueid.o \ + Python/getopt.o \ + Python/pystrcmp.o \ + Python/pystrtod.o \ + Python/pystrhex.o \ + Python/dtoa.o \ + Python/fileutils.o \ + Python/suggestions.o \ + Python/perf_trampoline.o \ + Python/perf_jit_trampoline.o \ + Python/jit_unwind.o \ + Python/remote_debugging.o \ + Python/$(DYNLOADFILE) \ + $(LIBOBJS) \ + $(MACHDEP_OBJS) \ + $(DTRACE_OBJS) \ + @PLATFORM_OBJS@ + + +########################################################################## +# Objects +OBJECT_OBJS= \ + Objects/abstract.o \ + Objects/boolobject.o \ + Objects/bytes_methods.o \ + Objects/bytearrayobject.o \ + Objects/bytesobject.o \ + Objects/call.o \ + Objects/capsule.o \ + Objects/cellobject.o \ + Objects/classobject.o \ + Objects/codeobject.o \ + Objects/complexobject.o \ + Objects/descrobject.o \ + Objects/enumobject.o \ + Objects/exceptions.o \ + Objects/genericaliasobject.o \ + Objects/genobject.o \ + Objects/fileobject.o \ + Objects/floatobject.o \ + Objects/frameobject.o \ + Objects/funcobject.o \ + Objects/interpolationobject.o \ + Objects/iterobject.o \ + Objects/lazyimportobject.o \ + Objects/listobject.o \ + Objects/longobject.o \ + Objects/dictobject.o \ + Objects/odictobject.o \ + Objects/memoryobject.o \ + Objects/methodobject.o \ + Objects/moduleobject.o \ + Objects/namespaceobject.o \ + Objects/object.o \ + Objects/obmalloc.o \ + Objects/picklebufobject.o \ + Objects/rangeobject.o \ + Objects/sentinelobject.o \ + Objects/setobject.o \ + Objects/sliceobject.o \ + Objects/structseq.o \ + Objects/templateobject.o \ + Objects/tupleobject.o \ + Objects/typeobject.o \ + Objects/typevarobject.o \ + Objects/unicode_format.o \ + Objects/unicode_formatter.o \ + Objects/unicode_writer.o \ + Objects/unicodectype.o \ + Objects/unicodeobject.o \ + Objects/unionobject.o \ + Objects/weakrefobject.o \ + @PERF_TRAMPOLINE_OBJ@ + +########################################################################## +# objects that get linked into the Python library +LIBRARY_OBJS_OMIT_FROZEN= \ + Modules/getbuildinfo.o \ + $(PARSER_OBJS) \ + $(OBJECT_OBJS) \ + $(PYTHON_OBJS) \ + $(MODULE_OBJS) \ + $(MODOBJS) + +LIBRARY_OBJS= \ + $(LIBRARY_OBJS_OMIT_FROZEN) \ + Modules/getpath.o \ + Python/frozen.o + +LINK_PYTHON_OBJS=@LINK_PYTHON_OBJS@ + +########################################################################## +# DTrace + +# On some systems, object files that reference DTrace probes need to be modified +# in-place by dtrace(1). +DTRACE_DEPS = \ + Python/ceval.o Python/gc.o Python/import.o Python/sysmodule.o + +########################################################################## +# pyexpat's expat library + +LIBEXPAT_OBJS= \ + Modules/expat/xmlparse.o \ + Modules/expat/xmlrole.o \ + Modules/expat/xmltok.o + +LIBEXPAT_HEADERS= \ + Modules/expat/ascii.h \ + Modules/expat/asciitab.h \ + Modules/expat/expat.h \ + Modules/expat/expat_config.h \ + Modules/expat/expat_external.h \ + Modules/expat/fallthrough.h \ + Modules/expat/iasciitab.h \ + Modules/expat/internal.h \ + Modules/expat/latin1tab.h \ + Modules/expat/memory_sanitizer.h \ + Modules/expat/nametab.h \ + Modules/expat/pyexpatns.h \ + Modules/expat/siphash.h \ + Modules/expat/utf8tab.h \ + Modules/expat/xcsinc.c \ + Modules/expat/xmlrole.h \ + Modules/expat/xmltok.h \ + Modules/expat/xmltok_impl.h \ + Modules/expat/xmltok_impl.c \ + Modules/expat/xmltok_ns.c + +########################################################################## +# hashlib's HACL* library +# +# On WASI, static build is required. +# On other platforms, a shared library is used. + +LIBHACL_MD5_OBJS= \ + Modules/_hacl/Hacl_Hash_MD5.o +LIBHACL_MD5_LIB_STATIC=Modules/_hacl/libHacl_Hash_MD5.a +LIBHACL_MD5_LIB_SHARED=$(LIBHACL_MD5_OBJS) + +LIBHACL_SHA1_OBJS= \ + Modules/_hacl/Hacl_Hash_SHA1.o +LIBHACL_SHA1_LIB_STATIC=Modules/_hacl/libHacl_Hash_SHA1.a +LIBHACL_SHA1_LIB_SHARED=$(LIBHACL_SHA1_OBJS) + +LIBHACL_SHA2_OBJS= \ + Modules/_hacl/Hacl_Hash_SHA2.o +LIBHACL_SHA2_LIB_STATIC=Modules/_hacl/libHacl_Hash_SHA2.a +LIBHACL_SHA2_LIB_SHARED=$(LIBHACL_SHA2_OBJS) + +LIBHACL_SHA3_OBJS= \ + Modules/_hacl/Hacl_Hash_SHA3.o +LIBHACL_SHA3_LIB_STATIC=Modules/_hacl/libHacl_Hash_SHA3.a +LIBHACL_SHA3_LIB_SHARED=$(LIBHACL_SHA3_OBJS) + +LIBHACL_BLAKE2_SIMD128_OBJS=@LIBHACL_BLAKE2_SIMD128_OBJS@ +LIBHACL_BLAKE2_SIMD256_OBJS=@LIBHACL_BLAKE2_SIMD256_OBJS@ +LIBHACL_BLAKE2_OBJS= \ + Modules/_hacl/Hacl_Hash_Blake2s.o \ + Modules/_hacl/Hacl_Hash_Blake2b.o \ + Modules/_hacl/Lib_Memzero0.o \ + $(LIBHACL_BLAKE2_SIMD128_OBJS) \ + $(LIBHACL_BLAKE2_SIMD256_OBJS) +LIBHACL_BLAKE2_LIB_STATIC=Modules/_hacl/libHacl_Hash_BLAKE2.a +LIBHACL_BLAKE2_LIB_SHARED=$(LIBHACL_BLAKE2_OBJS) + +LIBHACL_HMAC_OBJS= \ + Modules/_hacl/Hacl_HMAC.o \ + Modules/_hacl/Hacl_Streaming_HMAC.o \ + $(LIBHACL_MD5_OBJS) \ + $(LIBHACL_SHA1_OBJS) \ + $(LIBHACL_SHA2_OBJS) \ + $(LIBHACL_SHA3_OBJS) \ + $(LIBHACL_BLAKE2_OBJS) +LIBHACL_HMAC_LIB_STATIC=Modules/_hacl/libHacl_HMAC.a +LIBHACL_HMAC_LIB_SHARED=$(LIBHACL_HMAC_OBJS) + +LIBHACL_HEADERS= \ + Modules/_hacl/include/krml/FStar_UInt128_Verified.h \ + Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h \ + Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h \ + Modules/_hacl/include/krml/internal/compat.h \ + Modules/_hacl/include/krml/internal/target.h \ + Modules/_hacl/include/krml/internal/types.h \ + Modules/_hacl/include/krml/lowstar_endianness.h \ + Modules/_hacl/Hacl_Streaming_Types.h \ + Modules/_hacl/internal/Hacl_Streaming_Types.h \ + Modules/_hacl/libintvector.h \ + Modules/_hacl/python_hacl_namespaces.h + +LIBHACL_MD5_HEADERS= \ + Modules/_hacl/Hacl_Hash_MD5.h \ + Modules/_hacl/internal/Hacl_Hash_MD5.h \ + $(LIBHACL_HEADERS) + +LIBHACL_SHA1_HEADERS= \ + Modules/_hacl/Hacl_Hash_SHA1.h \ + Modules/_hacl/internal/Hacl_Hash_SHA1.h \ + $(LIBHACL_HEADERS) + +LIBHACL_SHA2_HEADERS= \ + Modules/_hacl/Hacl_Hash_SHA2.h \ + Modules/_hacl/internal/Hacl_Hash_SHA2.h \ + $(LIBHACL_HEADERS) + +LIBHACL_SHA3_HEADERS= \ + Modules/_hacl/Hacl_Hash_SHA3.h \ + Modules/_hacl/internal/Hacl_Hash_SHA3.h \ + $(LIBHACL_HEADERS) + +LIBHACL_BLAKE2_HEADERS= \ + Modules/_hacl/Hacl_Hash_Blake2b.h \ + Modules/_hacl/Hacl_Hash_Blake2s.h \ + Modules/_hacl/Hacl_Hash_Blake2s_Simd128.h \ + Modules/_hacl/Hacl_Hash_Blake2b_Simd256.h \ + Modules/_hacl/internal/Hacl_Hash_Blake2b.h \ + Modules/_hacl/internal/Hacl_Hash_Blake2s.h \ + Modules/_hacl/internal/Hacl_Impl_Blake2_Constants.h \ + Modules/_hacl/internal/Hacl_Hash_Blake2s_Simd128.h \ + Modules/_hacl/internal/Hacl_Hash_Blake2b_Simd256.h \ + $(LIBHACL_HEADERS) + +LIBHACL_HMAC_HEADERS= \ + Modules/_hacl/Hacl_HMAC.h \ + Modules/_hacl/Hacl_Streaming_HMAC.h \ + Modules/_hacl/internal/Hacl_HMAC.h \ + Modules/_hacl/internal/Hacl_Streaming_HMAC.h \ + Modules/_hacl/libintvector-shim.h \ + $(LIBHACL_MD5_HEADERS) \ + $(LIBHACL_SHA1_HEADERS) \ + $(LIBHACL_SHA2_HEADERS) \ + $(LIBHACL_SHA3_HEADERS) \ + $(LIBHACL_BLAKE2_HEADERS) \ + $(LIBHACL_HEADERS) + +######################################################################### +# Rules + +# Default target +all: @DEF_MAKE_ALL_RULE@ + +# First target in Makefile is implicit default. So .PHONY needs to come after +# all. +.PHONY: all + +# Provide quick help for common Makefile targets. +.PHONY: help +help: + @echo "Run 'make' to build the Python executable and extension modules" + @echo "" + @echo "or 'make <target>' where <target> is one of:" + @echo " test run the test suite" + @echo " install install built files" + @echo " regen-all regenerate a number of generated source files" + @echo " clinic run Argument Clinic over source files" + @echo "" + @echo " clean to remove build files" + @echo " distclean 'clean' + remove other generated files (patch, exe, etc)" + @echo "" + @echo " recheck rerun configure with last cmdline options" + @echo " reindent reindent .py files in Lib directory" + @echo " tags build a tags file (useful for Emacs and other editors)" + @echo " list-targets list all targets in the Makefile" + +# Display a full list of Makefile targets +.PHONY: list-targets +list-targets: + @grep -E '^[A-Za-z][-A-Za-z0-9]+:' Makefile | awk -F : '{print $$1}' + +.PHONY: build_all +build_all: check-clean-src check-app-store-compliance $(BUILDPYTHON) platform sharedmods \ + gdbhooks Programs/_testembed scripts checksharedmods rundsymutil $(BUILD_DETAILS) + +.PHONY: build_wasm +build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \ + python-config checksharedmods $(BUILD_DETAILS) + +.PHONY: build_emscripten +build_emscripten: build_wasm web_example web_example_pyrepl_jspi + +# Check that the source is clean when building out of source. +.PHONY: check-clean-src +check-clean-src: + @if test -n "$(VPATH)" -a \( \ + -f "$(srcdir)/$(BUILDPYTHON)" \ + -o -f "$(srcdir)/Programs/python.o" \ + -o -f "$(srcdir)/Python/frozen_modules/importlib._bootstrap.h" \ + \); then \ + echo "Error: The source directory ($(srcdir)) is not clean" ; \ + echo "Building Python out of the source tree (in $(abs_builddir)) requires a clean source tree ($(abs_srcdir))" ; \ + echo "Build artifacts such as .o files, executables, and Python/frozen_modules/*.h must not exist within $(srcdir)." ; \ + echo "Try to run:" ; \ + echo " (cd \"$(srcdir)\" && make distclean || git clean -fdx -e Doc/venv)" ; \ + exit 1; \ + fi + +# Check that the app store compliance patch can be applied (if configured). +# This is checked as a dry-run against the original library sources; +# the patch will be actually applied during the install phase. +.PHONY: check-app-store-compliance +check-app-store-compliance: + @if [ "$(APP_STORE_COMPLIANCE_PATCH)" != "" ]; then \ + patch --dry-run --quiet --force --strip 1 --directory "$(abs_srcdir)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)"; \ + echo "App store compliance patch can be applied."; \ + fi + +# Profile generation build must start from a clean tree. +profile-clean-stamp: + $(MAKE) clean-profile + touch $@ + +# Compile with profile generation enabled. +profile-gen-stamp: profile-clean-stamp + @if [ $(LLVM_PROF_ERR) = yes ]; then \ + echo "Error: Cannot perform PGO build because llvm-profdata was not found in PATH" ;\ + echo "Please add it to PATH and run ./configure again" ;\ + exit 1;\ + fi + @echo "Building with support for profile generation:" + $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LIBS="$(LIBS)" + touch $@ + +# Run task with profile generation build to create profile information. +profile-run-stamp: + @echo "Running code to generate profile data (this can take a while):" + # First, we need to create a clean build with profile generation + # enabled. + $(MAKE) profile-gen-stamp + # Next, run the profile task to generate the profile information. + @ # FIXME: can't run for a cross build + $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) + $(LLVM_PROF_MERGER) + # Remove profile generation binary since we are done with it. + $(MAKE) clean-retain-profile + # This is an expensive target to build and it does not have proper + # makefile dependency information. So, we create a "stamp" file + # to record its completion and avoid re-running it. + touch $@ + +# Compile Python binary with profile guided optimization. +# To force re-running of the profile task, remove the profile-run-stamp file. +.PHONY: profile-opt +profile-opt: profile-run-stamp + @echo "Rebuilding with profile guided optimizations:" + -rm -f profile-clean-stamp + $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST)" + +# List of binaries that BOLT runs on. +BOLT_BINARIES := @BOLT_BINARIES@ + +BOLT_INSTRUMENT_FLAGS := @BOLT_INSTRUMENT_FLAGS@ +BOLT_APPLY_FLAGS := @BOLT_APPLY_FLAGS@ + +.PHONY: clean-bolt +clean-bolt: + # Profile data. + rm -f *.fdata + # Pristine binaries before BOLT optimization. + rm -f *.prebolt + # BOLT instrumented binaries. + rm -f *.bolt_inst + +profile-bolt-stamp: $(BUILDPYTHON) + # Ensure a pristine, pre-BOLT copy of the binary and no profile data from last run. + for bin in $(BOLT_BINARIES); do \ + prebolt="$${bin}.prebolt"; \ + if [ -e "$${prebolt}" ]; then \ + echo "Restoring pre-BOLT binary $${prebolt}"; \ + mv "$${bin}.prebolt" "$${bin}"; \ + fi; \ + cp "$${bin}" "$${prebolt}"; \ + rm -f $${bin}.bolt.*.fdata $${bin}.fdata; \ + done + # Instrument each binary. + for bin in $(BOLT_BINARIES); do \ + @LLVM_BOLT@ "$${bin}" -instrument -instrumentation-file-append-pid -instrumentation-file=$(abspath $${bin}.bolt) -o $${bin}.bolt_inst $(BOLT_INSTRUMENT_FLAGS); \ + mv "$${bin}.bolt_inst" "$${bin}"; \ + done + # Run instrumented binaries to collect data. + $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) + # Merge all the data files together. + for bin in $(BOLT_BINARIES); do \ + @MERGE_FDATA@ $${bin}.*.fdata > "$${bin}.fdata"; \ + rm -f $${bin}.*.fdata; \ + done + # Run bolt against the merged data to produce an optimized binary. + for bin in $(BOLT_BINARIES); do \ + @LLVM_BOLT@ "$${bin}.prebolt" -o "$${bin}.bolt" -data="$${bin}.fdata" $(BOLT_APPLY_FLAGS); \ + mv "$${bin}.bolt" "$${bin}"; \ + done + touch $@ + +.PHONY: bolt-opt +bolt-opt: + $(MAKE) @PREBOLT_RULE@ + $(MAKE) profile-bolt-stamp + +# Compile and run with gcov +.PHONY: coverage +coverage: + @echo "Building with support for coverage checking:" + $(MAKE) clean + $(MAKE) @DEF_MAKE_RULE@ CFLAGS="$(CFLAGS) -O0 -pg --coverage" LDFLAGS="$(LDFLAGS) --coverage" + +.PHONY: coverage-lcov +coverage-lcov: + @echo "Creating Coverage HTML report with LCOV:" + @rm -f $(COVERAGE_INFO) + @rm -rf $(COVERAGE_REPORT) + @lcov $(COVERAGE_LCOV_OPTIONS) --capture \ + --directory $(abs_builddir) \ + --base-directory $(realpath $(abs_builddir)) \ + --path $(realpath $(abs_srcdir)) \ + --output-file $(COVERAGE_INFO) + @ # remove 3rd party modules, system headers and internal files with + @ # debug, test or dummy functions. + @lcov $(COVERAGE_LCOV_OPTIONS) --remove $(COVERAGE_INFO) \ + '*/Modules/_hacl/*' \ + '*/Modules/_ctypes/libffi*/*' \ + '*/Modules/expat/*' \ + '*/Modules/xx*.c' \ + '*/Python/pyfpe.c' \ + '*/Python/pystrcmp.c' \ + '/usr/include/*' \ + '/usr/local/include/*' \ + '/usr/lib/gcc/*' \ + --output-file $(COVERAGE_INFO) + @genhtml $(COVERAGE_INFO) \ + --output-directory $(COVERAGE_REPORT) \ + $(COVERAGE_REPORT_OPTIONS) + @echo + @echo "lcov report at $(COVERAGE_REPORT)/index.html" + @echo + +# Force regeneration of parser and frozen modules +.PHONY: coverage-report +coverage-report: regen-token regen-frozen + @ # build with coverage info + $(MAKE) coverage + @ # run tests, ignore failures + $(TESTRUNNER) --fast-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) || true + @ # build lcov report + $(MAKE) coverage-lcov + +# Run "Argument Clinic" over all source files +.PHONY: clinic +clinic: check-clean-src + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --force --make --exclude Lib/test/clinic.test.c --srcdir $(srcdir) + +.PHONY: clinic-tests +clinic-tests: check-clean-src $(srcdir)/Lib/test/clinic.test.c + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py -f $(srcdir)/Lib/test/clinic.test.c + +# Build the interpreter +$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) + $(LINKCC) $(PY_CORE_EXE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) + +platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt + $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform + +# Create build directory and generate the sysconfig build-time data there. +# pybuilddir.txt contains the name of the build dir and is used for +# sys.path fixup -- see Modules/getpath.c. +# Since this step runs before shared modules are built, try to avoid bootstrap +# problems by creating a dummy pybuilddir.txt just to allow interpreter +# initialization to succeed. It will be overwritten by generate-posix-vars +# or removed in case of failure. +pybuilddir.txt: $(PYTHON_FOR_BUILD_DEPS) + @echo "none" > ./pybuilddir.txt + $(RUNSHARED) $(PYTHON_FOR_BUILD) -S -X pathconfig_warnings=0 -m sysconfig --generate-posix-vars ;\ + if test $$? -ne 0 ; then \ + echo "generate-posix-vars failed" ; \ + rm -f ./pybuilddir.txt ; \ + exit 1 ; \ + fi + +$(BUILD_DETAILS): pybuilddir.txt + $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/generate-build-details.py `cat pybuilddir.txt`/$(BUILD_DETAILS) + +# Build static library +$(LIBRARY): $(LIBRARY_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBRARY_OBJS) + +libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACE_OBJS) + # AIX Linker don't support "-h" option + if test "$(MACHDEP)" != "aix"; then \ + $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM); \ + else \ + $(BLDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM); \ + fi + if test $(INSTSONAME) != $@; then \ + $(LN) -f $(INSTSONAME) $@; \ + fi + +libpython3.so: libpython$(LDVERSION).so + $(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^ + +libpython$(LDVERSION).dylib: $(LIBRARY_OBJS) + $(CC) -dynamiclib $(PY_CORE_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACE_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ + + +libpython$(VERSION).sl: $(LIBRARY_OBJS) + $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) + +# List of exported symbols for AIX +Modules/python.exp: $(LIBRARY) + $(srcdir)/Modules/makexp_aix $@ "$(EXPORTSFROM)" $? + +# Copy up the gdb python hooks into a position where they can be automatically +# loaded by gdb during Lib/test/test_gdb.py +# +# Distributors are likely to want to install this somewhere else e.g. relative +# to the stripped DWARF data for the shared library. +.PHONY: gdbhooks +gdbhooks: $(BUILDPYTHON)-gdb.py + +SRC_GDB_HOOKS=$(srcdir)/Tools/gdb/libpython.py +$(BUILDPYTHON)-gdb.py: $(SRC_GDB_HOOKS) + $(INSTALL_DATA) $(SRC_GDB_HOOKS) $(BUILDPYTHON)-gdb.py + +# This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary +# minimal framework (not including the Lib directory and such) in the current +# directory. +$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \ + $(LIBRARY) \ + $(RESSRCDIR)/Info.plist + $(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION) + $(CC) -o $(LDLIBRARY) $(PY_CORE_LDFLAGS) -dynamiclib \ + -all_load $(LIBRARY) \ + -install_name $(PYTHONFRAMEWORKINSTALLNAMEPREFIX)/$(PYTHONFRAMEWORK) \ + -compatibility_version $(VERSION) \ + -current_version $(VERSION) \ + -framework CoreFoundation $(LIBS); + $(INSTALL) -d -m $(DIRMODE) \ + $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj + $(INSTALL_DATA) $(RESSRCDIR)/Info.plist \ + $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/Info.plist + $(LN) -fsn $(VERSION) $(PYTHONFRAMEWORKDIR)/Versions/Current + $(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK) + $(LN) -fsn Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources + +# This rule is for iOS, which requires an annoyingly just slightly different +# format for frameworks to macOS. It *doesn't* use a versioned framework, and +# the Info.plist must be in the root of the framework. +$(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK): \ + $(LIBRARY) \ + $(RESSRCDIR)/Info.plist + $(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR) + $(CC) -o $(LDLIBRARY) $(PY_CORE_LDFLAGS) -dynamiclib \ + -all_load $(LIBRARY) \ + -install_name $(PYTHONFRAMEWORKINSTALLNAMEPREFIX)/$(PYTHONFRAMEWORK) \ + -compatibility_version $(VERSION) \ + -current_version $(VERSION) \ + -framework CoreFoundation $(LIBS); + $(INSTALL_DATA) $(RESSRCDIR)/Info.plist $(PYTHONFRAMEWORKDIR)/Info.plist + +# This rule builds the Cygwin Python DLL and import library if configured +# for a shared core library; otherwise, this rule is a noop. +$(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) + if test -n "$(DLLLIBRARY)"; then \ + $(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \ + $(LIBS) $(MODLIBS) $(SYSLIBS); \ + else true; \ + fi + +# wasm32-emscripten browser web example + +EMSCRIPTEN_DIR=$(srcdir)/Platforms/emscripten +WEBEX_DIR=$(EMSCRIPTEN_DIR)/web_example/ + +ZIP_STDLIB=python$(VERSION)$(ABI_THREAD).zip +$(ZIP_STDLIB): $(srcdir)/Lib/*.py $(srcdir)/Lib/*/*.py \ + $(EMSCRIPTEN_DIR)/wasm_assets.py \ + Makefile pybuilddir.txt Modules/Setup.local + $(PYTHON_FOR_BUILD) $(EMSCRIPTEN_DIR)/wasm_assets.py \ + --buildroot . --prefix $(prefix) -o $@ + +web_example/index.html: $(WEBEX_DIR)/index.html + @mkdir -p web_example + @cp $< $@ + +web_example/python.worker.mjs: $(WEBEX_DIR)/python.worker.mjs + @mkdir -p web_example + @cp $< $@ + +web_example/server.py: $(WEBEX_DIR)/server.py + @mkdir -p web_example + @cp $< $@ + +web_example/$(ZIP_STDLIB): $(ZIP_STDLIB) + @mkdir -p web_example + @cp $< $@ + +web_example/python.mjs web_example/python.wasm: $(BUILDPYTHON) + @if test $(HOST_GNU_TYPE) != 'wasm32-unknown-emscripten' ; then \ + echo "Can only build web_example when target is Emscripten" ;\ + exit 1 ;\ + fi + cp python.mjs web_example/python.mjs + cp python.wasm web_example/python.wasm + +.PHONY: web_example +web_example: web_example/python.mjs web_example/python.worker.mjs web_example/index.html web_example/server.py web_example/$(ZIP_STDLIB) + +WEBEX2=web_example_pyrepl_jspi +WEBEX2_DIR=$(EMSCRIPTEN_DIR)/$(WEBEX2)/ + +$(WEBEX2)/python.mjs $(WEBEX2)/python.wasm: $(BUILDPYTHON) + @if test $(HOST_GNU_TYPE) != 'wasm32-unknown-emscripten' ; then \ + echo "Can only build web_example when target is Emscripten" ;\ + exit 1 ;\ + fi + @mkdir -p $(WEBEX2) + @cp python.mjs $(WEBEX2)/python.mjs + @cp python.wasm $(WEBEX2)/python.wasm + +$(WEBEX2)/index.html: $(WEBEX2_DIR)/index.html + @mkdir -p $(WEBEX2) + @cp $< $@ + +$(WEBEX2)/src.mjs: $(WEBEX2_DIR)/src.mjs + @mkdir -p $(WEBEX2) + @cp $< $@ + +$(WEBEX2)/$(ZIP_STDLIB): $(ZIP_STDLIB) + @mkdir -p $(WEBEX2) + @cp $< $@ + +.PHONY: web_example_pyrepl_jspi +web_example_pyrepl_jspi: $(WEBEX2)/python.mjs $(WEBEX2)/index.html $(WEBEX2)/src.mjs $(WEBEX2)/$(ZIP_STDLIB) + + +############################################################################ +# Header files + +PYTHON_HEADERS= \ + $(srcdir)/Include/Python.h \ + $(srcdir)/Include/abstract.h \ + $(srcdir)/Include/audit.h \ + $(srcdir)/Include/bltinmodule.h \ + $(srcdir)/Include/boolobject.h \ + $(srcdir)/Include/bytearrayobject.h \ + $(srcdir)/Include/bytesobject.h \ + $(srcdir)/Include/ceval.h \ + $(srcdir)/Include/codecs.h \ + $(srcdir)/Include/compile.h \ + $(srcdir)/Include/complexobject.h \ + $(srcdir)/Include/critical_section.h \ + $(srcdir)/Include/descrobject.h \ + $(srcdir)/Include/dictobject.h \ + $(srcdir)/Include/dynamic_annotations.h \ + $(srcdir)/Include/enumobject.h \ + $(srcdir)/Include/errcode.h \ + $(srcdir)/Include/exports.h \ + $(srcdir)/Include/fileobject.h \ + $(srcdir)/Include/fileutils.h \ + $(srcdir)/Include/floatobject.h \ + $(srcdir)/Include/frameobject.h \ + $(srcdir)/Include/genericaliasobject.h \ + $(srcdir)/Include/import.h \ + $(srcdir)/Include/intrcheck.h \ + $(srcdir)/Include/iterobject.h \ + $(srcdir)/Include/listobject.h \ + $(srcdir)/Include/longobject.h \ + $(srcdir)/Include/marshal.h \ + $(srcdir)/Include/memoryobject.h \ + $(srcdir)/Include/methodobject.h \ + $(srcdir)/Include/modsupport.h \ + $(srcdir)/Include/moduleobject.h \ + $(srcdir)/Include/object.h \ + $(srcdir)/Include/objimpl.h \ + $(srcdir)/Include/opcode.h \ + $(srcdir)/Include/opcode_ids.h \ + $(srcdir)/Include/osdefs.h \ + $(srcdir)/Include/osmodule.h \ + $(srcdir)/Include/patchlevel.h \ + $(srcdir)/Include/pyabi.h \ + $(srcdir)/Include/pyatomic.h \ + $(srcdir)/Include/pybuffer.h \ + $(srcdir)/Include/pycapsule.h \ + $(srcdir)/Include/pydtrace.h \ + $(srcdir)/Include/pyerrors.h \ + $(srcdir)/Include/pyexpat.h \ + $(srcdir)/Include/pyframe.h \ + $(srcdir)/Include/pyhash.h \ + $(srcdir)/Include/pylifecycle.h \ + $(srcdir)/Include/pymacconfig.h \ + $(srcdir)/Include/pymacro.h \ + $(srcdir)/Include/pymath.h \ + $(srcdir)/Include/pymem.h \ + $(srcdir)/Include/pyport.h \ + $(srcdir)/Include/pystate.h \ + $(srcdir)/Include/pystats.h \ + $(srcdir)/Include/pystrcmp.h \ + $(srcdir)/Include/pystrtod.h \ + $(srcdir)/Include/pythonrun.h \ + $(srcdir)/Include/pythread.h \ + $(srcdir)/Include/pytypedefs.h \ + $(srcdir)/Include/rangeobject.h \ + $(srcdir)/Include/refcount.h \ + $(srcdir)/Include/setobject.h \ + $(srcdir)/Include/sliceobject.h \ + $(srcdir)/Include/slots.h \ + $(srcdir)/Include/slots_generated.h \ + $(srcdir)/Include/structmember.h \ + $(srcdir)/Include/structseq.h \ + $(srcdir)/Include/sysmodule.h \ + $(srcdir)/Include/traceback.h \ + $(srcdir)/Include/tupleobject.h \ + $(srcdir)/Include/unicodeobject.h \ + $(srcdir)/Include/warnings.h \ + $(srcdir)/Include/weakrefobject.h \ + $(srcdir)/Python/remote_debug.h \ + \ + pyconfig.h \ + $(PARSER_HEADERS) \ + \ + $(srcdir)/Include/cpython/abstract.h \ + $(srcdir)/Include/cpython/audit.h \ + $(srcdir)/Include/cpython/bytearrayobject.h \ + $(srcdir)/Include/cpython/bytesobject.h \ + $(srcdir)/Include/cpython/cellobject.h \ + $(srcdir)/Include/cpython/ceval.h \ + $(srcdir)/Include/cpython/classobject.h \ + $(srcdir)/Include/cpython/code.h \ + $(srcdir)/Include/cpython/compile.h \ + $(srcdir)/Include/cpython/complexobject.h \ + $(srcdir)/Include/cpython/context.h \ + $(srcdir)/Include/cpython/critical_section.h \ + $(srcdir)/Include/cpython/descrobject.h \ + $(srcdir)/Include/cpython/dictobject.h \ + $(srcdir)/Include/cpython/fileobject.h \ + $(srcdir)/Include/cpython/fileutils.h \ + $(srcdir)/Include/cpython/floatobject.h \ + $(srcdir)/Include/cpython/frameobject.h \ + $(srcdir)/Include/cpython/funcobject.h \ + $(srcdir)/Include/cpython/genobject.h \ + $(srcdir)/Include/cpython/import.h \ + $(srcdir)/Include/cpython/initconfig.h \ + $(srcdir)/Include/cpython/listobject.h \ + $(srcdir)/Include/cpython/pylock.h \ + $(srcdir)/Include/cpython/longintrepr.h \ + $(srcdir)/Include/cpython/longobject.h \ + $(srcdir)/Include/cpython/marshal.h \ + $(srcdir)/Include/cpython/memoryobject.h \ + $(srcdir)/Include/cpython/methodobject.h \ + $(srcdir)/Include/cpython/modsupport.h \ + $(srcdir)/Include/cpython/monitoring.h \ + $(srcdir)/Include/cpython/object.h \ + $(srcdir)/Include/cpython/objimpl.h \ + $(srcdir)/Include/cpython/odictobject.h \ + $(srcdir)/Include/cpython/picklebufobject.h \ + $(srcdir)/Include/cpython/pthread_stubs.h \ + $(srcdir)/Include/cpython/pyatomic.h \ + $(srcdir)/Include/cpython/pyatomic_gcc.h \ + $(srcdir)/Include/cpython/pyatomic_std.h \ + $(srcdir)/Include/cpython/pyctype.h \ + $(srcdir)/Include/cpython/pydebug.h \ + $(srcdir)/Include/cpython/pyerrors.h \ + $(srcdir)/Include/cpython/pyfpe.h \ + $(srcdir)/Include/cpython/pyframe.h \ + $(srcdir)/Include/cpython/pyhash.h \ + $(srcdir)/Include/cpython/pylifecycle.h \ + $(srcdir)/Include/cpython/pymem.h \ + $(srcdir)/Include/cpython/pystate.h \ + $(srcdir)/Include/cpython/pystats.h \ + $(srcdir)/Include/cpython/pythonrun.h \ + $(srcdir)/Include/cpython/pythread.h \ + $(srcdir)/Include/cpython/sentinelobject.h \ + $(srcdir)/Include/cpython/setobject.h \ + $(srcdir)/Include/cpython/sliceobject.h \ + $(srcdir)/Include/cpython/structseq.h \ + $(srcdir)/Include/cpython/traceback.h \ + $(srcdir)/Include/cpython/tracemalloc.h \ + $(srcdir)/Include/cpython/tupleobject.h \ + $(srcdir)/Include/cpython/unicodeobject.h \ + $(srcdir)/Include/cpython/warnings.h \ + $(srcdir)/Include/cpython/weakrefobject.h \ + \ + $(MIMALLOC_HEADERS) \ + \ + $(srcdir)/Include/internal/pycore_abstract.h \ + $(srcdir)/Include/internal/pycore_asdl.h \ + $(srcdir)/Include/internal/pycore_ast.h \ + $(srcdir)/Include/internal/pycore_ast_state.h \ + $(srcdir)/Include/internal/pycore_atexit.h \ + $(srcdir)/Include/internal/pycore_audit.h \ + $(srcdir)/Include/internal/pycore_backoff.h \ + $(srcdir)/Include/internal/pycore_bitutils.h \ + $(srcdir)/Include/internal/pycore_blocks_output_buffer.h \ + $(srcdir)/Include/internal/pycore_brc.h \ + $(srcdir)/Include/internal/pycore_bytes_methods.h \ + $(srcdir)/Include/internal/pycore_bytesobject.h \ + $(srcdir)/Include/internal/pycore_call.h \ + $(srcdir)/Include/internal/pycore_capsule.h \ + $(srcdir)/Include/internal/pycore_cell.h \ + $(srcdir)/Include/internal/pycore_ceval.h \ + $(srcdir)/Include/internal/pycore_ceval_state.h \ + $(srcdir)/Include/internal/pycore_code.h \ + $(srcdir)/Include/internal/pycore_codecs.h \ + $(srcdir)/Include/internal/pycore_compile.h \ + $(srcdir)/Include/internal/pycore_complexobject.h \ + $(srcdir)/Include/internal/pycore_condvar.h \ + $(srcdir)/Include/internal/pycore_context.h \ + $(srcdir)/Include/internal/pycore_critical_section.h \ + $(srcdir)/Include/internal/pycore_crossinterp.h \ + $(srcdir)/Include/internal/pycore_crossinterp_data_registry.h \ + $(srcdir)/Include/internal/pycore_debug_offsets.h \ + $(srcdir)/Include/internal/pycore_descrobject.h \ + $(srcdir)/Include/internal/pycore_dict.h \ + $(srcdir)/Include/internal/pycore_dict_state.h \ + $(srcdir)/Include/internal/pycore_dtoa.h \ + $(srcdir)/Include/internal/pycore_exceptions.h \ + $(srcdir)/Include/internal/pycore_faulthandler.h \ + $(srcdir)/Include/internal/pycore_fileutils.h \ + $(srcdir)/Include/internal/pycore_floatobject.h \ + $(srcdir)/Include/internal/pycore_flowgraph.h \ + $(srcdir)/Include/internal/pycore_format.h \ + $(srcdir)/Include/internal/pycore_frame.h \ + $(srcdir)/Include/internal/pycore_freelist.h \ + $(srcdir)/Include/internal/pycore_freelist_state.h \ + $(srcdir)/Include/internal/pycore_function.h \ + $(srcdir)/Include/internal/pycore_gc.h \ + $(srcdir)/Include/internal/pycore_genobject.h \ + $(srcdir)/Include/internal/pycore_getopt.h \ + $(srcdir)/Include/internal/pycore_gil.h \ + $(srcdir)/Include/internal/pycore_global_objects.h \ + $(srcdir)/Include/internal/pycore_global_objects_fini_generated.h \ + $(srcdir)/Include/internal/pycore_global_strings.h \ + $(srcdir)/Include/internal/pycore_hamt.h \ + $(srcdir)/Include/internal/pycore_hashtable.h \ + $(srcdir)/Include/internal/pycore_import.h \ + $(srcdir)/Include/internal/pycore_importdl.h \ + $(srcdir)/Include/internal/pycore_index_pool.h \ + $(srcdir)/Include/internal/pycore_initconfig.h \ + $(srcdir)/Include/internal/pycore_instruments.h \ + $(srcdir)/Include/internal/pycore_instruction_sequence.h \ + $(srcdir)/Include/internal/pycore_interp.h \ + $(srcdir)/Include/internal/pycore_interp_structs.h \ + $(srcdir)/Include/internal/pycore_interpframe.h \ + $(srcdir)/Include/internal/pycore_interpframe_structs.h \ + $(srcdir)/Include/internal/pycore_interpolation.h \ + $(srcdir)/Include/internal/pycore_intrinsics.h \ + $(srcdir)/Include/internal/pycore_iterobject.h \ + $(srcdir)/Include/internal/pycore_jit.h \ + $(srcdir)/Include/internal/pycore_lazyimportobject.h \ + $(srcdir)/Include/internal/pycore_list.h \ + $(srcdir)/Include/internal/pycore_llist.h \ + $(srcdir)/Include/internal/pycore_lock.h \ + $(srcdir)/Include/internal/pycore_long.h \ + $(srcdir)/Include/internal/pycore_memoryobject.h \ + $(srcdir)/Include/internal/pycore_mimalloc.h \ + $(srcdir)/Include/internal/pycore_mmap.h \ + $(srcdir)/Include/internal/pycore_modsupport.h \ + $(srcdir)/Include/internal/pycore_moduleobject.h \ + $(srcdir)/Include/internal/pycore_namespace.h \ + $(srcdir)/Include/internal/pycore_object.h \ + $(srcdir)/Include/internal/pycore_object_alloc.h \ + $(srcdir)/Include/internal/pycore_object_deferred.h \ + $(srcdir)/Include/internal/pycore_object_stack.h \ + $(srcdir)/Include/internal/pycore_object_state.h \ + $(srcdir)/Include/internal/pycore_obmalloc.h \ + $(srcdir)/Include/internal/pycore_obmalloc_init.h \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ + $(srcdir)/Include/internal/pycore_opcode_utils.h \ + $(srcdir)/Include/internal/pycore_optimizer.h \ + $(srcdir)/Include/internal/pycore_parking_lot.h \ + $(srcdir)/Include/internal/pycore_parser.h \ + $(srcdir)/Include/internal/pycore_pathconfig.h \ + $(srcdir)/Include/internal/pycore_pyarena.h \ + $(srcdir)/Include/internal/pycore_pyatomic_ft_wrappers.h \ + $(srcdir)/Include/internal/pycore_pybuffer.h \ + $(srcdir)/Include/internal/pycore_pyerrors.h \ + $(srcdir)/Include/internal/pycore_pyhash.h \ + $(srcdir)/Include/internal/pycore_pylifecycle.h \ + $(srcdir)/Include/internal/pycore_pymath.h \ + $(srcdir)/Include/internal/pycore_pymem.h \ + $(srcdir)/Include/internal/pycore_pymem_init.h \ + $(srcdir)/Include/internal/pycore_pystate.h \ + $(srcdir)/Include/internal/pycore_pystats.h \ + $(srcdir)/Include/internal/pycore_pythonrun.h \ + $(srcdir)/Include/internal/pycore_pythread.h \ + $(srcdir)/Include/internal/pycore_qsbr.h \ + $(srcdir)/Include/internal/pycore_range.h \ + $(srcdir)/Include/internal/pycore_runtime.h \ + $(srcdir)/Include/internal/pycore_runtime_init.h \ + $(srcdir)/Include/internal/pycore_runtime_init_generated.h \ + $(srcdir)/Include/internal/pycore_runtime_structs.h \ + $(srcdir)/Include/internal/pycore_semaphore.h \ + $(srcdir)/Include/internal/pycore_setobject.h \ + $(srcdir)/Include/internal/pycore_signal.h \ + $(srcdir)/Include/internal/pycore_sliceobject.h \ + $(srcdir)/Include/internal/pycore_slots.h \ + $(srcdir)/Include/internal/pycore_slots_generated.h \ + $(srcdir)/Include/internal/pycore_stats.h \ + $(srcdir)/Include/internal/pycore_strhex.h \ + $(srcdir)/Include/internal/pycore_stackref.h \ + $(srcdir)/Include/internal/pycore_structs.h \ + $(srcdir)/Include/internal/pycore_structseq.h \ + $(srcdir)/Include/internal/pycore_symtable.h \ + $(srcdir)/Include/internal/pycore_sysmodule.h \ + $(srcdir)/Include/internal/pycore_template.h \ + $(srcdir)/Include/internal/pycore_time.h \ + $(srcdir)/Include/internal/pycore_token.h \ + $(srcdir)/Include/internal/pycore_traceback.h \ + $(srcdir)/Include/internal/pycore_tracemalloc.h \ + $(srcdir)/Include/internal/pycore_tstate.h \ + $(srcdir)/Include/internal/pycore_tuple.h \ + $(srcdir)/Include/internal/pycore_typecache.h \ + $(srcdir)/Include/internal/pycore_typedefs.h \ + $(srcdir)/Include/internal/pycore_typeobject.h \ + $(srcdir)/Include/internal/pycore_typevarobject.h \ + $(srcdir)/Include/internal/pycore_ucnhash.h \ + $(srcdir)/Include/internal/pycore_unicodectype.h \ + $(srcdir)/Include/internal/pycore_unicodeobject.h \ + $(srcdir)/Include/internal/pycore_unicodeobject_generated.h \ + $(srcdir)/Include/internal/pycore_unionobject.h \ + $(srcdir)/Include/internal/pycore_uniqueid.h \ + $(srcdir)/Include/internal/pycore_uop.h \ + $(srcdir)/Include/internal/pycore_uop_ids.h \ + $(srcdir)/Include/internal/pycore_uop_metadata.h \ + $(srcdir)/Include/internal/pycore_warnings.h \ + $(srcdir)/Include/internal/pycore_weakref.h \ + $(DTRACE_HEADERS) \ + @PLATFORM_HEADERS@ \ + \ + $(srcdir)/Python/stdlib_module_names.h + +########################################################################## +# Build static libexpat.a +LIBEXPAT_CFLAGS=@LIBEXPAT_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED) + +Modules/expat/xmlparse.o: $(srcdir)/Modules/expat/xmlparse.c $(LIBEXPAT_HEADERS) $(PYTHON_HEADERS) + $(CC) -c $(LIBEXPAT_CFLAGS) -o $@ $(srcdir)/Modules/expat/xmlparse.c + +Modules/expat/xmlrole.o: $(srcdir)/Modules/expat/xmlrole.c $(LIBEXPAT_HEADERS) $(PYTHON_HEADERS) + $(CC) -c $(LIBEXPAT_CFLAGS) -o $@ $(srcdir)/Modules/expat/xmlrole.c + +Modules/expat/xmltok.o: $(srcdir)/Modules/expat/xmltok.c $(LIBEXPAT_HEADERS) $(PYTHON_HEADERS) + $(CC) -c $(LIBEXPAT_CFLAGS) -o $@ $(srcdir)/Modules/expat/xmltok.c + +$(LIBEXPAT_A): $(LIBEXPAT_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBEXPAT_OBJS) + +########################################################################## +# HACL* library build +# +# The HACL* modules are dynamically compiled and linked with the +# corresponding CPython built-in modules on demand, depending on +# whether the module is built or not. +# +# In particular, the HACL* objects are also dependencies of the +# corresponding C extension modules but makesetup must NOT create +# a rule for them. +# +# For WASI, static linking is needed and HACL* is statically linked instead. + +Modules/_hacl/Lib_Memzero0.o: $(srcdir)/Modules/_hacl/Lib_Memzero0.c $(LIBHACL_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Lib_Memzero0.c + +Modules/_hacl/Hacl_Hash_MD5.o: $(srcdir)/Modules/_hacl/Hacl_Hash_MD5.c $(LIBHACL_MD5_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_MD5.c +$(LIBHACL_MD5_LIB_STATIC): $(LIBHACL_MD5_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_MD5_OBJS) + +Modules/_hacl/Hacl_Hash_SHA1.o: $(srcdir)/Modules/_hacl/Hacl_Hash_SHA1.c $(LIBHACL_SHA1_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_SHA1.c +$(LIBHACL_SHA1_LIB_STATIC): $(LIBHACL_SHA1_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_SHA1_OBJS) + +Modules/_hacl/Hacl_Hash_SHA2.o: $(srcdir)/Modules/_hacl/Hacl_Hash_SHA2.c $(LIBHACL_SHA2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_SHA2.c +$(LIBHACL_SHA2_LIB_STATIC): $(LIBHACL_SHA2_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_SHA2_OBJS) + +Modules/_hacl/Hacl_Hash_SHA3.o: $(srcdir)/Modules/_hacl/Hacl_Hash_SHA3.c $(LIBHACL_SHA3_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_SHA3.c +$(LIBHACL_SHA3_LIB_STATIC): $(LIBHACL_SHA3_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_SHA3_OBJS) + +Modules/_hacl/Hacl_Hash_Blake2s.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s.c +Modules/_hacl/Hacl_Hash_Blake2b.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b.c +Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_BLAKE2_SIMD128_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c +Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_BLAKE2_SIMD128_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c +Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_BLAKE2_SIMD256_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c +Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_BLAKE2_SIMD256_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c +$(LIBHACL_BLAKE2_LIB_STATIC): $(LIBHACL_BLAKE2_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_BLAKE2_OBJS) + +# Other HACL* cryptographic primitives + +Modules/_hacl/Hacl_HMAC.o: $(srcdir)/Modules/_hacl/Hacl_HMAC.c $(LIBHACL_HMAC_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_HMAC.c +Modules/_hacl/Hacl_Streaming_HMAC.o: $(srcdir)/Modules/_hacl/Hacl_Streaming_HMAC.c $(LIBHACL_HMAC_HEADERS) + $(CC) -Wno-unused-variable -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Streaming_HMAC.c +$(LIBHACL_HMAC_LIB_STATIC): $(LIBHACL_HMAC_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_HMAC_OBJS) + +########################################################################## +# create relative links from build/lib.platform/egg.so to Modules/egg.so +# pybuilddir.txt is created too late. We cannot use it in Makefile +# targets. ln --relative is not portable. +.PHONY: sharedmods +sharedmods: $(SHAREDMODS) pybuilddir.txt + @target=`cat pybuilddir.txt`; \ + $(MKDIR_P) $$target; \ + for mod in X $(SHAREDMODS); do \ + if test $$mod != X; then \ + $(LN) -sf ../../$$mod $$target/`basename $$mod`; \ + fi; \ + done + +# dependency on BUILDPYTHON ensures that the target is run last +.PHONY: checksharedmods +checksharedmods: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) + @if [ -n "@MISSING_STDLIB_CONFIG@" ]; then \ + $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/check_extension_modules.py --generate-missing-stdlib-info --with-missing-stdlib-config="@MISSING_STDLIB_CONFIG@"; \ + else \ + $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/check_extension_modules.py --generate-missing-stdlib-info; \ + fi + @$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/check_extension_modules.py + +.PHONY: rundsymutil +rundsymutil: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) + @if [ ! -z $(DSYMUTIL) ] ; then \ + echo $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + if test -f $(LDLIBRARY); then \ + echo $(DSYMUTIL_PATH) $(LDLIBRARY); \ + $(DSYMUTIL_PATH) $(LDLIBRARY); \ + fi; \ + for mod in X $(SHAREDMODS); do \ + if test $$mod != X; then \ + echo $(DSYMUTIL_PATH) $$mod; \ + $(DSYMUTIL_PATH) $$mod; \ + fi; \ + done \ + fi + +Modules/Setup.local: + @# Create empty Setup.local when file was deleted by user + echo "# Edit this file for local setup changes" > $@ + +Modules/Setup.bootstrap: $(srcdir)/Modules/Setup.bootstrap.in config.status + ./config.status $@ + +Modules/Setup.stdlib: $(srcdir)/Modules/Setup.stdlib.in config.status + ./config.status $@ + +Makefile Modules/config.c: Makefile.pre \ + $(srcdir)/Modules/config.c.in \ + $(MAKESETUP) \ + $(srcdir)/Modules/Setup \ + Modules/Setup.local \ + Modules/Setup.bootstrap \ + Modules/Setup.stdlib + $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \ + -s Modules \ + Modules/Setup.local \ + Modules/Setup.stdlib \ + Modules/Setup.bootstrap \ + $(srcdir)/Modules/Setup + @mv config.c Modules + @echo "The Makefile was updated, you may need to re-run make." + +.PHONY: regen-test-frozenmain +regen-test-frozenmain: $(BUILDPYTHON) + # Regenerate Programs/test_frozenmain.h + # from Programs/test_frozenmain.py + # using Programs/freeze_test_frozenmain.py + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Programs/freeze_test_frozenmain.py Programs/test_frozenmain.h + +.PHONY: regen-test-levenshtein +regen-test-levenshtein: + # Regenerate Lib/test/levenshtein_examples.json + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_levenshtein_examples.py $(srcdir)/Lib/test/levenshtein_examples.json + +.PHONY: regen-re +regen-re: $(BUILDPYTHON) + # Regenerate Lib/re/_casefix.py + # using Tools/build/generate_re_casefix.py + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/generate_re_casefix.py $(srcdir)/Lib/re/_casefix.py + +Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS) + $(LINKCC) $(PY_CORE_EXE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) + +############################################################################ +# "Bootstrap Python" used to run Programs/_freeze_module.py + +BOOTSTRAP_HEADERS = \ + Python/frozen_modules/importlib._bootstrap.h \ + Python/frozen_modules/importlib._bootstrap_external.h \ + Python/frozen_modules/zipimport.h + +Programs/_bootstrap_python.o: Programs/_bootstrap_python.c $(BOOTSTRAP_HEADERS) $(PYTHON_HEADERS) + +_bootstrap_python: $(LIBRARY_OBJS_OMIT_FROZEN) Programs/_bootstrap_python.o Modules/getpath.o Modules/Setup.local + $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ $(LIBRARY_OBJS_OMIT_FROZEN) \ + Programs/_bootstrap_python.o Modules/getpath.o $(LIBS) $(MODLIBS) $(SYSLIBS) + # Dummy pybuilddir.txt is needed for _bootstrap_python to be runnable + @echo "none" > ./pybuilddir.txt + + +############################################################################ +# frozen modules (including importlib) +# +# Freezing is a multi step process. It works differently for standard builds +# and cross builds. Standard builds use Programs/_freeze_module and +# _bootstrap_python for freezing, so users can build Python +# without an existing Python installation. Cross builds cannot execute +# compiled binaries and therefore rely on an external build Python +# interpreter. The build interpreter must have same version and same bytecode +# as the host (target) binary. +# +# Standard build process: +# 1) compile minimal core objects for Py_Compile*() and PyMarshal_Write*(). +# 2) build Programs/_freeze_module binary. +# 3) create frozen module headers for importlib and getpath. +# 4) build _bootstrap_python binary. +# 5) create remaining frozen module headers with +# ``./_bootstrap_python Programs/_freeze_module.py``. The pure Python +# script is used to test the cross compile code path. +# +# Cross compile process: +# 1) create all frozen module headers with external build Python and +# Programs/_freeze_module.py script. +# + +# FROZEN_FILES_* are auto-generated by Tools/build/freeze_modules.py. +FROZEN_FILES_IN = \ + Lib/importlib/_bootstrap.py \ + Lib/importlib/_bootstrap_external.py \ + Lib/zipimport.py \ + Lib/abc.py \ + Lib/codecs.py \ + Lib/io.py \ + Lib/_collections_abc.py \ + Lib/_sitebuiltins.py \ + Lib/genericpath.py \ + Lib/ntpath.py \ + Lib/posixpath.py \ + Lib/os.py \ + Lib/site.py \ + Lib/stat.py \ + Lib/linecache.py \ + Lib/importlib/util.py \ + Lib/importlib/machinery.py \ + Lib/runpy.py \ + Lib/__hello__.py \ + Lib/__phello__/__init__.py \ + Lib/__phello__/ham/__init__.py \ + Lib/__phello__/ham/eggs.py \ + Lib/__phello__/spam.py \ + Tools/freeze/flag.py +# End FROZEN_FILES_IN +FROZEN_FILES_OUT = \ + Python/frozen_modules/importlib._bootstrap.h \ + Python/frozen_modules/importlib._bootstrap_external.h \ + Python/frozen_modules/zipimport.h \ + Python/frozen_modules/abc.h \ + Python/frozen_modules/codecs.h \ + Python/frozen_modules/io.h \ + Python/frozen_modules/_collections_abc.h \ + Python/frozen_modules/_sitebuiltins.h \ + Python/frozen_modules/genericpath.h \ + Python/frozen_modules/ntpath.h \ + Python/frozen_modules/posixpath.h \ + Python/frozen_modules/os.h \ + Python/frozen_modules/site.h \ + Python/frozen_modules/stat.h \ + Python/frozen_modules/linecache.h \ + Python/frozen_modules/importlib.util.h \ + Python/frozen_modules/importlib.machinery.h \ + Python/frozen_modules/runpy.h \ + Python/frozen_modules/__hello__.h \ + Python/frozen_modules/__phello__.h \ + Python/frozen_modules/__phello__.ham.h \ + Python/frozen_modules/__phello__.ham.eggs.h \ + Python/frozen_modules/__phello__.spam.h \ + Python/frozen_modules/frozen_only.h +# End FROZEN_FILES_OUT + +Programs/_freeze_module.o: Programs/_freeze_module.c Makefile + +Modules/getpath_noop.o: $(srcdir)/Modules/getpath_noop.c Makefile + +Programs/_freeze_module: Programs/_freeze_module.o Modules/getpath_noop.o $(LIBRARY_OBJS_OMIT_FROZEN) + $(LINKCC) $(PY_CORE_LDFLAGS) -o $@ Programs/_freeze_module.o Modules/getpath_noop.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) + +# We manually freeze getpath.py rather than through freeze_modules +Python/frozen_modules/getpath.h: Modules/getpath.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) getpath $(srcdir)/Modules/getpath.py Python/frozen_modules/getpath.h + +# BEGIN: freezing modules + +Python/frozen_modules/importlib._bootstrap.h: Lib/importlib/_bootstrap.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) importlib._bootstrap $(srcdir)/Lib/importlib/_bootstrap.py Python/frozen_modules/importlib._bootstrap.h + +Python/frozen_modules/importlib._bootstrap_external.h: Lib/importlib/_bootstrap_external.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) importlib._bootstrap_external $(srcdir)/Lib/importlib/_bootstrap_external.py Python/frozen_modules/importlib._bootstrap_external.h + +Python/frozen_modules/zipimport.h: Lib/zipimport.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) zipimport $(srcdir)/Lib/zipimport.py Python/frozen_modules/zipimport.h + +Python/frozen_modules/abc.h: Lib/abc.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) abc $(srcdir)/Lib/abc.py Python/frozen_modules/abc.h + +Python/frozen_modules/codecs.h: Lib/codecs.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) codecs $(srcdir)/Lib/codecs.py Python/frozen_modules/codecs.h + +Python/frozen_modules/io.h: Lib/io.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) io $(srcdir)/Lib/io.py Python/frozen_modules/io.h + +Python/frozen_modules/_collections_abc.h: Lib/_collections_abc.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) _collections_abc $(srcdir)/Lib/_collections_abc.py Python/frozen_modules/_collections_abc.h + +Python/frozen_modules/_sitebuiltins.h: Lib/_sitebuiltins.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) _sitebuiltins $(srcdir)/Lib/_sitebuiltins.py Python/frozen_modules/_sitebuiltins.h + +Python/frozen_modules/genericpath.h: Lib/genericpath.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) genericpath $(srcdir)/Lib/genericpath.py Python/frozen_modules/genericpath.h + +Python/frozen_modules/ntpath.h: Lib/ntpath.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) ntpath $(srcdir)/Lib/ntpath.py Python/frozen_modules/ntpath.h + +Python/frozen_modules/posixpath.h: Lib/posixpath.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) posixpath $(srcdir)/Lib/posixpath.py Python/frozen_modules/posixpath.h + +Python/frozen_modules/os.h: Lib/os.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) os $(srcdir)/Lib/os.py Python/frozen_modules/os.h + +Python/frozen_modules/site.h: Lib/site.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) site $(srcdir)/Lib/site.py Python/frozen_modules/site.h + +Python/frozen_modules/stat.h: Lib/stat.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) stat $(srcdir)/Lib/stat.py Python/frozen_modules/stat.h + +Python/frozen_modules/linecache.h: Lib/linecache.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) linecache $(srcdir)/Lib/linecache.py Python/frozen_modules/linecache.h + +Python/frozen_modules/importlib.util.h: Lib/importlib/util.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) importlib.util $(srcdir)/Lib/importlib/util.py Python/frozen_modules/importlib.util.h + +Python/frozen_modules/importlib.machinery.h: Lib/importlib/machinery.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) importlib.machinery $(srcdir)/Lib/importlib/machinery.py Python/frozen_modules/importlib.machinery.h + +Python/frozen_modules/runpy.h: Lib/runpy.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) runpy $(srcdir)/Lib/runpy.py Python/frozen_modules/runpy.h + +Python/frozen_modules/__hello__.h: Lib/__hello__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __hello__ $(srcdir)/Lib/__hello__.py Python/frozen_modules/__hello__.h + +Python/frozen_modules/__phello__.h: Lib/__phello__/__init__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__ $(srcdir)/Lib/__phello__/__init__.py Python/frozen_modules/__phello__.h + +Python/frozen_modules/__phello__.ham.h: Lib/__phello__/ham/__init__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__.ham $(srcdir)/Lib/__phello__/ham/__init__.py Python/frozen_modules/__phello__.ham.h + +Python/frozen_modules/__phello__.ham.eggs.h: Lib/__phello__/ham/eggs.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__.ham.eggs $(srcdir)/Lib/__phello__/ham/eggs.py Python/frozen_modules/__phello__.ham.eggs.h + +Python/frozen_modules/__phello__.spam.h: Lib/__phello__/spam.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__.spam $(srcdir)/Lib/__phello__/spam.py Python/frozen_modules/__phello__.spam.h + +Python/frozen_modules/frozen_only.h: Tools/freeze/flag.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) frozen_only $(srcdir)/Tools/freeze/flag.py Python/frozen_modules/frozen_only.h + +# END: freezing modules + +Tools/build/freeze_modules.py: $(FREEZE_MODULE) + +.PHONY: regen-frozen +regen-frozen: Tools/build/freeze_modules.py $(FROZEN_FILES_IN) + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/freeze_modules.py --frozen-modules + @echo "The Makefile was updated, you may need to re-run make." + +# We keep this renamed target around for folks with muscle memory. +.PHONY: regen-importlib +regen-importlib: regen-frozen + +############################################################################ +# Global objects + +# Dependencies which can add and/or remove _Py_ID() identifiers: +# - "make clinic" +.PHONY: regen-global-objects +regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py clinic + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py + +############################################################################ +# ABI + +.PHONY: regen-abidump +regen-abidump: all + @$(MKDIR_P) $(srcdir)/Doc/data/ + abidw "libpython$(LDVERSION).so" --no-architecture --out-file $(srcdir)/Doc/data/python$(LDVERSION).abi.new + @$(UPDATE_FILE) --create $(srcdir)/Doc/data/python$(LDVERSION).abi $(srcdir)/Doc/data/python$(LDVERSION).abi.new + +.PHONY: check-abidump +check-abidump: all + abidiff $(srcdir)/Doc/data/python$(LDVERSION).abi "libpython$(LDVERSION).so" --drop-private-types --no-architecture --no-added-syms --suppressions $(srcdir)/Misc/libabigail.abignore + +.PHONY: regen-limited-abi +regen-limited-abi: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --generate-all + +############################################################################ +# Regenerate Unicode Data + +.PHONY: regen-unicodedata +regen-unicodedata: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/unicode/makeunicodedata.py + + +############################################################################ +# Regenerate all generated files + +# "clinic" is regenerated implicitly via "regen-global-objects". +.PHONY: regen-all +regen-all: regen-cases regen-slots \ + regen-token regen-ast regen-keyword regen-sre regen-frozen \ + regen-pegen-metaparser regen-pegen regen-test-frozenmain \ + regen-test-levenshtein regen-global-objects + @echo + @echo "Note: make regen-stdlib-module-names, make regen-limited-abi, " + @echo "make regen-configure, make regen-sbom, and make regen-unicodedata should be run manually" + +############################################################################ +# Special rules for object files + +Modules/getbuildinfo.o: $(PARSER_OBJS) \ + $(OBJECT_OBJS) \ + $(PYTHON_OBJS) \ + $(MODULE_OBJS) \ + $(MODOBJS) \ + $(DTRACE_OBJS) \ + $(srcdir)/Modules/getbuildinfo.c + $(CC) -c $(PY_CORE_CFLAGS) \ + -DGITVERSION="\"`LC_ALL=C $(GITVERSION)`\"" \ + -DGITTAG="\"`LC_ALL=C $(GITTAG)`\"" \ + -DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \ + -o $@ $(srcdir)/Modules/getbuildinfo.c + +Modules/getpath.o: $(srcdir)/Modules/getpath.c Python/frozen_modules/getpath.h Makefile $(PYTHON_HEADERS) + $(CC) -c $(PY_CORE_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \ + -DPREFIX='"$(host_prefix)"' \ + -DEXEC_PREFIX='"$(host_exec_prefix)"' \ + -DVERSION='"$(VERSION)"' \ + -DVPATH='"$(VPATH)"' \ + -DPLATLIBDIR='"$(PLATLIBDIR)"' \ + -DPYTHONFRAMEWORK='"$(PYTHONFRAMEWORK)"' \ + -o $@ $(srcdir)/Modules/getpath.c + +Programs/python.o: $(srcdir)/Programs/python.c + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c + +Programs/_testembed.o: $(srcdir)/Programs/_testembed.c Programs/test_frozenmain.h $(PYTHON_HEADERS) + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c + +Modules/_sre/sre.o: $(srcdir)/Modules/_sre/sre.c $(srcdir)/Modules/_sre/sre.h $(srcdir)/Modules/_sre/sre_constants.h $(srcdir)/Modules/_sre/sre_lib.h + +Modules/posixmodule.o: $(srcdir)/Modules/posixmodule.c $(srcdir)/Modules/posixmodule.h + +Modules/grpmodule.o: $(srcdir)/Modules/grpmodule.c $(srcdir)/Modules/posixmodule.h + +Modules/pwdmodule.o: $(srcdir)/Modules/pwdmodule.c $(srcdir)/Modules/posixmodule.h + +Modules/signalmodule.o: $(srcdir)/Modules/signalmodule.c $(srcdir)/Modules/posixmodule.h + +Modules/_interpretersmodule.o: $(srcdir)/Modules/_interpretersmodule.c $(srcdir)/Modules/_interpreters_common.h + +Modules/_interpqueuesmodule.o: $(srcdir)/Modules/_interpqueuesmodule.c $(srcdir)/Modules/_interpreters_common.h + +Modules/_interpchannelsmodule.o: $(srcdir)/Modules/_interpchannelsmodule.c $(srcdir)/Modules/_interpreters_common.h + +Python/crossinterp.o: $(srcdir)/Python/crossinterp.c $(srcdir)/Python/crossinterp_data_lookup.h $(srcdir)/Python/crossinterp_exceptions.h + +Python/initconfig.o: $(srcdir)/Python/initconfig.c $(srcdir)/Python/config_common.h + +Python/interpconfig.o: $(srcdir)/Python/interpconfig.c $(srcdir)/Python/config_common.h + +Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile + $(CC) -c $(PY_CORE_CFLAGS) \ + -DSOABI='"$(SOABI)"' \ + -o $@ $(srcdir)/Python/dynload_shlib.c + +Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile + $(CC) -c $(PY_CORE_CFLAGS) \ + -DSHLIB_EXT='"$(EXT_SUFFIX)"' \ + -o $@ $(srcdir)/Python/dynload_hpux.c + +Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h + $(CC) -c $(PY_CORE_CFLAGS) \ + -DABIFLAGS='"$(ABIFLAGS)"' \ + $(MULTIARCH_CPPFLAGS) \ + -o $@ $(srcdir)/Python/sysmodule.c + +$(IO_OBJS): $(IO_H) + +.PHONY: regen-pegen-metaparser +regen-pegen-metaparser: + @$(MKDIR_P) $(srcdir)/Tools/peg_generator/pegen + PYTHONPATH=$(srcdir)/Tools/peg_generator $(PYTHON_FOR_REGEN) -m pegen -q python \ + $(srcdir)/Tools/peg_generator/pegen/metagrammar.gram \ + -o $(srcdir)/Tools/peg_generator/pegen/grammar_parser.py.new + $(UPDATE_FILE) $(srcdir)/Tools/peg_generator/pegen/grammar_parser.py \ + $(srcdir)/Tools/peg_generator/pegen/grammar_parser.py.new + +.PHONY: regen-pegen +regen-pegen: + @$(MKDIR_P) $(srcdir)/Parser + @$(MKDIR_P) $(srcdir)/Parser/tokenizer + @$(MKDIR_P) $(srcdir)/Parser/lexer + PYTHONPATH=$(srcdir)/Tools/peg_generator $(PYTHON_FOR_REGEN) -m pegen -q c \ + $(srcdir)/Grammar/python.gram \ + $(srcdir)/Grammar/Tokens \ + -o $(srcdir)/Parser/parser.c.new + $(UPDATE_FILE) --create $(srcdir)/Parser/parser.c $(srcdir)/Parser/parser.c.new + +.PHONY: regen-ast +regen-ast: + # Regenerate 3 files using Parser/asdl_c.py: + # - Include/internal/pycore_ast.h + # - Include/internal/pycore_ast_state.h + # - Python/Python-ast.c + $(MKDIR_P) $(srcdir)/Include + $(MKDIR_P) $(srcdir)/Python + $(PYTHON_FOR_REGEN) $(srcdir)/Parser/asdl_c.py \ + $(srcdir)/Parser/Python.asdl \ + -H $(srcdir)/Include/internal/pycore_ast.h.new \ + -I $(srcdir)/Include/internal/pycore_ast_state.h.new \ + -C $(srcdir)/Python/Python-ast.c.new + + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_ast.h $(srcdir)/Include/internal/pycore_ast.h.new + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_ast_state.h $(srcdir)/Include/internal/pycore_ast_state.h.new + $(UPDATE_FILE) $(srcdir)/Python/Python-ast.c $(srcdir)/Python/Python-ast.c.new + +.PHONY: regen-token +regen-token: + # Regenerate Doc/library/token-list.inc from Grammar/Tokens + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py rst \ + $(srcdir)/Grammar/Tokens \ + $(srcdir)/Doc/library/token-list.inc \ + $(srcdir)/Doc/library/token.rst + # Regenerate Include/internal/pycore_token.h from Grammar/Tokens + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py h \ + $(srcdir)/Grammar/Tokens \ + $(srcdir)/Include/internal/pycore_token.h + # Regenerate Parser/token.c from Grammar/Tokens + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py c \ + $(srcdir)/Grammar/Tokens \ + $(srcdir)/Parser/token.c + # Regenerate Lib/token.py from Grammar/Tokens + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py py \ + $(srcdir)/Grammar/Tokens \ + $(srcdir)/Lib/token.py + +.PHONY: regen-keyword +regen-keyword: + # Regenerate Lib/keyword.py from Grammar/python.gram and Grammar/Tokens + # using Tools/peg_generator/pegen + PYTHONPATH=$(srcdir)/Tools/peg_generator $(PYTHON_FOR_REGEN) -m pegen.keywordgen \ + $(srcdir)/Grammar/python.gram \ + $(srcdir)/Grammar/Tokens \ + $(srcdir)/Lib/keyword.py.new + $(UPDATE_FILE) $(srcdir)/Lib/keyword.py $(srcdir)/Lib/keyword.py.new + +.PHONY: regen-stdlib-module-names +regen-stdlib-module-names: all Programs/_testembed + # Regenerate Python/stdlib_module_names.h + # using Tools/build/generate_stdlib_module_names.py + $(RUNSHARED) ./$(BUILDPYTHON) \ + $(srcdir)/Tools/build/generate_stdlib_module_names.py \ + > $(srcdir)/Python/stdlib_module_names.h.new + $(UPDATE_FILE) $(srcdir)/Python/stdlib_module_names.h $(srcdir)/Python/stdlib_module_names.h.new + +.PHONY: regen-sre +regen-sre: + # Regenerate Modules/_sre/sre_constants.h and Modules/_sre/sre_targets.h + # from Lib/re/_constants.py using Tools/build/generate_sre_constants.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_sre_constants.py \ + $(srcdir)/Lib/re/_constants.py \ + $(srcdir)/Modules/_sre/sre_constants.h \ + $(srcdir)/Modules/_sre/sre_targets.h + +Python/compile.o Python/codegen.o Python/symtable.o Python/ast_unparse.o Python/ast.o Python/future.o: $(srcdir)/Include/internal/pycore_ast.h $(srcdir)/Include/internal/pycore_ast.h + +Python/getplatform.o: $(srcdir)/Python/getplatform.c + $(CC) -c $(PY_CORE_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c + +Python/importdl.o: $(srcdir)/Python/importdl.c + $(CC) -c $(PY_CORE_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c + +Objects/unicodectype.o: $(srcdir)/Objects/unicodectype.c \ + $(srcdir)/Objects/unicodetype_db.h + +BYTESTR_DEPS = \ + $(srcdir)/Objects/stringlib/count.h \ + $(srcdir)/Objects/stringlib/ctype.h \ + $(srcdir)/Objects/stringlib/fastsearch.h \ + $(srcdir)/Objects/stringlib/find.h \ + $(srcdir)/Objects/stringlib/join.h \ + $(srcdir)/Objects/stringlib/partition.h \ + $(srcdir)/Objects/stringlib/split.h \ + $(srcdir)/Objects/stringlib/stringdefs.h \ + $(srcdir)/Objects/stringlib/transmogrify.h + +UNICODE_DEPS = \ + $(srcdir)/Objects/stringlib/asciilib.h \ + $(srcdir)/Objects/stringlib/codecs.h \ + $(srcdir)/Objects/stringlib/count.h \ + $(srcdir)/Objects/stringlib/fastsearch.h \ + $(srcdir)/Objects/stringlib/find.h \ + $(srcdir)/Objects/stringlib/find_max_char.h \ + $(srcdir)/Objects/stringlib/partition.h \ + $(srcdir)/Objects/stringlib/replace.h \ + $(srcdir)/Objects/stringlib/repr.h \ + $(srcdir)/Objects/stringlib/split.h \ + $(srcdir)/Objects/stringlib/ucs1lib.h \ + $(srcdir)/Objects/stringlib/ucs2lib.h \ + $(srcdir)/Objects/stringlib/ucs4lib.h \ + $(srcdir)/Objects/stringlib/undef.h \ + $(srcdir)/Objects/stringlib/unicode_format.h + +Objects/bytes_methods.o: $(srcdir)/Objects/bytes_methods.c $(BYTESTR_DEPS) +Objects/bytesobject.o: $(srcdir)/Objects/bytesobject.c $(BYTESTR_DEPS) +Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c $(BYTESTR_DEPS) + +Objects/unicode_format.o: $(srcdir)/Objects/unicode_format.c $(UNICODE_DEPS) +Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c $(UNICODE_DEPS) + +Objects/dictobject.o: $(srcdir)/Objects/stringlib/eq.h +Objects/setobject.o: $(srcdir)/Objects/stringlib/eq.h + +Objects/obmalloc.o: $(srcdir)/Objects/mimalloc/alloc.c \ + $(srcdir)/Objects/mimalloc/alloc-aligned.c \ + $(srcdir)/Objects/mimalloc/alloc-posix.c \ + $(srcdir)/Objects/mimalloc/arena.c \ + $(srcdir)/Objects/mimalloc/bitmap.c \ + $(srcdir)/Objects/mimalloc/heap.c \ + $(srcdir)/Objects/mimalloc/init.c \ + $(srcdir)/Objects/mimalloc/options.c \ + $(srcdir)/Objects/mimalloc/os.c \ + $(srcdir)/Objects/mimalloc/page.c \ + $(srcdir)/Objects/mimalloc/random.c \ + $(srcdir)/Objects/mimalloc/segment.c \ + $(srcdir)/Objects/mimalloc/segment-map.c \ + $(srcdir)/Objects/mimalloc/stats.c \ + $(srcdir)/Objects/mimalloc/prim/prim.c \ + $(srcdir)/Objects/mimalloc/prim/osx/prim.c \ + $(srcdir)/Objects/mimalloc/prim/unix/prim.c \ + $(srcdir)/Objects/mimalloc/prim/wasi/prim.c + +Objects/mimalloc/page.o: $(srcdir)/Objects/mimalloc/page-queue.c + + +# Regenerate various files from Python/bytecodes.c +# Pass CASESFLAG=-l to insert #line directives in the output + +.PHONY: regen-cases +regen-cases: \ + regen-opcode-ids regen-opcode-targets regen-uop-ids regen-opcode-metadata-py \ + regen-generated-cases regen-executor-cases regen-optimizer-cases regen-record-functions \ + regen-opcode-metadata regen-uop-metadata regen-test-cases regen-test-opcode-targets + +.PHONY: regen-opcode-ids +regen-opcode-ids: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/opcode_id_generator.py \ + -o $(srcdir)/Include/opcode_ids.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Include/opcode_ids.h $(srcdir)/Include/opcode_ids.h.new + +.PHONY: regen-opcode-targets +regen-opcode-targets: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/target_generator.py \ + -o $(srcdir)/Python/opcode_targets.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new + +.PHONY: regen-uop-ids +regen-uop-ids: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/uop_id_generator.py \ + -o $(srcdir)/Include/internal/pycore_uop_ids.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_uop_ids.h $(srcdir)/Include/internal/pycore_uop_ids.h.new + +.PHONY: regen-opcode-metadata-py +regen-opcode-metadata-py: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/py_metadata_generator.py \ + -o $(srcdir)/Lib/_opcode_metadata.py.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Lib/_opcode_metadata.py $(srcdir)/Lib/_opcode_metadata.py.new + +.PHONY: regen-generated-cases +regen-generated-cases: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier1_generator.py \ + -o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new + +.PHONY: regen-record-functions +regen-record-functions: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/record_function_generator.py \ + -o $(srcdir)/Python/record_functions.c.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Python/record_functions.c.h $(srcdir)/Python/record_functions.c.h.new + +.PHONY: regen-test-cases +regen-test-cases: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier1_generator.py \ + -o $(srcdir)/Modules/_testinternalcapi/test_cases.c.h.new $(srcdir)/Python/bytecodes.c \ + $(srcdir)/Modules/_testinternalcapi/testbytecodes.c + $(UPDATE_FILE) $(srcdir)/Modules/_testinternalcapi/test_cases.c.h $(srcdir)/Modules/_testinternalcapi/test_cases.c.h.new + +.PHONY: regen-test-opcode-targets +regen-test-opcode-targets: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/target_generator.py \ + -o $(srcdir)/Modules/_testinternalcapi/test_targets.h.new $(srcdir)/Python/bytecodes.c \ + $(srcdir)/Modules/_testinternalcapi/testbytecodes.c + $(UPDATE_FILE) $(srcdir)/Modules/_testinternalcapi/test_targets.h $(srcdir)/Modules/_testinternalcapi/test_targets.h.new + +.PHONY: regen-executor-cases +regen-executor-cases: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier2_generator.py \ + -o $(srcdir)/Python/executor_cases.c.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Python/executor_cases.c.h $(srcdir)/Python/executor_cases.c.h.new + +.PHONY: regen-optimizer-cases +regen-optimizer-cases: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/optimizer_generator.py \ + -o $(srcdir)/Python/optimizer_cases.c.h.new \ + $(srcdir)/Python/optimizer_bytecodes.c \ + $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Python/optimizer_cases.c.h $(srcdir)/Python/optimizer_cases.c.h.new + +.PHONY: regen-opcode-metadata +regen-opcode-metadata: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/opcode_metadata_generator.py \ + -o $(srcdir)/Include/internal/pycore_opcode_metadata.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode_metadata.h $(srcdir)/Include/internal/pycore_opcode_metadata.h.new + +.PHONY: regen-uop-metadata +regen-uop-metadata: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/uop_metadata_generator.py -o \ + $(srcdir)/Include/internal/pycore_uop_metadata.h.new $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_uop_metadata.h $(srcdir)/Include/internal/pycore_uop_metadata.h.new + +Python/compile.o Python/codegen.o Python/assemble.o Python/flowgraph.o Python/instruction_sequence.o: \ + $(srcdir)/Include/internal/pycore_compile.h \ + $(srcdir)/Include/internal/pycore_flowgraph.h \ + $(srcdir)/Include/internal/pycore_instruction_sequence.h \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ + $(srcdir)/Include/internal/pycore_opcode_utils.h + +Python/ceval.o: \ + $(srcdir)/Python/ceval_macros.h \ + $(srcdir)/Python/condvar.h \ + $(srcdir)/Python/generated_cases.c.h \ + $(srcdir)/Python/executor_cases.c.h \ + $(srcdir)/Python/opcode_targets.h \ + $(srcdir)/Python/record_functions.c.h + +Python/flowgraph.o: \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h + +Python/optimizer.o: \ + $(srcdir)/Python/executor_cases.c.h \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ + $(srcdir)/Include/internal/pycore_optimizer.h + +Python/optimizer_analysis.o: \ + $(srcdir)/Include/internal/pycore_opcode_metadata.h \ + $(srcdir)/Include/internal/pycore_optimizer.h \ + $(srcdir)/Python/optimizer_cases.c.h + +Python/frozen.o: $(FROZEN_FILES_OUT) + +# Generate DTrace probe macros, then rename them (PYTHON_ -> PyDTrace_) to +# follow our naming conventions. dtrace(1) uses the output filename to generate +# an include guard, so we can't use a pipeline to transform its output. +Include/pydtrace_probes.h: $(srcdir)/Include/pydtrace.d + $(MKDIR_P) Include + CC="$(CC)" CFLAGS="$(CFLAGS)" $(DTRACE) $(DFLAGS) -o $@ -h -s $(srcdir)/Include/pydtrace.d + : sed in-place edit with POSIX-only tools + sed 's/PYTHON_/PyDTrace_/' $@ > $@.tmp + mv $@.tmp $@ + +Python/ceval.o: $(srcdir)/Include/pydtrace.h +Python/gc.o: $(srcdir)/Include/pydtrace.h +Python/import.o: $(srcdir)/Include/pydtrace.h + +Python/pydtrace.o: $(srcdir)/Include/pydtrace.d $(DTRACE_DEPS) + CC="$(CC)" CFLAGS="$(CFLAGS)" $(DTRACE) $(DFLAGS) -o $@ -G -s $(srcdir)/Include/pydtrace.d $(DTRACE_DEPS) + +.PHONY: regen-typeslots +regen-typeslots: + echo 'NOTE: "regen-typeslots" was renamed to "regen-slots"' + $(MAKE) regen-slots + +.PHONY: regen-slots +regen-slots: Python/slots.toml + # Regenerate {Python,Include}/slots_generated.{c,h} + # from Python/slots.toml using Tools/build/generate_slots.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_slots.py \ + --generate-all + +$(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS) + + +###################################################################### + +TESTOPTS= $(EXTRATESTOPTS) +TESTPYTHON= $(RUNSHARED) $(PYTHON_FOR_BUILD) $(TESTPYTHONOPTS) +TESTRUNNER= $(TESTPYTHON) -m test +TESTTIMEOUT= + +# Remove "test_python_*" directories of previous failed test jobs. +# Pass TESTOPTS options because it can contain --tempdir option. +.PHONY: cleantest +cleantest: all + $(TESTRUNNER) $(TESTOPTS) --cleanup + +# Run a basic set of regression tests. +# This excludes some tests that are particularly resource-intensive. +# Similar to buildbottest, but use --fast-ci option, instead of --slow-ci. +.PHONY: test +test: all + $(TESTRUNNER) --fast-ci -u-gui --timeout=$(TESTTIMEOUT) $(TESTOPTS) + +# Run a basic set of regression tests inside the CI. +# This excludes some tests that are particularly resource-intensive. +# Similar to test, but also runs GUI tests. +ci: all + $(TESTRUNNER) --fast-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) + +# Run the test suite for both architectures in a Universal build on OSX. +# Must be run on an Intel box. +.PHONY: testuniversal +testuniversal: all + @if [ `arch` != 'i386' ]; then \ + echo "This can only be used on OSX/i386" ;\ + exit 1 ;\ + fi + $(TESTRUNNER) --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) + $(RUNSHARED) /usr/libexec/oah/translate \ + ./$(BUILDPYTHON) -E -m test -j 0 -u all $(TESTOPTS) + +# Run the test suite on the iOS simulator. Must be run on a macOS machine with +# a full Xcode install that has an iPhone SE (3rd edition) simulator available. +# This must be run *after* a `make install` has completed the build. The +# `--with-framework-name` argument *cannot* be used when configuring the build. +XCFOLDER:=iOSTestbed.$(MULTIARCH).$(shell date +%s).$$PPID +.PHONY: testios +testios: + @if test "$(MACHDEP)" != "ios"; then \ + echo "Cannot run the iOS testbed for a non-iOS build."; \ + exit 1;\ + fi + @if test "$(findstring -iphonesimulator,$(MULTIARCH))" != "-iphonesimulator"; then \ + echo "Cannot run the iOS testbed for non-simulator builds."; \ + exit 1;\ + fi + @if test $(PYTHONFRAMEWORK) != "Python"; then \ + echo "Cannot run the iOS testbed with a non-default framework name."; \ + exit 1;\ + fi + @if ! test -d $(PYTHONFRAMEWORKPREFIX); then \ + echo "Cannot find a finalized iOS Python.framework. Have you run 'make install' to finalize the framework build?"; \ + exit 1;\ + fi + + # Clone the testbed project into the XCFOLDER + $(PYTHON_FOR_BUILD) $(srcdir)/Platforms/Apple/testbed clone --framework $(PYTHONFRAMEWORKPREFIX) "$(XCFOLDER)" + + # Run the testbed project + $(PYTHON_FOR_BUILD) "$(XCFOLDER)" run --verbose -- test -uall --single-process --rerun -W --pythoninfo + +# Like test, but using --slow-ci which enables all test resources and use +# longer timeout. Run an optional pybuildbot.identify script to include +# information about the build environment. +.PHONY: buildbottest +buildbottest: all + -@if which pybuildbot.identify >/dev/null 2>&1; then \ + pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ + fi + $(TESTRUNNER) --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) + +.PHONY: pythoninfo +pythoninfo: all + $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo + +QUICKTESTOPTS= -x test_subprocess test_io \ + test_multibytecodec test_urllib2_localnet test_itertools \ + test_multiprocessing_fork test_multiprocessing_spawn \ + test_multiprocessing_forkserver \ + test_mailbox test_socket test_poll \ + test_select test_zipfile test_concurrent_futures + +.PHONY: quicktest +quicktest: all + $(TESTRUNNER) --fast-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) $(QUICKTESTOPTS) + +# SSL tests +.PHONY: multisslcompile +multisslcompile: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py --steps=modules + +.PHONY: multissltest +multissltest: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py + +# All install targets use the "all" target as synchronization point to +# prevent race conditions with PGO builds. PGO builds use recursive make, +# which can lead to two parallel `./python setup.py build` processes that +# step on each others toes. +# Only the main install gets a build-details.json. +.PHONY: install +install: @FRAMEWORKINSTALLFIRST@ @INSTALLTARGETS@ @FRAMEWORKINSTALLLAST@ + $(INSTALL_DATA) `cat pybuilddir.txt`/$(BUILD_DETAILS) $(DESTDIR)$(LIBDEST); \ + if test "x$(ENSUREPIP)" != "xno" ; then \ + case $(ENSUREPIP) in \ + upgrade) ensurepip="--upgrade" ;; \ + install|*) ensurepip="" ;; \ + esac; \ + $(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \ + $$ensurepip --root=$(DESTDIR)/ ; \ + fi + +.PHONY: altinstall +altinstall: commoninstall + if test "x$(ENSUREPIP)" != "xno" ; then \ + case $(ENSUREPIP) in \ + upgrade) ensurepip="--altinstall --upgrade" ;; \ + install|*) ensurepip="--altinstall" ;; \ + esac; \ + $(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \ + $$ensurepip --root=$(DESTDIR)/ ; \ + fi + +.PHONY: commoninstall +commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ + altbininstall libinstall inclinstall libainstall \ + sharedinstall altmaninstall @FRAMEWORKALTINSTALLLAST@ + +# Install shared libraries enabled by Setup +DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) + +.PHONY: sharedinstall +sharedinstall: all + @for i in $(DESTDIRS); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ + echo "Creating directory $$i"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \ + else true; \ + fi; \ + done + @for i in X $(SHAREDMODS); do \ + if test $$i != X; then \ + echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \ + $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + if test -d "$$i.dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + fi; \ + fi; \ + done + +# Install the interpreter with $(VERSION) affixed +# This goes into $(exec_prefix) +.PHONY: altbininstall +altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ + @for i in $(BINDIR) $(LIBDIR); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ + echo "Creating directory $$i"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \ + else true; \ + fi; \ + done + if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ + $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + else \ + $(INSTALL_PROGRAM) $(STRIPFLAG) Mac/pythonw $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + fi + -if test "$(VERSION)" != "$(LDVERSION)"; then \ + if test -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE) -o -h $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ + then rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ + fi; \ + (cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE)); \ + fi + @if test "$(PY_ENABLE_SHARED)" = 1 -o "$(STATIC_LIBPYTHON)" = 1; then \ + if test -f $(LDLIBRARY) && test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ + if test -n "$(DLLLIBRARY)" ; then \ + $(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \ + else \ + $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + if test $(LDLIBRARY) != $(INSTSONAME); then \ + (cd $(DESTDIR)$(LIBDIR); $(LN) -sf $(INSTSONAME) $(LDLIBRARY)) \ + fi \ + fi; \ + if test -n "$(PY3LIBRARY)"; then \ + $(INSTALL_SHARED) $(PY3LIBRARY) $(DESTDIR)$(LIBDIR)/$(PY3LIBRARY); \ + fi; \ + else true; \ + fi; \ + fi + if test "x$(LIPO_32BIT_FLAGS)" != "x" ; then \ + rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)-32$(EXE); \ + lipo $(LIPO_32BIT_FLAGS) \ + -output $(DESTDIR)$(BINDIR)/python$(VERSION)-32$(EXE) \ + $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ + fi + if test "x$(LIPO_INTEL64_FLAGS)" != "x" ; then \ + rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)-intel64$(EXE); \ + lipo $(LIPO_INTEL64_FLAGS) \ + -output $(DESTDIR)$(BINDIR)/python$(VERSION)-intel64$(EXE) \ + $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ + fi + # Install macOS debug information (if available) + if test -d "$(BUILDPYTHON).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + fi + if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + fi \ + else \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + fi \ + fi + +.PHONY: bininstall +# We depend on commoninstall here to make sure the installation is already usable +# before we possibly overwrite the global 'python3' symlink to avoid causing +# problems for anything else trying to run 'python3' while we install, particularly +# if we're installing in parallel with -j. +bininstall: commoninstall altbininstall + if test ! -d $(DESTDIR)$(LIBPC); then \ + echo "Creating directory $(LIBPC)"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(LIBPC); \ + fi + -if test -f $(DESTDIR)$(BINDIR)/python3$(EXE) -o -h $(DESTDIR)$(BINDIR)/python3$(EXE); \ + then rm -f $(DESTDIR)$(BINDIR)/python3$(EXE); \ + else true; \ + fi + (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)$(EXE) python3$(EXE)) + -if test "$(VERSION)" != "$(LDVERSION)"; then \ + rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)-config; \ + (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(LDVERSION)-config python$(VERSION)-config); \ + rm -f $(DESTDIR)$(LIBPC)/python-$(VERSION).pc; \ + (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(LDVERSION).pc python-$(VERSION).pc); \ + rm -f $(DESTDIR)$(LIBPC)/python-$(VERSION)-embed.pc; \ + (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(LDVERSION)-embed.pc python-$(VERSION)-embed.pc); \ + fi + -rm -f $(DESTDIR)$(BINDIR)/python3-config + (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python3-config) + -rm -f $(DESTDIR)$(LIBPC)/python3.pc + (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python3.pc) + -rm -f $(DESTDIR)$(LIBPC)/python3-embed.pc + (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION)-embed.pc python3-embed.pc) + -rm -f $(DESTDIR)$(BINDIR)/idle3 + (cd $(DESTDIR)$(BINDIR); $(LN) -s idle$(VERSION) idle3) + -rm -f $(DESTDIR)$(BINDIR)/pydoc3 + (cd $(DESTDIR)$(BINDIR); $(LN) -s pydoc$(VERSION) pydoc3) + if test "x$(LIPO_32BIT_FLAGS)" != "x" ; then \ + rm -f $(DESTDIR)$(BINDIR)/python3-32$(EXE); \ + (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-32$(EXE) python3-32$(EXE)) \ + fi + if test "x$(LIPO_INTEL64_FLAGS)" != "x" ; then \ + rm -f $(DESTDIR)$(BINDIR)/python3-intel64$(EXE); \ + (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-intel64$(EXE) python3-intel64$(EXE)) \ + fi + +# Install the versioned manual page +.PHONY: altmaninstall +altmaninstall: + @for i in $(MANDIR) $(MANDIR)/man1; \ + do \ + if test ! -d $(DESTDIR)$$i; then \ + echo "Creating directory $$i"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \ + else true; \ + fi; \ + done + $(INSTALL_DATA) $(srcdir)/Misc/python.man \ + $(DESTDIR)$(MANDIR)/man1/python$(VERSION).1 + +# Install the unversioned manual page +.PHONY: maninstall +maninstall: altmaninstall + -rm -f $(DESTDIR)$(MANDIR)/man1/python3.1 + (cd $(DESTDIR)$(MANDIR)/man1; $(LN) -s python$(VERSION).1 python3.1) + +# Install the library +XMLLIBSUBDIRS= xml xml/dom xml/etree xml/parsers xml/sax +LIBSUBDIRS= asyncio \ + collections \ + compression compression/_common compression/zstd \ + concurrent concurrent/futures concurrent/interpreters \ + csv \ + ctypes ctypes/macholib \ + curses \ + dbm \ + email email/mime \ + encodings \ + ensurepip ensurepip/_bundled \ + html \ + http \ + idlelib idlelib/Icons \ + importlib importlib/resources importlib/metadata \ + json \ + logging \ + multiprocessing multiprocessing/dummy \ + pathlib \ + profile \ + profiling profiling/sampling profiling/tracing \ + profiling/sampling/_assets \ + profiling/sampling/_heatmap_assets \ + profiling/sampling/_flamegraph_assets \ + profiling/sampling/_shared_assets \ + profiling/sampling/live_collector \ + profiling/sampling/_vendor/d3/7.8.5 \ + profiling/sampling/_vendor/d3-flame-graph/4.1.3 \ + pydoc_data \ + re \ + site-packages \ + sqlite3 \ + string \ + sysconfig \ + tkinter \ + tomllib \ + turtledemo \ + unittest \ + urllib \ + venv venv/scripts venv/scripts/common venv/scripts/posix \ + wsgiref \ + $(XMLLIBSUBDIRS) \ + xmlrpc \ + zipfile zipfile/_path \ + zoneinfo \ + _pyrepl \ + __phello__ +TESTSUBDIRS= idlelib/idle_test \ + test \ + test/test_ast \ + test/test_ast/data \ + test/archivetestdata \ + test/audit_test_data \ + test/audiodata \ + test/certdata \ + test/certdata/capath \ + test/cjkencodings \ + test/configdata \ + test/crashers \ + test/data \ + test/decimaltestdata \ + test/dtracedata \ + test/encoded_modules \ + test/leakers \ + test/libregrtest \ + test/mathdata \ + test/regrtestdata \ + test/regrtestdata/import_from_tests \ + test/regrtestdata/import_from_tests/test_regrtest_b \ + test/subprocessdata \ + test/support \ + test/support/_hypothesis_stubs \ + test/test_asyncio \ + test/test_capi \ + test/test_cext \ + test/test_concurrent_futures \ + test/test_cppext \ + test/test_ctypes \ + test/test_dataclasses \ + test/test_doctest \ + test/test_email \ + test/test_email/data \ + test/test_free_threading \ + test/test_future_stmt \ + test/test_gdb \ + test/test_import \ + test/test_import/data \ + test/test_import/data/circular_imports \ + test/test_import/data/circular_imports/subpkg \ + test/test_import/data/circular_imports/subpkg2 \ + test/test_import/data/circular_imports/subpkg2/parent \ + test/test_import/data/package \ + test/test_import/data/package2 \ + test/test_import/data/package3 \ + test/test_import/data/package4 \ + test/test_import/data/unwritable \ + test/test_importlib \ + test/test_importlib/builtin \ + test/test_importlib/extension \ + test/test_importlib/frozen \ + test/test_importlib/import_ \ + test/test_importlib/metadata \ + test/test_importlib/metadata/data \ + test/test_importlib/metadata/data/sources \ + test/test_importlib/metadata/data/sources/example \ + test/test_importlib/metadata/data/sources/example/example \ + test/test_importlib/metadata/data/sources/example2 \ + test/test_importlib/metadata/data/sources/example2/example2 \ + test/test_importlib/namespace_pkgs \ + test/test_importlib/namespace_pkgs/both_portions \ + test/test_importlib/namespace_pkgs/both_portions/foo \ + test/test_importlib/namespace_pkgs/foo \ + test/test_importlib/namespace_pkgs/module_and_namespace_package \ + test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test \ + test/test_importlib/namespace_pkgs/not_a_namespace_pkg \ + test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo \ + test/test_importlib/namespace_pkgs/portion1 \ + test/test_importlib/namespace_pkgs/portion1/foo \ + test/test_importlib/namespace_pkgs/portion2 \ + test/test_importlib/namespace_pkgs/portion2/foo \ + test/test_importlib/namespace_pkgs/project1 \ + test/test_importlib/namespace_pkgs/project1/parent \ + test/test_importlib/namespace_pkgs/project1/parent/child \ + test/test_importlib/namespace_pkgs/project2 \ + test/test_importlib/namespace_pkgs/project2/parent \ + test/test_importlib/namespace_pkgs/project2/parent/child \ + test/test_importlib/namespace_pkgs/project3 \ + test/test_importlib/namespace_pkgs/project3/parent \ + test/test_importlib/namespace_pkgs/project3/parent/child \ + test/test_importlib/partial \ + test/test_importlib/resources \ + test/test_importlib/source \ + test/test_inspect \ + test/test_interpreters \ + test/test_io \ + test/test_json \ + test/test_lazy_import \ + test/test_lazy_import/data \ + test/test_lazy_import/data/pkg \ + test/test_lazy_import/data/badsyntax \ + test/test_lazy_import/data/circular_import_pkg \ + test/test_lazy_import/data/lazypkg \ + test/test_lazy_import/data/metasyntactic \ + test/test_lazy_import/data/metasyntactic/foo \ + test/test_lazy_import/data/metasyntactic/foo/ack \ + test/test_lazy_import/data/metasyntactic/foo/bar \ + test/test_lazy_import/data/metasyntactic/foo/bar/baz \ + test/test_lazy_import/data/metasyntactic/foo/bar/baz/qux \ + test/test_lazy_import/data/metasyntactic/foo/bar/thud \ + test/test_lazy_import/data/metasyntactic/plugh \ + test/test_lazy_import/data/metasyntactic/waldo \ + test/test_lazy_import/data/metasyntactic/waldo/fred \ + test/test_lazy_import/data/module_same_name_var_order1 \ + test/test_lazy_import/data/module_same_name_var_order2 \ + test/test_lazy_import/data/versioned \ + test/test_module \ + test/test_multiprocessing_fork \ + test/test_multiprocessing_forkserver \ + test/test_multiprocessing_spawn \ + test/test_os \ + test/test_pathlib \ + test/test_pathlib/support \ + test/test_peg_generator \ + test/test_profiling \ + test/test_profiling/test_sampling_profiler \ + test/test_pydoc \ + test/test_pyrepl \ + test/test_string \ + test/test_sqlite3 \ + test/test_tkinter \ + test/test_tomllib \ + test/test_tomllib/data \ + test/test_tomllib/data/invalid \ + test/test_tomllib/data/invalid/array \ + test/test_tomllib/data/invalid/array-of-tables \ + test/test_tomllib/data/invalid/boolean \ + test/test_tomllib/data/invalid/dates-and-times \ + test/test_tomllib/data/invalid/dotted-keys \ + test/test_tomllib/data/invalid/inline-table \ + test/test_tomllib/data/invalid/keys-and-vals \ + test/test_tomllib/data/invalid/literal-str \ + test/test_tomllib/data/invalid/multiline-basic-str \ + test/test_tomllib/data/invalid/multiline-literal-str \ + test/test_tomllib/data/invalid/table \ + test/test_tomllib/data/valid \ + test/test_tomllib/data/valid/array \ + test/test_tomllib/data/valid/dates-and-times \ + test/test_tomllib/data/valid/inline-table \ + test/test_tomllib/data/valid/multiline-basic-str \ + test/test_tools \ + test/test_tools/i18n_data \ + test/test_tools/msgfmt_data \ + test/test_ttk \ + test/test_unittest \ + test/test_unittest/namespace_test_pkg \ + test/test_unittest/namespace_test_pkg/bar \ + test/test_unittest/namespace_test_pkg/noop \ + test/test_unittest/namespace_test_pkg/noop/no2 \ + test/test_unittest/testmock \ + test/test_warnings \ + test/test_warnings/data \ + test/test_zipfile \ + test/test_zipfile/_path \ + test/test_zoneinfo \ + test/test_zoneinfo/data \ + test/tkinterdata \ + test/tokenizedata \ + test/tracedmodules \ + test/translationdata \ + test/translationdata/argparse \ + test/translationdata/getopt \ + test/translationdata/optparse \ + test/typinganndata \ + test/typinganndata/partialexecution \ + test/wheeldata \ + test/xmltestdata \ + test/xmltestdata/c14n-20 \ + test/zipimport_data + +COMPILEALL_OPTS=-j0 + +TEST_MODULES=@TEST_MODULES@ + +.PHONY: libinstall +libinstall: all $(srcdir)/Modules/xxmodule.c + @for i in $(SCRIPTDIR) $(LIBDEST); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ + echo "Creating directory $$i"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \ + else true; \ + fi; \ + done + @if test "$(TEST_MODULES)" = yes; then \ + subdirs="$(LIBSUBDIRS) $(TESTSUBDIRS)"; \ + else \ + subdirs="$(LIBSUBDIRS)"; \ + fi; \ + for d in $$subdirs; \ + do \ + a=$(srcdir)/Lib/$$d; \ + if test ! -d $$a; then continue; else true; fi; \ + b=$(LIBDEST)/$$d; \ + if test ! -d $(DESTDIR)$$b; then \ + echo "Creating directory $$b"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$b; \ + else true; \ + fi; \ + done + @for i in $(srcdir)/Lib/*.py; \ + do \ + if test -x $$i; then \ + $(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \ + echo $(INSTALL_SCRIPT) $$i $(LIBDEST); \ + else \ + $(INSTALL_DATA) $$i $(DESTDIR)$(LIBDEST); \ + echo $(INSTALL_DATA) $$i $(LIBDEST); \ + fi; \ + done + @if test "$(TEST_MODULES)" = yes; then \ + subdirs="$(LIBSUBDIRS) $(TESTSUBDIRS)"; \ + else \ + subdirs="$(LIBSUBDIRS)"; \ + fi; \ + for d in $$subdirs; \ + do \ + a=$(srcdir)/Lib/$$d; \ + if test ! -d $$a; then continue; else true; fi; \ + if test `ls $$a | wc -l` -lt 1; then continue; fi; \ + b=$(LIBDEST)/$$d; \ + for i in $$a/*; \ + do \ + case $$i in \ + *CVS) ;; \ + *.py[co]) ;; \ + *.orig) ;; \ + *~) ;; \ + *) \ + if test -d $$i; then continue; fi; \ + if test -x $$i; then \ + echo $(INSTALL_SCRIPT) $$i $$b; \ + $(INSTALL_SCRIPT) $$i $(DESTDIR)$$b; \ + else \ + echo $(INSTALL_DATA) $$i $$b; \ + $(INSTALL_DATA) $$i $(DESTDIR)$$b; \ + fi;; \ + esac; \ + done; \ + done + $(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py $(DESTDIR)$(LIBDEST); \ + $(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfig_vars_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).json $(DESTDIR)$(LIBDEST); \ + $(INSTALL_DATA) `cat pybuilddir.txt`/_missing_stdlib_info.py $(DESTDIR)$(LIBDEST); \ + $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt + @ # If app store compliance has been configured, apply the patch to the + @ # installed library code. The patch has been previously validated against + @ # the original source tree, so we can ignore any errors that are raised + @ # due to files that are missing because of --disable-test-modules etc. + @if [ "$(APP_STORE_COMPLIANCE_PATCH)" != "" ]; then \ + echo "Applying app store compliance patch"; \ + patch --force --reject-file "$(abs_builddir)/app-store-compliance.rej" --strip 2 --directory "$(DESTDIR)$(LIBDEST)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)" || true ; \ + fi + @ # Build PYC files for the 3 optimization levels (0, 1, 2) + -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ + $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ + -o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST) -f \ + -x 'bad_coding|badsyntax|site-packages' \ + $(DESTDIR)$(LIBDEST) + -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ + $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ + -o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST)/site-packages -f \ + -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages + +# bpo-21536: Misc/python-config.sh is generated in the build directory +# from $(srcdir)Misc/python-config.sh.in. +python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh + @ # Substitution happens here, as the completely-expanded BINDIR + @ # is not available in configure + sed -e "s,@EXENAME@,$(EXENAME)," < $(srcdir)/Misc/python-config.in >python-config.py + @ # Replace makefile compat. variable references with shell script compat. ones; $(VAR) -> ${VAR} + LC_ALL=C sed -e 's,\$$(\([A-Za-z0-9_]*\)),\$$\{\1\},g' < Misc/python-config.sh >python-config + @ # On Darwin, always use the python version of the script, the shell + @ # version doesn't use the compiler customizations that are provided + @ # in python (_osx_support.py). + @if test `uname -s` = Darwin; then \ + cp python-config.py python-config; \ + fi + +# macOS' make seems to ignore a dependency on a +# "$(BUILD_SCRIPTS_DIR): $(MKDIR_P) $@" rule. +BUILD_SCRIPTS_DIR=build/scripts-$(VERSION) +SCRIPT_IDLE=$(BUILD_SCRIPTS_DIR)/idle$(VERSION) +SCRIPT_PYDOC=$(BUILD_SCRIPTS_DIR)/pydoc$(VERSION) + +$(SCRIPT_IDLE): $(srcdir)/Tools/scripts/idle3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/idle3 > $@ + @chmod +x $@ + +$(SCRIPT_PYDOC): $(srcdir)/Tools/scripts/pydoc3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/pydoc3 > $@ + @chmod +x $@ + +.PHONY: scripts +scripts: $(SCRIPT_IDLE) $(SCRIPT_PYDOC) python-config + +# Install the include files +INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY) + +.PHONY: inclinstall +inclinstall: + @for i in $(INCLDIRSTOMAKE); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ + echo "Creating directory $$i"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \ + else true; \ + fi; \ + done + @if test ! -d $(DESTDIR)$(INCLUDEPY)/cpython; then \ + echo "Creating directory $(DESTDIR)$(INCLUDEPY)/cpython"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(INCLUDEPY)/cpython; \ + else true; \ + fi + @if test ! -d $(DESTDIR)$(INCLUDEPY)/internal; then \ + echo "Creating directory $(DESTDIR)$(INCLUDEPY)/internal"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(INCLUDEPY)/internal; \ + else true; \ + fi + @if test "$(INSTALL_MIMALLOC)" = "yes"; then \ + if test ! -d $(DESTDIR)$(INCLUDEPY)/internal/mimalloc/mimalloc; then \ + echo "Creating directory $(DESTDIR)$(INCLUDEPY)/internal/mimalloc/mimalloc"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(INCLUDEPY)/internal/mimalloc/mimalloc; \ + fi; \ + fi + @for i in $(srcdir)/Include/*.h; \ + do \ + echo $(INSTALL_DATA) $$i $(INCLUDEPY); \ + $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY); \ + done + @for i in $(srcdir)/Include/cpython/*.h; \ + do \ + echo $(INSTALL_DATA) $$i $(INCLUDEPY)/cpython; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY)/cpython; \ + done + @for i in $(srcdir)/Include/internal/*.h; \ + do \ + echo $(INSTALL_DATA) $$i $(INCLUDEPY)/internal; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY)/internal; \ + done + @if test "$(INSTALL_MIMALLOC)" = "yes"; then \ + echo $(INSTALL_DATA) $(srcdir)/Include/internal/mimalloc/mimalloc.h $(DESTDIR)$(INCLUDEPY)/internal/mimalloc/mimalloc.h; \ + $(INSTALL_DATA) $(srcdir)/Include/internal/mimalloc/mimalloc.h $(DESTDIR)$(INCLUDEPY)/internal/mimalloc/mimalloc.h; \ + for i in $(srcdir)/Include/internal/mimalloc/mimalloc/*.h; \ + do \ + echo $(INSTALL_DATA) $$i $(INCLUDEPY)/internal/mimalloc/mimalloc; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY)/internal/mimalloc/mimalloc; \ + done; \ + fi + echo $(INSTALL_DATA) pyconfig.h $(DESTDIR)$(CONFINCLUDEPY)/pyconfig.h + $(INSTALL_DATA) pyconfig.h $(DESTDIR)$(CONFINCLUDEPY)/pyconfig.h + +# Install the library and miscellaneous stuff needed for extending/embedding +# This goes into $(exec_prefix) +LIBPL= @LIBPL@ + +# pkgconfig directory +LIBPC= $(LIBDIR)/pkgconfig + +.PHONY: libainstall +libainstall: all scripts + @for i in $(LIBDIR) $(LIBPL) $(LIBPC) $(BINDIR); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ + echo "Creating directory $$i"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \ + else true; \ + fi; \ + done + @if test "$(STATIC_LIBPYTHON)" = 1; then \ + if test -d $(LIBRARY); then :; else \ + if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ + if test "$(SHLIB_SUFFIX)" = .dll; then \ + $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \ + else \ + $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ + fi; \ + else \ + echo Skip install of $(LIBRARY) - use make frameworkinstall; \ + fi; \ + fi; \ + $(INSTALL_DATA) Programs/python.o $(DESTDIR)$(LIBPL)/python.o; \ + fi + $(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c + $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in + $(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile + $(INSTALL_DATA) $(srcdir)/Modules/Setup $(DESTDIR)$(LIBPL)/Setup + $(INSTALL_DATA) Modules/Setup.bootstrap $(DESTDIR)$(LIBPL)/Setup.bootstrap + $(INSTALL_DATA) Modules/Setup.stdlib $(DESTDIR)$(LIBPL)/Setup.stdlib + $(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local + $(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(LDVERSION).pc + $(INSTALL_DATA) Misc/python-embed.pc $(DESTDIR)$(LIBPC)/python-$(LDVERSION)-embed.pc + $(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup + $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh + $(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py + $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(LDVERSION)-config + $(INSTALL_SCRIPT) $(SCRIPT_IDLE) $(DESTDIR)$(BINDIR)/idle$(VERSION) + $(INSTALL_SCRIPT) $(SCRIPT_PYDOC) $(DESTDIR)$(BINDIR)/pydoc$(VERSION) + @if [ -s Modules/python.exp -a \ + "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \ + echo; echo "Installing support files for building shared extension modules on AIX:"; \ + $(INSTALL_DATA) Modules/python.exp \ + $(DESTDIR)$(LIBPL)/python.exp; \ + echo; echo "$(LIBPL)/python.exp"; \ + $(INSTALL_SCRIPT) $(srcdir)/Modules/makexp_aix \ + $(DESTDIR)$(LIBPL)/makexp_aix; \ + echo "$(LIBPL)/makexp_aix"; \ + $(INSTALL_SCRIPT) Modules/ld_so_aix \ + $(DESTDIR)$(LIBPL)/ld_so_aix; \ + echo "$(LIBPL)/ld_so_aix"; \ + echo; echo "See Misc/README.AIX for details."; \ + else true; \ + fi + +# Here are a couple of targets for MacOSX again, to install a full +# framework-based Python. frameworkinstall installs everything, the +# subtargets install specific parts. Much of the actual work is offloaded to +# the Makefile in Mac +# +# +# This target is here for backward compatibility, previous versions of Python +# hadn't integrated framework installation in the normal install process. +.PHONY: frameworkinstall +frameworkinstall: install + +# On install, we re-make the framework +# structure in the install location, /Library/Frameworks/ or the argument to +# --enable-framework. If --enable-framework has been specified then we have +# automatically set prefix to the location deep down in the framework, so we +# only have to cater for the structural bits of the framework. + +.PHONY: frameworkinstallframework +frameworkinstallframework: @FRAMEWORKINSTALLFIRST@ install frameworkinstallmaclib + +# macOS uses a versioned frameworks structure that includes a full install +.PHONY: frameworkinstallversionedstructure +frameworkinstallversionedstructure: $(LDLIBRARY) + @if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ + echo Not configured with --enable-framework; \ + exit 1; \ + else true; \ + fi + @for i in $(prefix)/Resources/English.lproj $(prefix)/lib; do\ + if test ! -d $(DESTDIR)$$i; then \ + echo "Creating directory $(DESTDIR)$$i"; \ + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \ + else true; \ + fi; \ + done + $(LN) -fsn include/python$(LDVERSION) $(DESTDIR)$(prefix)/Headers + sed 's/%VERSION%/'"`$(RUNSHARED) ./$(BUILDPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > $(DESTDIR)$(prefix)/Resources/Info.plist + $(LN) -fsn $(VERSION) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current + $(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/$(PYTHONFRAMEWORK) + $(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers + $(LN) -fsn Versions/Current/Resources $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Resources + $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY) + +# iOS/tvOS/watchOS uses a non-versioned framework with Info.plist in the +# framework root, no .lproj data, and only stub compilation assistance binaries +.PHONY: frameworkinstallunversionedstructure +frameworkinstallunversionedstructure: $(LDLIBRARY) + @if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ + echo Not configured with --enable-framework; \ + exit 1; \ + else true; \ + fi + if test -d $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/include; then \ + echo "Clearing stale header symlink directory"; \ + rm -rf $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/include; \ + fi + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR) + sed 's/%VERSION%/'"`$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Info.plist + $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY) + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(LIBDIR) + $(LN) -fs "../$(LDLIBRARY)" "$(DESTDIR)$(prefix)/lib/libpython$(LDVERSION).dylib" + $(LN) -fs "../$(LDLIBRARY)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(BINDIR) + for file in $(srcdir)/$(RESSRCDIR)/bin/* ; do \ + $(INSTALL) -m $(EXEMODE) $$file $(DESTDIR)$(BINDIR); \ + done + +# This installs Mac/Lib into the framework +# Install a number of symlinks to keep software that expects a normal unix +# install (which includes python-config) happy. +.PHONY: frameworkinstallmaclib +frameworkinstallmaclib: + $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).a" + $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).dylib" + $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(VERSION).a" + $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(VERSION).dylib" + $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(LDVERSION).dylib" + $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" + +# This installs the IDE, the Launcher and other apps into /Applications +.PHONY: frameworkinstallapps +frameworkinstallapps: + cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)" + +# Build the bootstrap executable that will spawn the interpreter inside +# an app bundle within the framework. This allows the interpreter to +# run OS X GUI APIs. +.PHONY: frameworkpythonw +frameworkpythonw: + cd Mac && $(MAKE) pythonw + +# This installs the python* and other bin symlinks in $prefix/bin or in +# a bin directory relative to the framework root +.PHONY: frameworkinstallunixtools +frameworkinstallunixtools: + cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)" + +.PHONY: frameworkaltinstallunixtools +frameworkaltinstallunixtools: + cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)" + +# This installs the Tools into the applications directory. +# It is not part of a normal frameworkinstall +.PHONY: frameworkinstallextras +frameworkinstallextras: + cd Mac && $(MAKE) installextras DESTDIR="$(DESTDIR)" + +# On iOS, bin/lib can't live inside the framework; include needs to be called +# "Headers", but *must* be in the framework, and *not* include the `python3.X` +# subdirectory. The install has put these folders in the same folder as +# Python.framework; Move the headers to their final framework-compatible home. +.PHONY: frameworkinstallmobileheaders +frameworkinstallmobileheaders: frameworkinstallunversionedstructure inclinstall + if test -d $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers; then \ + echo "Removing old framework headers"; \ + rm -rf $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers; \ + fi + mv "$(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/include/python$(LDVERSION)" "$(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers" + $(LN) -fs "../$(PYTHONFRAMEWORKDIR)/Headers" "$(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/include/python$(LDVERSION)" + +# Build the toplevel Makefile +Makefile.pre: $(srcdir)/Makefile.pre.in config.status + CONFIG_FILES=Makefile.pre CONFIG_HEADERS= ./config.status + $(MAKE) -f Makefile.pre Makefile + +# Run the configure script. +config.status: $(srcdir)/configure + $(srcdir)/configure $(CONFIG_ARGS) + +.PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre + +Python/asm_trampoline_x86_64.o: $(srcdir)/Python/asm_trampoline_x86_64.S + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + +Python/asm_trampoline_aarch64.o: $(srcdir)/Python/asm_trampoline_aarch64.S + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + +Python/asm_trampoline_riscv64.o: $(srcdir)/Python/asm_trampoline_riscv64.S + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + +# On macOS universal2 builds, $(PY_CORE_CFLAGS) contains "-arch arm64 -arch x86_64", +# which would produce fat .o files containing both architectures for each .S input. +# lipo -create then refuses to combine them because they share architectures. +# Build each per-arch object with a single -arch flag before merging with lipo. +Python/asm_trampoline_universal2.o: $(srcdir)/Python/asm_trampoline_aarch64.S $(srcdir)/Python/asm_trampoline_x86_64.S + $(CC) -c $(filter-out -arch arm64 x86_64,$(PY_CORE_CFLAGS)) -arch arm64 \ + -o Python/asm_trampoline_arm64-apple-darwin.o $(srcdir)/Python/asm_trampoline_aarch64.S + $(CC) -c $(filter-out -arch arm64 x86_64,$(PY_CORE_CFLAGS)) -arch x86_64 \ + -o Python/asm_trampoline_x86_64-apple-darwin.o $(srcdir)/Python/asm_trampoline_x86_64.S + lipo -create -output $@ \ + Python/asm_trampoline_arm64-apple-darwin.o \ + Python/asm_trampoline_x86_64-apple-darwin.o + rm -f Python/asm_trampoline_arm64-apple-darwin.o \ + Python/asm_trampoline_x86_64-apple-darwin.o + +Python/emscripten_trampoline_inner.wasm: $(srcdir)/Python/emscripten_trampoline_inner.c + # emcc has a path that ends with emsdk/upstream/emscripten/emcc, we're looking for emsdk/upstream/bin/clang. + $$(em-config LLVM_ROOT)/clang -o $@ $< -mgc -O2 -Wl,--no-entry -Wl,--import-table -Wl,--import-memory -target wasm32-unknown-unknown -nostdlib + +Python/emscripten_trampoline_wasm.c: Python/emscripten_trampoline_inner.wasm + $(PYTHON_FOR_REGEN) $(srcdir)/Platforms/emscripten/prepare_external_wasm.py $< $@ getWasmTrampolineModule + +JIT_SHIM_BUILD_OBJS= @JIT_SHIM_BUILD_O@ +JIT_UNWIND_INFO_H= $(if $(JIT_OBJS),jit_unwind_info.h $(patsubst jit_stencils-%.h,jit_unwind_info-%.h,@JIT_STENCILS_H@)) +JIT_BUILD_TARGETS= jit_stencils.h @JIT_STENCILS_H@ $(JIT_UNWIND_INFO_H) $(JIT_SHIM_BUILD_OBJS) +JIT_TARGETS= $(JIT_BUILD_TARGETS) $(filter-out $(JIT_SHIM_BUILD_OBJS),$(JIT_OBJS)) +JIT_GENERATED_STAMP= .jit-stamp + +JIT_DEPS = \ + $(srcdir)/Tools/jit/*.c \ + $(srcdir)/Tools/jit/*.h \ + $(srcdir)/Tools/jit/*.py \ + $(srcdir)/Python/executor_cases.c.h \ + pyconfig.h + +$(JIT_GENERATED_STAMP): $(JIT_DEPS) + @REGEN_JIT_COMMAND@ + @touch $@ + +$(JIT_BUILD_TARGETS): $(JIT_GENERATED_STAMP) + @if test ! -f "$@"; then \ + rm -f $(JIT_GENERATED_STAMP); \ + $(MAKE) $(JIT_GENERATED_STAMP); \ + test -f "$@"; \ + fi + +jit_shim-universal2-apple-darwin.o: jit_shim-aarch64-apple-darwin.o jit_shim-x86_64-apple-darwin.o + lipo -create -output $@ jit_shim-aarch64-apple-darwin.o jit_shim-x86_64-apple-darwin.o + +Python/jit.o: $(srcdir)/Python/jit.c @JIT_STENCILS_H@ + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + +Python/jit_unwind.o: $(srcdir)/Python/jit_unwind.c $(JIT_UNWIND_INFO_H) + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + +.PHONY: regen-jit +regen-jit: $(JIT_TARGETS) + +# Some make's put the object file in the current directory +.c.o: + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + +# bpo-30104: dtoa.c uses union to cast double to unsigned long[2]. clang 4.0 +# with -O2 or higher and strict aliasing miscompiles the ratio() function +# causing rounding issues. Compile dtoa.c using -fno-strict-aliasing on clang. +# https://bugs.llvm.org//show_bug.cgi?id=31928 +Python/dtoa.o: Python/dtoa.c + $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_ALIASING) -o $@ $< + +Python/ceval.o: Python/ceval.c + $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_CEVAL) -o $@ $< + +# Run reindent on the library +.PHONY: reindent +reindent: + ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/reindent.py -r $(srcdir)/Lib + +# Rerun configure with the same options as it was run last time, +# provided the config.status script exists +.PHONY: recheck +recheck: + ./config.status --recheck + ./config.status + +# Regenerate configure and pyconfig.h.in +.PHONY: autoconf +autoconf: + (cd $(srcdir); autoreconf -ivf -Werror) + +.PHONY: regen-configure +regen-configure: + $(srcdir)/Tools/build/regen-configure.sh + +.PHONY: regen-sbom +regen-sbom: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_sbom.py + +# Create a tags file for vi +tags:: + ctags -w $(srcdir)/Include/*.h $(srcdir)/Include/cpython/*.h $(srcdir)/Include/internal/*.h + for i in $(SRCDIRS); do ctags -f tags -w -a $(srcdir)/$$i/*.[ch]; done + ctags -f tags -w -a $(srcdir)/Modules/_ctypes/*.[ch] + find $(srcdir)/Lib -type f -name "*.py" -not -name "test_*.py" -not -path "*/test/*" -not -path "*/tests/*" -not -path "*/*_test/*" | ctags -f tags -w -a -L - + LC_ALL=C sort -o tags tags + +# Create a tags file for GNU Emacs +TAGS:: + cd $(srcdir); \ + etags Include/*.h Include/cpython/*.h Include/internal/*.h; \ + for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done + etags -a $(srcdir)/Modules/_ctypes/*.[ch] + find $(srcdir)/Lib -type f -name "*.py" -not -name "test_*.py" -not -path "*/test/*" -not -path "*/tests/*" -not -path "*/*_test/*" | etags - -a + +# Sanitation targets -- clean leaves libraries, executables and tags +# files, which clobber removes as well +.PHONY: pycremoval +pycremoval: + -find $(srcdir) -depth -name '__pycache__' -exec rm -rf {} ';' + -find $(srcdir) -name '*.py[co]' -exec rm -f {} ';' + +.PHONY: rmtestturds +rmtestturds: + -rm -f *BAD *GOOD *SKIPPED + -rm -rf OUT + -rm -f *.TXT + -rm -f *.txt + -rm -f gb-18030-2000.xml + +.PHONY: docclean +docclean: + $(MAKE) -C $(srcdir)/Doc clean + +# like the 'clean' target but retain the profile guided optimization (PGO) +# data. The PGO data is only valid if source code remains unchanged. +.PHONY: clean-retain-profile +clean-retain-profile: pycremoval + # Keep the generated JIT shim objects with the rest of the JIT generated + # files: they are regenerated as a group and tracked by .jit-stamp. + find . -name '*.[oa]' ! -name 'jit_shim*.o' -exec rm -f {} ';' + find . -name '*.s[ol]' -exec rm -f {} ';' + find . -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';' + find . -name '*.lto' -exec rm -f {} ';' + find . -name '*.wasm' -exec rm -f {} ';' + find . -name '*.lst' -exec rm -f {} ';' + find build -name 'fficonfig.h' -exec rm -f {} ';' || true + find build -name '*.py' -exec rm -f {} ';' || true + find build -name '*.py[co]' -exec rm -f {} ';' || true + -rm -f pybuilddir.txt + -rm -f _bootstrap_python + -rm -rf web_example python.mjs python.wasm python*.symbols python*.map + -rm -f Programs/_testembed Programs/_freeze_module + -rm -rf Python/deepfreeze + -rm -f Python/frozen_modules/*.h + -rm -f Python/frozen_modules/MANIFEST + -find build -type f -a ! -name '*.gc??' -exec rm -f {} ';' + -rm -f Include/pydtrace_probes.h + -rm -f profile-gen-stamp + -rm -rf Platforms/Apple/iOS/testbed/Python.xcframework/ios-*/bin + -rm -rf Platforms/Apple/iOS/testbed/Python.xcframework/ios-*/lib + -rm -rf Platforms/Apple/iOS/testbed/Python.xcframework/ios-*/include + -rm -rf Platforms/Apple/iOS/testbed/Python.xcframework/ios-*/Python.framework + +.PHONY: profile-removal +profile-removal: + find . -name '*.gc??' -exec rm -f {} ';' + find . -name '*.profclang?' -exec rm -f {} ';' + find . -name '*.dyn' -exec rm -f {} ';' + rm -f $(COVERAGE_INFO) + rm -rf $(COVERAGE_REPORT) + rm -f profile-run-stamp + rm -f profile-bolt-stamp + +.PHONY: clean-profile +clean-profile: clean-retain-profile clean-bolt + @if test @DEF_MAKE_ALL_RULE@ = profile-opt -o @DEF_MAKE_ALL_RULE@ = bolt-opt; then \ + rm -f profile-gen-stamp profile-clean-stamp; \ + $(MAKE) profile-removal; \ + fi + +# gh-141808: The JIT stencils are deliberately kept in clean-profile +.PHONY: clean-jit-stencils +clean-jit-stencils: + -rm -f $(JIT_TARGETS) $(JIT_GENERATED_STAMP) jit_stencils*.h jit_unwind_info*.h jit_shim*.o + +.PHONY: clean +clean: clean-profile clean-jit-stencils + +.PHONY: clobber +clobber: clean + -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \ + tags TAGS \ + config.cache config.log pyconfig.h Modules/config.c + -rm -rf build platform + -rm -rf $(PYTHONFRAMEWORKDIR) + -rm -rf Platforms/Apple/iOS/Frameworks + -rm -rf iOSTestbed.* + -rm -f python-config.py python-config + -rm -rf cross-build + +# Make things extra clean, before making a distribution: +# remove all generated files, even Makefile[.pre] +# Keep configure and Python-ast.[ch], it's possible they can't be generated +.PHONY: distclean +distclean: clobber docclean + for file in $(srcdir)/Lib/test/data/* ; do \ + if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \ + done + -rm -f core Makefile Makefile.pre config.status Modules/Setup.local \ + Modules/Setup.bootstrap Modules/Setup.stdlib \ + Modules/ld_so_aix Modules/python.exp Misc/python.pc \ + Misc/python-embed.pc Misc/python-config.sh + -rm -f python*-gdb.py + # Issue #28258: set LC_ALL to avoid issues with Estonian locale. + # Expansion is performed here by shell (spawned by make) itself before + # arguments are passed to find. So LC_ALL=C must be set as a separate + # command. + LC_ALL=C; find $(srcdir)/[a-zA-Z]* '(' -name '*.fdc' -o -name '*~' \ + -o -name '[@,#]*' -o -name '*.old' \ + -o -name '*.orig' -o -name '*.rej' \ + -o -name '*.bak' ')' \ + -exec rm -f {} ';' + +# Check that all symbols exported by libpython start with "Py" or "_Py" +.PHONY: smelly +smelly: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/smelly.py + +# Check if any unsupported C global variables have been added. +.PHONY: check-c-globals +check-c-globals: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/c-analyzer/check-c-globals.py \ + --format summary \ + --traceback + +# Check for undocumented C APIs. +.PHONY: check-c-api-docs +check-c-api-docs: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/check-c-api-docs/main.py + +# Find files with funny names +.PHONY: funny +funny: + find $(SUBDIRS) $(SUBDIRSTOO) \ + -type d \ + -o -name '*.[chs]' \ + -o -name '*.py' \ + -o -name '*.pyw' \ + -o -name '*.dat' \ + -o -name '*.el' \ + -o -name '*.fd' \ + -o -name '*.in' \ + -o -name '*.gif' \ + -o -name '*.txt' \ + -o -name '*.xml' \ + -o -name '*.xbm' \ + -o -name '*.xpm' \ + -o -name '*.uue' \ + -o -name '*.decTest' \ + -o -name '*.tmCommand' \ + -o -name '*.tmSnippet' \ + -o -name 'Setup' \ + -o -name 'Setup.*' \ + -o -name README \ + -o -name NEWS \ + -o -name HISTORY \ + -o -name Makefile \ + -o -name ChangeLog \ + -o -name .hgignore \ + -o -name MANIFEST \ + -o -print + +# Perform some verification checks on any modified files. +.PHONY: patchcheck +patchcheck: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/patchcheck.py + +.PHONY: check-limited-abi +check-limited-abi: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --all + +.PHONY: update-config +update-config: + curl -sL -o config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' + curl -sL -o config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' + chmod +x config.guess config.sub + +# Dependencies + +Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h + +########################################################################## +# Module dependencies and platform-specific files + +# force rebuild when header file or module build flavor (static/shared) is changed +MODULE_DEPS_STATIC=Modules/config.c +MODULE_DEPS_SHARED=@MODULE_DEPS_SHARED@ + +MODULE__CURSES_DEPS=$(srcdir)/Include/py_curses.h +MODULE__CURSES_PANEL_DEPS=$(srcdir)/Include/py_curses.h +MODULE__DATETIME_DEPS=$(srcdir)/Include/datetime.h +MODULE_CMATH_DEPS=$(srcdir)/Modules/_math.h +MODULE_MATH_DEPS=$(srcdir)/Modules/_math.h +MODULE_PYEXPAT_DEPS=@LIBEXPAT_INTERNAL@ +MODULE_UNICODEDATA_DEPS=$(srcdir)/Modules/unicodedata_db.h $(srcdir)/Modules/unicodename_db.h +MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h +MODULE__CTYPES_TEST_DEPS=$(srcdir)/Modules/_ctypes/_ctypes_test_generated.c.h +MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@ +MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@ +MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h $(srcdir)/Modules/_openssl_mem.h +MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h +MODULE__REMOTE_DEBUGGING_DEPS=$(srcdir)/Modules/_remote_debugging/_remote_debugging.h $(srcdir)/Modules/_remote_debugging/gc_stats.h + +# HACL*-based cryptographic primitives +MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__MD5_LDEPS=$(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA1_LDEPS=$(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA2_LDEPS=$(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA3_LDEPS=$(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__BLAKE2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__BLAKE2_LDEPS=$(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__HMAC_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HMAC_HEADERS) $(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__HMAC_LDEPS=$(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@) + +MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c +MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_openssl_mem.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h +MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/parts.h $(srcdir)/Modules/_testcapi/util.h +MODULE__TESTLIMITEDCAPI_DEPS=$(srcdir)/Modules/_testlimitedcapi/testcapi_long.h $(srcdir)/Modules/_testlimitedcapi/parts.h $(srcdir)/Modules/_testlimitedcapi/util.h +MODULE__TESTINTERNALCAPI_DEPS=$(srcdir)/Modules/_testinternalcapi/parts.h $(srcdir)/Parser/tokenizer/cursor.h $(srcdir)/Parser/tokenizer/source.h $(srcdir)/Python/ceval.h $(srcdir)/Modules/_testinternalcapi/test_targets.h $(srcdir)/Modules/_testinternalcapi/test_cases.c.h +MODULE__SQLITE3_DEPS=$(srcdir)/Modules/_sqlite/connection.h $(srcdir)/Modules/_sqlite/cursor.h $(srcdir)/Modules/_sqlite/microprotocols.h $(srcdir)/Modules/_sqlite/module.h $(srcdir)/Modules/_sqlite/prepare_protocol.h $(srcdir)/Modules/_sqlite/row.h $(srcdir)/Modules/_sqlite/util.h +MODULE__ZSTD_DEPS=$(srcdir)/Modules/_zstd/_zstdmodule.h $(srcdir)/Modules/_zstd/buffer.h $(srcdir)/Modules/_zstd/zstddict.h + +CODECS_COMMON_HEADERS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h $(srcdir)/Modules/cjkcodecs/cjkcodecs.h +MODULE__CODECS_CN_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_cn.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_HK_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_hk.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_ISO2022_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_jisx0213_pair.h $(srcdir)/Modules/cjkcodecs/alg_jisx0201.h $(srcdir)/Modules/cjkcodecs/emu_jisx0213_2000.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_JP_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_jisx0213_pair.h $(srcdir)/Modules/cjkcodecs/alg_jisx0201.h $(srcdir)/Modules/cjkcodecs/emu_jisx0213_2000.h $(srcdir)/Modules/cjkcodecs/mappings_jp.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_KR_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_kr.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_TW_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_tw.h $(CODECS_COMMON_HEADERS) +MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# Local Variables: +# mode: makefile +# End: diff --git a/stdlib/kvlang/reference/python/cpython/README.rst b/stdlib/kvlang/reference/python/cpython/README.rst new file mode 100644 index 00000000..0cafee73 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/README.rst @@ -0,0 +1,235 @@ +This is Python version 3.16.0 alpha 0 +===================================== + +.. image:: https://github.com/python/cpython/actions/workflows/build.yml/badge.svg?branch=main&event=push + :alt: CPython build status on GitHub Actions + :target: https://github.com/python/cpython/actions + +.. image:: https://dev.azure.com/python/cpython/_apis/build/status/Azure%20Pipelines%20CI?branchName=main + :alt: CPython build status on Azure DevOps + :target: https://dev.azure.com/python/cpython/_build/latest?definitionId=4&branchName=main + +.. image:: https://img.shields.io/badge/discourse-join_chat-brightgreen.svg + :alt: Python Discourse chat + :target: https://discuss.python.org/ + + +Copyright © 2001 Python Software Foundation. All rights reserved. + +See the end of this file for further copyright and license information. + +.. contents:: + +General Information +------------------- + +- Website: https://www.python.org +- Source code: https://github.com/python/cpython +- Issue tracker: https://github.com/python/cpython/issues +- Documentation: https://docs.python.org +- Developer's Guide: https://devguide.python.org/ + +Contributing to CPython +----------------------- + +For more complete instructions on contributing to CPython development, +see the `Developer Guide`_. + +.. _Developer Guide: https://devguide.python.org/ + +Using Python +------------ + +Installable Python kits, and information about using Python, are available at +`python.org`_. + +.. _python.org: https://www.python.org/ + +Build Instructions +------------------ + +On Unix, Linux, BSD, macOS, and Cygwin:: + + ./configure + make + make test + sudo make install + +This will install Python as ``python3``. + +You can pass many options to the configure script; run ``./configure --help`` +to find out more. On macOS case-insensitive file systems and on Cygwin, +the executable is called ``python.exe``; elsewhere it's just ``python``. + +Building a complete Python installation requires the use of various +additional third-party libraries, depending on your build platform and +configure options. Not all standard library modules are buildable or +usable on all platforms. Refer to the +`Install dependencies <https://devguide.python.org/getting-started/setup-building.html#build-dependencies>`_ +section of the `Developer Guide`_ for current detailed information on +dependencies for various Linux distributions and macOS. + +On macOS, there are additional configure and build options related +to macOS framework and universal builds. Refer to `Mac/README.rst +<https://github.com/python/cpython/blob/main/Mac/README.rst>`_. + +On Windows, see `PCbuild/readme.txt +<https://github.com/python/cpython/blob/main/PCbuild/readme.txt>`_. + +To build Windows packages, see `PC/layout/README.md +<https://github.com/python/cpython/blob/main/PC/layout/README.md>`_. + +If you wish, you can create a subdirectory and invoke configure from there. +For example:: + + mkdir debug + cd debug + ../configure --with-pydebug + make + make test + +(This will fail if you *also* built at the top-level directory. You should do +a ``make clean`` at the top-level first.) + +To get an optimized build of Python, run ``configure --enable-optimizations`` +before you run ``make``. This sets the default make targets up to enable +Profile Guided Optimization (PGO) and may be used to auto-enable Link Time +Optimization (LTO) on some platforms. For more details, see the sections +below. + +Profile Guided Optimization +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +PGO takes advantage of recent versions of the GCC or Clang compilers. If used, +either via ``configure --enable-optimizations`` or by manually running +``make profile-opt`` regardless of configure flags, the optimized build +process will perform the following steps: + +The entire Python directory is cleaned of temporary files that may have +resulted from a previous compilation. + +An instrumented version of the interpreter is built, using suitable compiler +flags for each flavor. Note that this is just an intermediary step. The +binary resulting from this step is not good for real-life workloads as it has +profiling instructions embedded inside. + +After the instrumented interpreter is built, the Makefile will run a training +workload. This is necessary in order to profile the interpreter's execution. +Note also that any output, both stdout and stderr, that may appear at this step +is suppressed. + +The final step is to build the actual interpreter, using the information +collected from the instrumented one. The end result will be a Python binary +that is optimized; suitable for distribution or production installation. + + +Link Time Optimization +^^^^^^^^^^^^^^^^^^^^^^ + +Enabled via configure's ``--with-lto`` flag. LTO takes advantage of the +ability of recent compiler toolchains to optimize across the otherwise +arbitrary ``.o`` file boundary when building final executables or shared +libraries for additional performance gains. + + +What's New +---------- + +We have a comprehensive overview of the changes in the `What's new in Python +3.16 <https://docs.python.org/3.16/whatsnew/3.16.html>`_ document. For a more +detailed change log, read `Misc/NEWS +<https://github.com/python/cpython/tree/main/Misc/NEWS.d>`_, but a full +accounting of changes can only be gleaned from the `commit history +<https://github.com/python/cpython/commits/main>`_. + +If you want to install multiple versions of Python, see the section below +entitled "Installing multiple versions". + + +Documentation +------------- + +`Documentation for Python 3.16 <https://docs.python.org/3.16/>`_ is online, +updated daily. + +It can also be downloaded in many formats for faster access. The documentation +is downloadable in HTML, EPUB, and reStructuredText formats; the latter version +is primarily for documentation authors, translators, and people with special +formatting requirements. + +For information about building Python's documentation, refer to `Doc/README.rst +<https://github.com/python/cpython/blob/main/Doc/README.rst>`_. + + +Testing +------- + +To test the interpreter, type ``make test`` in the top-level directory. The +test set produces some output. You can generally ignore the messages about +skipped tests due to optional features which can't be imported. If a message +is printed about a failed test or a traceback or core dump is produced, +something is wrong. + +By default, tests are prevented from overusing resources like disk space and +memory. To enable these tests, run ``make buildbottest``. + +If any tests fail, you can re-run the failing test(s) in verbose mode. For +example, if ``test_os`` and ``test_gdb`` failed, you can run:: + + make test TESTOPTS="-v test_os test_gdb" + +If the failure persists and appears to be a problem with Python rather than +your environment, you can `file a bug report +<https://github.com/python/cpython/issues>`_ and include relevant output from +that command to show the issue. + +See `Running & Writing Tests <https://devguide.python.org/testing/run-write-tests.html>`_ +for more on running tests. + +Installing multiple versions +---------------------------- + +On Unix and Mac systems if you intend to install multiple versions of Python +using the same installation prefix (``--prefix`` argument to the configure +script) you must take care that your primary python executable is not +overwritten by the installation of a different version. All files and +directories installed using ``make altinstall`` contain the major and minor +version and can thus live side-by-side. ``make install`` also creates +``${prefix}/bin/python3`` which refers to ``${prefix}/bin/python3.X``. If you +intend to install multiple versions using the same prefix you must decide which +version (if any) is your "primary" version. Install that version using +``make install``. Install all other versions using ``make altinstall``. + +For example, if you want to install Python 2.7, 3.6, and 3.15 with 3.15 being the +primary version, you would execute ``make install`` in your 3.15 build directory +and ``make altinstall`` in the others. + + +Release Schedule +---------------- + +See `PEP 826 <https://peps.python.org/pep-0826/>`__ for Python 3.16 release details. + + +Copyright and License Information +--------------------------------- + + +Copyright © 2001 Python Software Foundation. All rights reserved. + +Copyright © 2000 BeOpen.com. All rights reserved. + +Copyright © 1995-2001 Corporation for National Research Initiatives. All +rights reserved. + +Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved. + +See the `LICENSE <https://github.com/python/cpython/blob/main/LICENSE>`_ for +information on the history of this software, terms & conditions for usage, and a +DISCLAIMER OF ALL WARRANTIES. + +This Python distribution contains *no* GNU General Public License (GPL) code, +so it may be used in proprietary projects. There are interfaces to some GNU +code but these are entirely optional. + +All trademarks referenced herein are property of their respective holders. diff --git a/stdlib/kvlang/reference/python/cpython/aclocal.m4 b/stdlib/kvlang/reference/python/cpython/aclocal.m4 new file mode 100644 index 00000000..920c2b38 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/aclocal.m4 @@ -0,0 +1,794 @@ +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +# =============================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_c_float_words_bigendian.html +# =============================================================================== +# +# SYNOPSIS +# +# AX_C_FLOAT_WORDS_BIGENDIAN([ACTION-IF-TRUE], [ACTION-IF-FALSE], [ACTION-IF-UNKNOWN]) +# +# DESCRIPTION +# +# Checks the ordering of words within a multi-word float. This check is +# necessary because on some systems (e.g. certain ARM systems), the float +# word ordering can be different from the byte ordering. In a multi-word +# float context, "big-endian" implies that the word containing the sign +# bit is found in the memory location with the lowest address. This +# implementation was inspired by the AC_C_BIGENDIAN macro in autoconf. +# +# The endianness is detected by first compiling C code that contains a +# special double float value, then grepping the resulting object file for +# certain strings of ASCII values. The double is specially crafted to have +# a binary representation that corresponds with a simple string. In this +# implementation, the string "noonsees" was selected because the +# individual word values ("noon" and "sees") are palindromes, thus making +# this test byte-order agnostic. If grep finds the string "noonsees" in +# the object file, the target platform stores float words in big-endian +# order. If grep finds "seesnoon", float words are in little-endian order. +# If neither value is found, the user is instructed to specify the +# ordering. +# +# Early versions of this macro (i.e., before serial 12) would not work +# when interprocedural optimization (via link-time optimization) was +# enabled. This would happen when, say, the GCC/clang "-flto" flag, or the +# ICC "-ipo" flag was used, for example. The problem was that under +# these conditions, the compiler did not allocate for and write the special +# float value in the data segment of the object file, since doing so might +# not prove optimal once more context was available. Thus, the special value +# (in platform-dependent binary form) could not be found in the object file, +# and the macro would fail. +# +# The solution to the above problem was to: +# +# 1) Compile and link a whole test program rather than just compile an +# object file. This ensures that we reach the point where even an +# interprocedural optimizing compiler writes values to the data segment. +# +# 2) Add code that requires the compiler to write the special value to +# the data segment, as opposed to "optimizing away" the variable's +# allocation. This could be done via compiler keywords or options, but +# it's tricky to make this work for all versions of all compilers with +# all optimization settings. The chosen solution was to make the exit +# code of the test program depend on the storing of the special value +# in memory (in the data segment). Because the exit code can be +# verified, any compiler that aspires to be correct will produce a +# program binary that contains the value, which the macro can then find. +# +# How does the exit code depend on the special value residing in memory? +# Memory, unlike variables and registers, can be addressed indirectly at run +# time. The exit code of this test program is a result of indirectly reading +# and writing to the memory region where the special value is supposed to +# reside. The actual memory addresses used and the values to be written are +# derived from the the program input ("argv") and are therefore not known at +# compile or link time. The compiler has no choice but to defer the +# computation to run time, and to prepare by allocating and populating the +# data segment with the special value. For further details, refer to the +# source code of the test program. +# +# Note that the test program is never meant to be run. It only exists to host +# a double float value in a given platform's binary format. Thus, error +# handling is not included. +# +# LICENSE +# +# Copyright (c) 2008, 2023 Daniel Amelang <dan@amelang.net> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 14 + +AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], + [AC_CACHE_CHECK(whether float word ordering is bigendian, + ax_cv_c_float_words_bigendian, [ + +ax_cv_c_float_words_bigendian=unknown +AC_LINK_IFELSE([AC_LANG_SOURCE([[ + +#include <stdlib.h> + +static double m[] = {9.090423496703681e+223, 0.0}; + +int main (int argc, char *argv[]) +{ + m[atoi (argv[1])] += atof (argv[2]); + return m[atoi (argv[3])] > 0.0; +} + +]])], [ + +if grep noonsees conftest* > /dev/null ; then + ax_cv_c_float_words_bigendian=yes +fi +if grep seesnoon conftest* >/dev/null ; then + if test "$ax_cv_c_float_words_bigendian" = unknown; then + ax_cv_c_float_words_bigendian=no + else + ax_cv_c_float_words_bigendian=unknown + fi +fi + +])]) + +case $ax_cv_c_float_words_bigendian in + yes) + m4_default([$1], + [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1, + [Define to 1 if your system stores words within floats + with the most significant word first])]) ;; + no) + $2 ;; + *) + m4_default([$3], + [AC_MSG_ERROR([ + +Unknown float word ordering. You need to manually preset +ax_cv_c_float_words_bigendian=no (or yes) according to your system. + + ])]) ;; +esac + +])# AX_C_FLOAT_WORDS_BIGENDIAN + +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS + +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_define.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_CHECK_DEFINE([symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# AX_CHECK_DEFINE([includes],[symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# +# DESCRIPTION +# +# Complements AC_CHECK_FUNC but it does not check for a function but for a +# define to exist. Consider a usage like: +# +# AC_CHECK_DEFINE(__STRICT_ANSI__, CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500") +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +AU_ALIAS([AC_CHECK_DEFINED], [AC_CHECK_DEFINE]) +AC_DEFUN([AC_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl +AC_CACHE_CHECK([for $1 defined], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + #ifdef $1 + int ok; + (void)ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AU_ALIAS([AX_CHECK_DEFINED], [AX_CHECK_DEFINE]) +AC_DEFUN([AX_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2_$1])dnl +AC_CACHE_CHECK([for $2 defined in $1], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <$1>]], [[ + #ifdef $2 + int ok; + (void)ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AC_DEFUN([AX_CHECK_FUNC], +[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl +AC_CACHE_CHECK([for $2], ac_var, +dnl AC_LANG_FUNC_LINK_TRY +[AC_LINK_IFELSE([AC_LANG_PROGRAM([$1 + #undef $2 + char $2 ();],[ + char (*f) () = $2; + return f != $2; ])], + [AS_VAR_SET(ac_var, yes)], + [AS_VAR_SET(ac_var, no)])]) +AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +])# AC_CHECK_FUNC + +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_openssl.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_OPENSSL([action-if-found[, action-if-not-found]]) +# +# DESCRIPTION +# +# Look for OpenSSL in a number of default spots, or in a user-selected +# spot (via --with-openssl). Sets +# +# OPENSSL_INCLUDES to the include directives required +# OPENSSL_LIBS to the -l directives required +# OPENSSL_LDFLAGS to the -L or -R flags required +# +# and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately +# +# This macro sets OPENSSL_INCLUDES such that source files should use the +# openssl/ directory in include directives: +# +# #include <openssl/hmac.h> +# +# LICENSE +# +# Copyright (c) 2009,2010 Zmanda Inc. <http://www.zmanda.com/> +# Copyright (c) 2009,2010 Dustin J. Mitchell <dustin@zmanda.com> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL]) +AC_DEFUN([AX_CHECK_OPENSSL], [ + found=false + AC_ARG_WITH([openssl], + [AS_HELP_STRING([--with-openssl=DIR], + [root of the OpenSSL directory])], + [ + case "$withval" in + "" | y | ye | yes | n | no) + AC_MSG_ERROR([Invalid --with-openssl value]) + ;; + *) ssldirs="$withval" + ;; + esac + ], [ + # if pkg-config is installed and openssl has installed a .pc file, + # then use that information and don't search ssldirs + AC_CHECK_TOOL([PKG_CONFIG], [pkg-config]) + if test x"$PKG_CONFIG" != x""; then + OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null` + if test $? = 0; then + OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null` + OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null` + found=true + fi + fi + + # no such luck; use some default ssldirs + if ! $found; then + ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" + fi + ] + ) + + + # note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in + # an 'openssl' subdirectory + + if ! $found; then + OPENSSL_INCLUDES= + for ssldir in $ssldirs; do + AC_MSG_CHECKING([for include/openssl/ssl.h in $ssldir]) + if test -f "$ssldir/include/openssl/ssl.h"; then + OPENSSL_INCLUDES="-I$ssldir/include" + OPENSSL_LDFLAGS="-L$ssldir/lib" + OPENSSL_LIBS="-lssl -lcrypto" + found=true + AC_MSG_RESULT([yes]) + break + else + AC_MSG_RESULT([no]) + fi + done + + # if the file wasn't found, well, go ahead and try the link anyway -- maybe + # it will just work! + fi + + # try the preprocessor and linker with our new flags, + # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS + + AC_MSG_CHECKING([whether compiling and linking against OpenSSL works]) + echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \ + "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&AS_MESSAGE_LOG_FD + + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + save_CPPFLAGS="$CPPFLAGS" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" + LIBS="$OPENSSL_LIBS $LIBS" + CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([#include <openssl/ssl.h>], [SSL_new(NULL)])], + [ + AC_MSG_RESULT([yes]) + $1 + ], [ + AC_MSG_RESULT([no]) + $2 + ]) + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + + AC_SUBST([OPENSSL_INCLUDES]) + AC_SUBST([OPENSSL_LIBS]) + AC_SUBST([OPENSSL_LDFLAGS]) +]) + +# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + +dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.2]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurrence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + +dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------ +dnl +dnl Prepare a "--with-" configure option using the lowercase +dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and +dnl PKG_CHECK_MODULES in a single macro. +AC_DEFUN([PKG_WITH_MODULES], +[ +m4_pushdef([with_arg], m4_tolower([$1])) + +m4_pushdef([description], + [m4_default([$5], [build with ]with_arg[ support])]) + +m4_pushdef([def_arg], [m4_default([$6], [auto])]) +m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) +m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) + +m4_case(def_arg, + [yes],[m4_pushdef([with_without], [--without-]with_arg)], + [m4_pushdef([with_without],[--with-]with_arg)]) + +AC_ARG_WITH(with_arg, + AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, + [AS_TR_SH([with_]with_arg)=def_arg]) + +AS_CASE([$AS_TR_SH([with_]with_arg)], + [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], + [auto],[PKG_CHECK_MODULES([$1],[$2], + [m4_n([def_action_if_found]) $3], + [m4_n([def_action_if_not_found]) $4])]) + +m4_popdef([with_arg]) +m4_popdef([description]) +m4_popdef([def_arg]) + +])dnl PKG_WITH_MODULES + +dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ----------------------------------------------- +dnl +dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES +dnl check._[VARIABLE-PREFIX] is exported as make variable. +AC_DEFUN([PKG_HAVE_WITH_MODULES], +[ +PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) + +AM_CONDITIONAL([HAVE_][$1], + [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) +])dnl PKG_HAVE_WITH_MODULES + +dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------------------ +dnl +dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after +dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make +dnl and preprocessor variable. +AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], +[ +PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) + +AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], + [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) +])dnl PKG_HAVE_DEFINE_WITH_MODULES + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 2006-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + diff --git a/stdlib/kvlang/reference/python/cpython/config.guess b/stdlib/kvlang/reference/python/cpython/config.guess new file mode 100755 index 00000000..cdfc4392 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/config.guess @@ -0,0 +1,1807 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2023 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2023-08-22' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <https://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to <config-patches@gnu.org>. + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system '$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2023 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Just in case it came from the environment. +GUESS= + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case $UNAME_SYSTEM in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else + #include <features.h> + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #else + #include <stdarg.h> + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + #endif + EOF + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + GUESS=$machine-${os}${release}${abi-} + ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; + *:ekkoBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; + *:SolidBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; + macppc:MirBSD:*:*) + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; + *:MirBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; + alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; + Amiga*:UNIX_System_V:4.0:*) + GUESS=m68k-unknown-sysv4 + ;; + *:[Aa]miga[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; + *:[Mm]orph[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-morphos + ;; + *:OS/390:*:*) + GUESS=i370-ibm-openedition + ;; + *:z/VM:*:*) + GUESS=s390-ibm-zvmoe + ;; + *:OS400:*:*) + GUESS=powerpc-ibm-os400 + ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + GUESS=arm-unknown-riscos + ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + GUESS=hppa1.1-hitachi-hiuxmpp + ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; + NILE*:*:*:dcosx) + GUESS=pyramid-pyramid-svr4 + ;; + DRS?6000:unix:4.0:6*) + GUESS=sparc-icl-nx6 + ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; + s390x:SunOS:*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; + sun4H:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; + sun4*:SunOS:*:*) + case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like '4.1.3-JL'. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; + sun3*:SunOS:*:*) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in + sun3) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) + GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac + ;; + aushp:SunOS:*:*) + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; + m68k:machten:*:*) + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; + powerpc:machten:*:*) + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; + RISC*:Mach:*:*) + GUESS=mips-dec-mach_bsd4.3 + ;; + RISC*:ULTRIX:*:*) + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; + VAX*:ULTRIX*:*:*) + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; + Motorola:PowerMAX_OS:*:*) + GUESS=powerpc-motorola-powermax + ;; + Motorola:*:4.3:PL8-*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:Power_UNIX:*:*) + GUESS=powerpc-harris-powerunix + ;; + m88k:CX/UX:7*:*) + GUESS=m88k-harris-cxux7 + ;; + m88k:*:4*:R4*) + GUESS=m88k-motorola-sysv4 + ;; + m88k:*:3*:R3*) + GUESS=m88k-motorola-sysv3 + ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + GUESS=m88k-dg-dgux$UNAME_RELEASE + else + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else + GUESS=i586-dg-dgux$UNAME_RELEASE + fi + ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + GUESS=m88k-dolphin-sysv3 + ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + GUESS=m88k-motorola-sysv3 + ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + GUESS=m88k-tektronix-sysv3 + ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + GUESS=m68k-tektronix-bsd + ;; + *:IRIX*:*:*) + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + GUESS=i386-ibm-aix + ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + GUESS=$SYSTEM_NAME + else + GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + GUESS=rs6000-ibm-aix3.2.4 + else + GUESS=rs6000-ibm-aix3.2 + fi + ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; + *:AIX:*:*) + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + GUESS=rs6000-bull-bosx + ;; + DPX/2?00:B.O.S.:*:*) + GUESS=m68k-bull-sysv3 + ;; + 9000/[34]??:4.3bsd:1.*:*) + GUESS=m68k-hp-bsd + ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + GUESS=m68k-hp-bsd4.4 + ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; + 9000/8??:4.3bsd:*:*) + GUESS=hppa1.0-hp-bsd + ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; + hp8??:OSF1:*:*) + GUESS=hppa1.0-hp-osf + ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk + else + GUESS=$UNAME_MACHINE-unknown-osf1 + fi + ;; + parisc*:Lites*:*:*) + GUESS=hppa1.1-hp-lites + ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + GUESS=c1-convex-bsd + ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + GUESS=c34-convex-bsd + ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + GUESS=c38-convex-bsd + ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + GUESS=c4-convex-bsd + ;; + CRAY*Y-MP:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; + CRAY*T3E:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; + CRAY*SV1:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; + *:UNICOS/mp:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; + sparc*:BSD/OS:*:*) + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; + *:BSD/OS:*:*) + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; + i*:CYGWIN*:*) + GUESS=$UNAME_MACHINE-pc-cygwin + ;; + *:MINGW64*:*) + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; + *:MINGW*:*) + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; + i*:PW*:*) + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + GUESS=i586-pc-interix$UNAME_RELEASE + ;; + authenticamd | genuineintel | EM64T) + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; + IA64) + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; + esac ;; + i*:UWIN*:*) + GUESS=$UNAME_MACHINE-pc-uwin + ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + GUESS=x86_64-pc-cygwin + ;; + prep*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; + *:GNU:*:*) + # the GNU system + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI + ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi + ;; + avr32*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + cris:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + crisv32:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + frv:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + hexagon:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:Linux:*:*) + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; + ia64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m32r*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m68*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + padre:Linux:*:*) + GUESS=sparc-unknown-linux-$LIBC + ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + GUESS=hppa64-unknown-linux-$LIBC + ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; + esac + ;; + ppc64:Linux:*:*) + GUESS=powerpc64-unknown-linux-$LIBC + ;; + ppc:Linux:*:*) + GUESS=powerpc-unknown-linux-$LIBC + ;; + ppc64le:Linux:*:*) + GUESS=powerpc64le-unknown-linux-$LIBC + ;; + ppcle:Linux:*:*) + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + s390:Linux:*:* | s390x:Linux:*:*) + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; + sh64*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sh*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + tile*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + vax:Linux:*:*) + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; + x86_64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac + fi + GUESS=$CPU-pc-linux-$LIBCABI + ;; + xtensa*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + GUESS=i386-sequent-sysv4 + ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; + i*86:OS/2:*:*) + # If we were able to find 'uname', then EMX Unix compatibility + # is probably installed. + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; + i*86:XTS-300:*:STOP) + GUESS=$UNAME_MACHINE-unknown-stop + ;; + i*86:atheos:*:*) + GUESS=$UNAME_MACHINE-unknown-atheos + ;; + i*86:syllable:*:*) + GUESS=$UNAME_MACHINE-pc-syllable + ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; + i*86:*DOS:*:*) + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi + ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv32 + fi + ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + GUESS=i586-pc-msdosdjgpp + ;; + Intel:Mach:3*:*) + GUESS=i386-pc-mach3 + ;; + paragon:*:*:*) + GUESS=i860-intel-osf1 + ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi + ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + GUESS=m68010-convergent-sysv + ;; + mc68k:UNIX:SYSTEM5:3.51m) + GUESS=m68k-convergent-sysv + ;; + M680?0:D-NIX:5.3:*) + GUESS=m68k-diab-dnix + ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; + mc68030:UNIX_System_V:4.*:*) + GUESS=m68k-atari-sysv4 + ;; + TSUNAMI:LynxOS:2.*:*) + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; + rs6000:LynxOS:2.*:*) + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; + SM[BE]S:UNIX_SV:*:*) + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; + RM*:ReliantUNIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + RM*:SINIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 + else + GUESS=ns32k-sni-sysv + fi + ;; + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + GUESS=i586-unisys-sysv4 + ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + GUESS=hppa1.1-stratus-sysv4 + ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + GUESS=i860-stratus-sysv4 + ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=$UNAME_MACHINE-stratus-vos + ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=hppa1.1-stratus-vos + ;; + mc68*:A/UX:*:*) + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; + news*:NEWS-OS:6*:*) + GUESS=mips-sony-newsos6 + ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE + else + GUESS=mips-unknown-sysv$UNAME_RELEASE + fi + ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + GUESS=powerpc-be-beos + ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + GUESS=powerpc-apple-beos + ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + GUESS=i586-pc-beos + ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + GUESS=i586-pc-haiku + ;; + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku + ;; + SX-4:SUPER-UX:*:*) + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; + SX-5:SUPER-UX:*:*) + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; + SX-6:SUPER-UX:*:*) + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; + SX-7:SUPER-UX:*:*) + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; + SX-8:SUPER-UX:*:*) + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; + SX-8R:SUPER-UX:*:*) + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; + Power*:Rhapsody:*:*) + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; + *:Rhapsody:*:*) + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; + *:QNX:*:4*) + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; + NSE-*:NONSTOP_KERNEL:*:*) + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; + *:NonStop-UX:*:*) + GUESS=mips-compaq-nonstopux + ;; + BS2000:POSIX*:*:*) + GUESS=bs2000-siemens-sysv + ;; + DS/*:UNIX_System_V:*:*) + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype + fi + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; + *:TOPS-10:*:*) + GUESS=pdp10-unknown-tops10 + ;; + *:TENEX:*:*) + GUESS=pdp10-unknown-tenex + ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + GUESS=pdp10-dec-tops20 + ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + GUESS=pdp10-xkl-tops20 + ;; + *:TOPS-20:*:*) + GUESS=pdp10-unknown-tops20 + ;; + *:ITS:*:*) + GUESS=pdp10-unknown-its + ;; + SEI:*:*:SEIUX) + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; + *:DragonFly:*:*) + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) + GUESS=i386-pc-xenix + ;; + i*86:skyos:*:*) + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; + i*86:rdos:*:*) + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; + x86_64:VMkernel:*:*) + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" <<EOF +#ifdef _SEQUENT_ +#include <sys/types.h> +#include <sys/utsname.h> +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include <signal.h> +#if defined(_SIZE_T_) || defined(SIGLOST) +#include <sys/utsname.h> +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include <sys/param.h> +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <<EOF + +NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize +the system type. Please install a C compiler and try again. +EOF + ;; +esac + +cat >&2 <<EOF + +This script (version $timestamp), has failed to recognize the +operating system you are using. If your script is old, overwrite *all* +copies of config.guess and config.sub with the latest versions from: + + https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +and + https://git.savannah.gnu.org/cgit/config.git/plain/config.sub +EOF + +our_year=`echo $timestamp | sed 's,-.*,,'` +thisyear=`date +%Y` +# shellcheck disable=SC2003 +script_age=`expr "$thisyear" - "$our_year"` +if test "$script_age" -lt 3 ; then + cat >&2 <<EOF + +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/stdlib/kvlang/reference/python/cpython/config.sub b/stdlib/kvlang/reference/python/cpython/config.sub new file mode 100755 index 00000000..1bb6a05d --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/config.sub @@ -0,0 +1,1974 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2024 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +# Patched 2024-02-03 to include support for arm64_32 and iOS/tvOS/watchOS simulators +timestamp='2024-01-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <https://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to <config-patches@gnu.org>. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2024 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <<EOF +$1 +EOF +IFS=$saved_IFS + +# Separate into logical components for further validation +case $1 in + *-*-*-*-*) + echo "Invalid configuration '$1': more than four components" >&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <<EOF +$basic_machine +EOF + IFS=$saved_IFS + ;; + # We use 'pc' rather than 'unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + cpu=$basic_machine + vendor=pc + ;; + # These rules are duplicated from below for sake of the special case above; + # i.e. things that normalized to x86 arches should also default to "pc" + pc98) + cpu=i386 + vendor=pc + ;; + x64 | amd64) + cpu=x86_64 + vendor=pc + ;; + # Recognize the basic CPU types without company name. + *) + cpu=$basic_machine + vendor=unknown + ;; +esac + +unset -v basic_machine + +# Decode basic machines in the full and proper CPU-Company form. +case $cpu-$vendor in + # Here we handle the default manufacturer of certain CPU types in canonical form. It is in + # some cases the only manufacturer, in others, it is the most popular. + craynv-unknown) + vendor=cray + basic_os=${basic_os:-unicosmp} + ;; + c90-unknown | c90-cray) + vendor=cray + basic_os=${Basic_os:-unicos} + ;; + fx80-unknown) + vendor=alliant + ;; + romp-unknown) + vendor=ibm + ;; + mmix-unknown) + vendor=knuth + ;; + microblaze-unknown | microblazeel-unknown) + vendor=xilinx + ;; + rs6000-unknown) + vendor=ibm + ;; + vax-unknown) + vendor=dec + ;; + pdp11-unknown) + vendor=dec + ;; + we32k-unknown) + vendor=att + ;; + cydra-unknown) + vendor=cydrome + ;; + i370-ibm*) + vendor=ibm + ;; + orion-unknown) + vendor=highlevel + ;; + xps-unknown | xps100-unknown) + cpu=xps100 + vendor=honeywell + ;; + + # Here we normalize CPU types with a missing or matching vendor + armh-unknown | armh-alt) + cpu=armv7l + vendor=alt + basic_os=${basic_os:-linux-gnueabihf} + ;; + dpx20-unknown | dpx20-bull) + cpu=rs6000 + vendor=bull + basic_os=${basic_os:-bosx} + ;; + + # Here we normalize CPU types irrespective of the vendor + amd64-*) + cpu=x86_64 + ;; + blackfin-*) + cpu=bfin + basic_os=linux + ;; + c54x-*) + cpu=tic54x + ;; + c55x-*) + cpu=tic55x + ;; + c6x-*) + cpu=tic6x + ;; + e500v[12]-*) + cpu=powerpc + basic_os=${basic_os}"spe" + ;; + mips3*-*) + cpu=mips64 + ;; + ms1-*) + cpu=mt + ;; + m68knommu-*) + cpu=m68k + basic_os=linux + ;; + m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) + cpu=s12z + ;; + openrisc-*) + cpu=or32 + ;; + parisc-*) + cpu=hppa + basic_os=linux + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + cpu=i586 + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) + cpu=i686 + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + cpu=i686 + ;; + pentium4-*) + cpu=i786 + ;; + pc98-*) + cpu=i386 + ;; + ppc-* | ppcbe-*) + cpu=powerpc + ;; + ppcle-* | powerpclittle-*) + cpu=powerpcle + ;; + ppc64-*) + cpu=powerpc64 + ;; + ppc64le-* | powerpc64little-*) + cpu=powerpc64le + ;; + sb1-*) + cpu=mipsisa64sb1 + ;; + sb1el-*) + cpu=mipsisa64sb1el + ;; + sh5e[lb]-*) + cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` + ;; + spur-*) + cpu=spur + ;; + strongarm-* | thumb-*) + cpu=arm + ;; + tx39-*) + cpu=mipstx39 + ;; + tx39el-*) + cpu=mipstx39el + ;; + x64-*) + cpu=x86_64 + ;; + xscale-* | xscalee[bl]-*) + cpu=`echo "$cpu" | sed 's/^xscale/arm/'` + ;; + arm64-* | aarch64le-* | arm64_32-*) + cpu=aarch64 + ;; + + # Recognize the canonical CPU Types that limit and/or modify the + # company names they are paired with. + cr16-*) + basic_os=${basic_os:-elf} + ;; + crisv32-* | etraxfs*-*) + cpu=crisv32 + vendor=axis + ;; + cris-* | etrax*-*) + cpu=cris + vendor=axis + ;; + crx-*) + basic_os=${basic_os:-elf} + ;; + neo-tandem) + cpu=neo + vendor=tandem + ;; + nse-tandem) + cpu=nse + vendor=tandem + ;; + nsr-tandem) + cpu=nsr + vendor=tandem + ;; + nsv-tandem) + cpu=nsv + vendor=tandem + ;; + nsx-tandem) + cpu=nsx + vendor=tandem + ;; + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony + ;; + tile*-*) + basic_os=${basic_os:-linux-gnu} + ;; + + *) + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb | arc32 | arc64 \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | javascript \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | kvx \ + | le32 | le64 \ + | lm32 \ + | loongarch32 | loongarch64 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips* \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nanomips* \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | thumbv7* \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | vc4 \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x"$basic_os" != x +then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +obj= +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <<EOF +$basic_os +EOF + IFS=$saved_IFS + ;; + # Default OS when just kernel was specified + nto*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto|qnx|'` + ;; + linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|linux|gnu|'` + ;; + managarm*) + kernel=managarm + os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` + ;; + *) + kernel= + os=$basic_os + ;; +esac + +# Now, normalize the OS (knowing we just have one component, it's not a kernel, +# etc.) +case $os in + # First match some system type aliases that might get confused + # with valid system types. + # solaris* is a basic system type, with this one exception. + auroraux) + os=auroraux + ;; + bluegene*) + os=cnk + ;; + solaris1 | solaris1.*) + os=`echo "$os" | sed -e 's|solaris1|sunos4|'` + ;; + solaris) + os=solaris2 + ;; + unixware*) + os=sysv4.2uw + ;; + # es1800 is here to avoid being matched by es* (a different OS) + es1800*) + os=ose + ;; + # Some version numbers need modification + chorusos*) + os=chorusos + ;; + isc) + os=isc2.2 + ;; + sco6) + os=sco5v6 + ;; + sco5) + os=sco3.2v5 + ;; + sco4) + os=sco3.2v4 + ;; + sco3.2.[4-9]*) + os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'` + ;; + sco*v* | scout) + # Don't match below + ;; + sco*) + os=sco3.2v2 + ;; + psos*) + os=psos + ;; + qnx*) + os=qnx + ;; + hiux*) + os=hiuxwe2 + ;; + lynx*178) + os=lynxos178 + ;; + lynx*5) + os=lynxos5 + ;; + lynxos*) + # don't get caught up in next wildcard + ;; + lynx*) + os=lynxos + ;; + mac[0-9]*) + os=`echo "$os" | sed -e 's|mac|macos|'` + ;; + opened*) + os=openedition + ;; + os400*) + os=os400 + ;; + sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` + ;; + sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` + ;; + wince*) + os=wince + ;; + utek*) + os=bsd + ;; + dynix*) + os=bsd + ;; + acis*) + os=aos + ;; + atheos*) + os=atheos + ;; + syllable*) + os=syllable + ;; + 386bsd) + os=bsd + ;; + ctix* | uts*) + os=sysv + ;; + nova*) + os=rtmk-nova + ;; + ns2) + os=nextstep2 + ;; + # Preserve the version number of sinix5. + sinix5.*) + os=`echo "$os" | sed -e 's|sinix|sysv|'` + ;; + sinix*) + os=sysv4 + ;; + tpf*) + os=tpf + ;; + triton*) + os=sysv3 + ;; + oss*) + os=sysv3 + ;; + svr4*) + os=sysv4 + ;; + svr3) + os=sysv3 + ;; + sysvr4) + os=sysv4 + ;; + ose*) + os=ose + ;; + *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) + os=mint + ;; + dicos*) + os=dicos + ;; + pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $cpu in + arm*) + os=eabi + ;; + *) + os= + obj=elf + ;; + esac + ;; + aout* | coff* | elf* | pe*) + # These are machine code file formats, not OSes + obj=$os + os= + ;; + *) + # No normalization, but not necessarily accepted, that comes below. + ;; +esac + +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +kernel= +obj= +case $cpu-$vendor in + score-*) + os= + obj=elf + ;; + spu-*) + os= + obj=elf + ;; + *-acorn) + os=riscix1.2 + ;; + arm*-rebel) + kernel=linux + os=gnu + ;; + arm*-semi) + os= + obj=aout + ;; + c4x-* | tic4x-*) + os= + obj=coff + ;; + c8051-*) + os= + obj=elf + ;; + clipper-intergraph) + os=clix + ;; + hexagon-*) + os= + obj=elf + ;; + tic54x-*) + os= + obj=coff + ;; + tic55x-*) + os= + obj=coff + ;; + tic6x-*) + os= + obj=coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=tops20 + ;; + pdp11-*) + os=none + ;; + *-dec | vax-*) + os=ultrix4.2 + ;; + m68*-apollo) + os=domain + ;; + i386-sun) + os=sunos4.0.2 + ;; + m68000-sun) + os=sunos3 + ;; + m68*-cisco) + os= + obj=aout + ;; + mep-*) + os= + obj=elf + ;; + mips*-cisco) + os= + obj=elf + ;; + mips*-*|nanomips*-*) + os= + obj=elf + ;; + or32-*) + os= + obj=coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=sysv3 + ;; + sparc-* | *-sun) + os=sunos4.1.1 + ;; + pru-*) + os= + obj=elf + ;; + *-be) + os=beos + ;; + *-ibm) + os=aix + ;; + *-knuth) + os=mmixware + ;; + *-wec) + os=proelf + ;; + *-winbond) + os=proelf + ;; + *-oki) + os=proelf + ;; + *-hp) + os=hpux + ;; + *-hitachi) + os=hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=sysv + ;; + *-cbm) + os=amigaos + ;; + *-dg) + os=dgux + ;; + *-dolphin) + os=sysv3 + ;; + m68k-ccur) + os=rtu + ;; + m88k-omron*) + os=luna + ;; + *-next) + os=nextstep + ;; + *-sequent) + os=ptx + ;; + *-crds) + os=unos + ;; + *-ns) + os=genix + ;; + i370-*) + os=mvs + ;; + *-gould) + os=sysv + ;; + *-highlevel) + os=bsd + ;; + *-encore) + os=bsd + ;; + *-sgi) + os=irix + ;; + *-siemens) + os=sysv4 + ;; + *-masscomp) + os=rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=uxpv + ;; + *-rom68k) + os= + obj=coff + ;; + *-*bug) + os= + obj=coff + ;; + *-apple) + os=macos + ;; + *-atari*) + os=mint + ;; + *-wrs) + os=vxworks + ;; + *) + os=none + ;; +esac + +fi + +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). + +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + llvm* | musl* | newlib* | relibc* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # See `case $cpu-$os` validation below + ghcjs) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ + | fiwix* | mlibc* | cos* | mbr* | ironclad* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + # This refers to builds using the UEFI calling convention + # (which depends on the architecture) and PE file format. + # Note that this is both a different calling convention and + # different file format than that of GNU-EFI + # (x86_64-w64-mingw32). + uefi) + ;; + none) + ;; + kernel* | msvc* ) + # Restricted further below + ;; + '') + if test x"$obj" = x + then + echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 + fi + ;; + *) + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) + ;; + windows*-msvc*-) + ;; + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 + ;; + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 + ;; + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) + ;; + *-eabi*- | *-gnueabi*-) + ;; + ios*-simulator- | tvos*-simulator- | watchos*-simulator- ) + ;; + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) + # Blank kernel with real OS is always fine. + ;; + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/stdlib/kvlang/reference/python/cpython/configure b/stdlib/kvlang/reference/python/cpython/configure new file mode 100755 index 00000000..7e484426 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/configure @@ -0,0 +1,40255 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.72 for python 3.16. +# +# Report bugs to <https://github.com/python/cpython/issues/>. +# +# +# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else case e in #( + e) case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi +if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as 'sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed 'exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else case e in #( + e) case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : + +else case e in #( + e) exitcode=1; echo positional parameters were not saved. ;; +esac +fi +test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null +then : + as_have_required=yes +else case e in #( + e) as_have_required=no ;; +esac +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : + +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$as_shell as_have_required=yes + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : + break 2 +fi +fi + done;; + esac + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else case e in #( + e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi ;; +esac +fi + + + if test "x$CONFIG_SHELL" != x +then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed 'exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." + else + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and +$0: https://github.com/python/cpython/issues/ about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi ;; +esac +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else case e in #( + e) as_fn_append () + { + eval $1=\$$1\$2 + } ;; +esac +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else case e in #( + e) as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } ;; +esac +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + t clear + :clear + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated + +# Sed expression to map a string onto a valid variable name. +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='python' +PACKAGE_TARNAME='python' +PACKAGE_VERSION='3.16' +PACKAGE_STRING='python 3.16' +PACKAGE_BUGREPORT='https://github.com/python/cpython/issues/' +PACKAGE_URL='' + +ac_unique_file="Include/object.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stddef.h> +#ifdef HAVE_STDIO_H +# include <stdio.h> +#endif +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#endif +#ifdef HAVE_STRING_H +# include <string.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_header_c_list= +ac_func_c_list= +ac_subst_vars='LTLIBOBJS +MODULE_BLOCK +JIT_SHIM_BUILD_O +JIT_SHIM_O +JIT_STENCILS_H +MODULE_XXLIMITED_3_13_FALSE +MODULE_XXLIMITED_3_13_TRUE +MODULE_XXLIMITED_35_FALSE +MODULE_XXLIMITED_35_TRUE +MODULE_XXLIMITED_FALSE +MODULE_XXLIMITED_TRUE +MODULE__CTYPES_TEST_FALSE +MODULE__CTYPES_TEST_TRUE +MODULE__XXTESTFUZZ_FALSE +MODULE__XXTESTFUZZ_TRUE +MODULE_XXSUBTYPE_FALSE +MODULE_XXSUBTYPE_TRUE +MODULE__TESTSINGLEPHASE_FALSE +MODULE__TESTSINGLEPHASE_TRUE +MODULE__TESTMULTIPHASE_FALSE +MODULE__TESTMULTIPHASE_TRUE +MODULE__TESTIMPORTMULTIPLE_FALSE +MODULE__TESTIMPORTMULTIPLE_TRUE +MODULE__TESTBUFFER_FALSE +MODULE__TESTBUFFER_TRUE +MODULE__TESTINTERNALCAPI_FALSE +MODULE__TESTINTERNALCAPI_TRUE +MODULE__TESTLIMITEDCAPI_FALSE +MODULE__TESTLIMITEDCAPI_TRUE +MODULE__TESTCLINIC_LIMITED_FALSE +MODULE__TESTCLINIC_LIMITED_TRUE +MODULE__TESTCLINIC_FALSE +MODULE__TESTCLINIC_TRUE +MODULE__TESTCAPI_FALSE +MODULE__TESTCAPI_TRUE +MODULE__HASHLIB_FALSE +MODULE__HASHLIB_TRUE +MODULE__SSL_FALSE +MODULE__SSL_TRUE +MODULE__ZSTD_FALSE +MODULE__ZSTD_TRUE +MODULE__LZMA_FALSE +MODULE__LZMA_TRUE +MODULE__BZ2_FALSE +MODULE__BZ2_TRUE +MODULE_BINASCII_FALSE +MODULE_BINASCII_TRUE +MODULE_ZLIB_FALSE +MODULE_ZLIB_TRUE +MODULE__UUID_FALSE +MODULE__UUID_TRUE +MODULE__TKINTER_FALSE +MODULE__TKINTER_TRUE +MODULE__SQLITE3_FALSE +MODULE__SQLITE3_TRUE +MODULE_READLINE_FALSE +MODULE_READLINE_TRUE +MODULE__GDBM_FALSE +MODULE__GDBM_TRUE +MODULE__DBM_FALSE +MODULE__DBM_TRUE +MODULE__DECIMAL_FALSE +MODULE__DECIMAL_TRUE +MODULE__CURSES_PANEL_FALSE +MODULE__CURSES_PANEL_TRUE +MODULE__CURSES_FALSE +MODULE__CURSES_TRUE +MODULE__CTYPES_FALSE +MODULE__CTYPES_TRUE +MODULE__HMAC_FALSE +MODULE__HMAC_TRUE +MODULE__BLAKE2_FALSE +MODULE__BLAKE2_TRUE +MODULE__SHA3_FALSE +MODULE__SHA3_TRUE +MODULE__SHA2_FALSE +MODULE__SHA2_TRUE +MODULE__SHA1_FALSE +MODULE__SHA1_TRUE +MODULE__MD5_FALSE +MODULE__MD5_TRUE +LIBHACL_LDEPS_LIBTYPE +LIBHACL_BLAKE2_SIMD256_OBJS +LIBHACL_SIMD256_FLAGS +LIBHACL_BLAKE2_SIMD128_OBJS +LIBHACL_SIMD128_FLAGS +LIBHACL_LDFLAGS +LIBHACL_CFLAGS +MODULE_UNICODEDATA_FALSE +MODULE_UNICODEDATA_TRUE +MODULE__MULTIBYTECODEC_FALSE +MODULE__MULTIBYTECODEC_TRUE +MODULE__CODECS_TW_FALSE +MODULE__CODECS_TW_TRUE +MODULE__CODECS_KR_FALSE +MODULE__CODECS_KR_TRUE +MODULE__CODECS_JP_FALSE +MODULE__CODECS_JP_TRUE +MODULE__CODECS_ISO2022_FALSE +MODULE__CODECS_ISO2022_TRUE +MODULE__CODECS_HK_FALSE +MODULE__CODECS_HK_TRUE +MODULE__CODECS_CN_FALSE +MODULE__CODECS_CN_TRUE +MODULE__ELEMENTTREE_FALSE +MODULE__ELEMENTTREE_TRUE +MODULE_PYEXPAT_FALSE +MODULE_PYEXPAT_TRUE +MODULE_TERMIOS_FALSE +MODULE_TERMIOS_TRUE +MODULE_SYSLOG_FALSE +MODULE_SYSLOG_TRUE +MODULE__SCPROXY_FALSE +MODULE__SCPROXY_TRUE +MODULE_RESOURCE_FALSE +MODULE_RESOURCE_TRUE +MODULE_PWD_FALSE +MODULE_PWD_TRUE +MODULE_GRP_FALSE +MODULE_GRP_TRUE +MODULE__SOCKET_FALSE +MODULE__SOCKET_TRUE +MODULE_MMAP_FALSE +MODULE_MMAP_TRUE +MODULE_FCNTL_FALSE +MODULE_FCNTL_TRUE +MODULE__DATETIME_FALSE +MODULE__DATETIME_TRUE +MODULE_MATH_FALSE +MODULE_MATH_TRUE +MODULE_CMATH_FALSE +MODULE_CMATH_TRUE +MODULE__STATISTICS_FALSE +MODULE__STATISTICS_TRUE +MODULE__POSIXSHMEM_FALSE +MODULE__POSIXSHMEM_TRUE +MODULE__MULTIPROCESSING_FALSE +MODULE__MULTIPROCESSING_TRUE +MODULE__ZONEINFO_FALSE +MODULE__ZONEINFO_TRUE +MODULE__INTERPQUEUES_FALSE +MODULE__INTERPQUEUES_TRUE +MODULE__INTERPCHANNELS_FALSE +MODULE__INTERPCHANNELS_TRUE +MODULE__INTERPRETERS_FALSE +MODULE__INTERPRETERS_TRUE +MODULE__TYPING_FALSE +MODULE__TYPING_TRUE +MODULE__TYPES_FALSE +MODULE__TYPES_TRUE +MODULE__STRUCT_FALSE +MODULE__STRUCT_TRUE +MODULE_SELECT_FALSE +MODULE_SELECT_TRUE +MODULE__REMOTE_DEBUGGING_FALSE +MODULE__REMOTE_DEBUGGING_TRUE +MODULE__RANDOM_FALSE +MODULE__RANDOM_TRUE +MODULE__QUEUE_FALSE +MODULE__QUEUE_TRUE +MODULE__POSIXSUBPROCESS_FALSE +MODULE__POSIXSUBPROCESS_TRUE +MODULE__PICKLE_FALSE +MODULE__PICKLE_TRUE +MODULE__LSPROF_FALSE +MODULE__LSPROF_TRUE +MODULE__JSON_FALSE +MODULE__JSON_TRUE +MODULE__HEAPQ_FALSE +MODULE__HEAPQ_TRUE +MODULE__CSV_FALSE +MODULE__CSV_TRUE +MODULE__BISECT_FALSE +MODULE__BISECT_TRUE +MODULE__ASYNCIO_FALSE +MODULE__ASYNCIO_TRUE +MODULE__MATH_INTEGER_FALSE +MODULE__MATH_INTEGER_TRUE +MODULE_ARRAY_FALSE +MODULE_ARRAY_TRUE +MODULE_TIME_FALSE +MODULE_TIME_TRUE +MODULE__IO_FALSE +MODULE__IO_TRUE +MODULE_BUILDTYPE +_PYTHREAD_NAME_MAXLEN +BUILD_DETAILS +TEST_MODULES +OPENSSL_LDFLAGS +OPENSSL_LIBS +OPENSSL_INCLUDES +ENSUREPIP +CFLAGS_CEVAL +SRCDIRS +THREADHEADERS +PANEL_LIBS +PANEL_CFLAGS +CURSES_LIBS +CURSES_CFLAGS +LIBEDIT_LIBS +LIBEDIT_CFLAGS +LIBREADLINE_LIBS +LIBREADLINE_CFLAGS +WHEEL_PKG_DIR +LIBPL +PY_ENABLE_SHARED +BINLIBDEST +LIBDEST +PLATLIBDIR +LIBPYTHON +MODULE_DEPS_SHARED +EXT_SUFFIX +ALT_SOABI +SOABI +LIBC +LIBM +HAVE_GETHOSTBYNAME +HAVE_GETHOSTBYNAME_R +HAVE_GETHOSTBYNAME_R_3_ARG +HAVE_GETHOSTBYNAME_R_5_ARG +HAVE_GETHOSTBYNAME_R_6_ARG +LIBOBJS +REMOTE_DEBUGGING_LIBS +REMOTE_DEBUGGING_CFLAGS +LIBZSTD_LIBS +LIBZSTD_CFLAGS +LIBLZMA_LIBS +LIBLZMA_CFLAGS +BZIP2_LIBS +BZIP2_CFLAGS +ZLIB_LIBS +ZLIB_CFLAGS +TRUE +MACHDEP_OBJS +DYNLOADFILE +DLINCLDIR +PLATFORM_OBJS +PLATFORM_HEADERS +DTRACE_OBJS +DTRACE_HEADERS +DFLAGS +DTRACE +INSTALL_MIMALLOC +MIMALLOC_HEADERS +GDBM_LIBS +GDBM_CFLAGS +X11_LIBS +X11_CFLAGS +TCLTK_LIBS +TCLTK_CFLAGS +LIBSQLITE3_LIBS +LIBSQLITE3_CFLAGS +LIBMPDEC_LIBS +LIBMPDEC_CFLAGS +MODULE__CTYPES_MALLOC_CLOSURE +LIBFFI_LIBS +LIBFFI_CFLAGS +LIBEXPAT_INTERNAL +LIBEXPAT_CFLAGS +TZPATH +LIBUUID_LIBS +LIBUUID_CFLAGS +PERF_TRAMPOLINE_OBJ +SHLIBS +CFLAGSFORSHARED +LINKFORSHARED +CCSHARED +BLDSHARED +LDCXXSHARED +LDSHARED +SHLIB_SUFFIX +DSYMUTIL_PATH +DSYMUTIL +REGEN_JIT_COMMAND +UNIVERSAL_ARCH_FLAGS +WASM_STDLIB +WASM_ASSETS_DIR +LDFLAGS_NOLTO +EXE_LDFLAGS +LDFLAGS_NODIST +CFLAGS_NODIST +BASECFLAGS +CFLAGS_ALIASING +OPT +BOLT_APPLY_FLAGS +BOLT_INSTRUMENT_FLAGS +BOLT_COMMON_FLAGS +BOLT_BINARIES +MERGE_FDATA +LLVM_BOLT +PREBOLT_RULE +LLVM_PROF_FOUND +LLVM_PROFDATA +LLVM_PROF_ERR +LLVM_PROF_FILE +LLVM_PROF_MERGER +PGO_PROF_USE_FLAG +PGO_PROF_GEN_FLAG +LLVM_AR_FOUND +LLVM_AR +PROFILE_TASK +DEF_MAKE_RULE +DEF_MAKE_ALL_RULE +ABI_THREAD +ABIFLAGS +LN +MKDIR_P +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +ARFLAGS +ac_ct_AR +AR +LINK_PYTHON_OBJS +LINK_PYTHON_DEPS +LIBRARY_DEPS +HOSTRUNNER +NODE +STATIC_LIBPYTHON +GNULD +EXPORTSFROM +EXPORTSYMS +LINKCC +LDVERSION +RUNSHARED +INSTSONAME +LDLIBRARYDIR +PY3LIBRARY +BLDLIBRARY +DLLLIBRARY +LDLIBRARY +LIBRARY +BUILDEXEEXT +NO_AS_NEEDED +_Py_STACK_GROWS_DOWN +MULTIARCH_CPPFLAGS +PLATFORM_TRIPLET +MULTIARCH +ac_ct_CXX +CXX +EGREP +SED +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +HAS_XCRUN +IPHONEOS_DEPLOYMENT_TARGET +EXPORT_MACOSX_DEPLOYMENT_TARGET +CONFIGURE_MACOSX_DEPLOYMENT_TARGET +_PYTHON_HOST_PLATFORM +APP_STORE_COMPLIANCE_PATCH +INSTALLTARGETS +FRAMEWORKINSTALLAPPSPREFIX +FRAMEWORKUNIXTOOLSPREFIX +FRAMEWORKPYTHONW +FRAMEWORKALTINSTALLLAST +FRAMEWORKALTINSTALLFIRST +FRAMEWORKINSTALLLAST +FRAMEWORKINSTALLFIRST +RESSRCDIR +PYTHONFRAMEWORKINSTALLNAMEPREFIX +PYTHONFRAMEWORKINSTALLDIR +PYTHONFRAMEWORKPREFIX +PYTHONFRAMEWORKDIR +PYTHONFRAMEWORKIDENTIFIER +PYTHONFRAMEWORK +LIPO_INTEL64_FLAGS +LIPO_32BIT_FLAGS +ARCH_RUN_32BIT +UNIVERSALSDK +host_exec_prefix +host_prefix +MACHDEP +MISSING_STDLIB_CONFIG +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +CONFIG_ARGS +SOVERSION +VERSION +PYTHON_FOR_REGEN +PYTHON_FOR_BUILD_DEPS +FREEZE_MODULE_DEPS +FREEZE_MODULE +FREEZE_MODULE_BOOTSTRAP_DEPS +FREEZE_MODULE_BOOTSTRAP +PYTHON_FOR_FREEZE +PYTHON_FOR_BUILD +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +HAS_GIT +GITBRANCH +GITTAG +GITVERSION +BASECPPFLAGS +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_build_python +with_pkg_config +with_missing_stdlib_config +enable_universalsdk +with_universal_archs +with_framework_name +enable_framework +with_app_store_compliance +enable_wasm_dynamic_linking +enable_wasm_pthreads +enable_emscripten_syscalls +with_suffix +enable_shared +with_static_libpython +enable_static_libpython_for_interpreter +enable_profiling +enable_gil +with_pydebug +with_trace_refs +enable_pystats +with_assertions +enable_optimizations +with_lto +enable_bolt +with_strict_overflow +enable_safety +enable_slower_safety +with_frame_pointers +enable_experimental_jit +with_dsymutil +with_address_sanitizer +with_memory_sanitizer +with_undefined_behavior_sanitizer +with_thread_sanitizer +with_hash_algorithm +with_tzpath +with_libs +with_system_expat +with_decimal_contextvar +enable_loadable_sqlite_extensions +with_dbmliborder +enable_ipv6 +with_doc_strings +with_mimalloc +with_pymalloc +with_pymalloc_hugepages +with_c_locale_coercion +with_valgrind +with_dtrace +enable_epoll +with_zlib +with_bzip2 +with_libm +with_libc +enable_big_digits +with_platlibdir +with_wheel_pkg_dir +with_readline +with_curses +with_computed_gotos +with_tail_call_interp +with_remote_debug +with_ensurepip +with_openssl +with_openssl_rpath +with_ssl_default_suites +with_builtin_hashlib_hashes +enable_test_modules +with_build_details_suffix +' + ac_precious_vars='build_alias +host_alias +target_alias +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +MACHDEP +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +PROFILE_TASK +BOLT_COMMON_FLAGS +BOLT_INSTRUMENT_FLAGS +BOLT_APPLY_FLAGS +LIBUUID_CFLAGS +LIBUUID_LIBS +LIBFFI_CFLAGS +LIBFFI_LIBS +LIBMPDEC_CFLAGS +LIBMPDEC_LIBS +LIBSQLITE3_CFLAGS +LIBSQLITE3_LIBS +TCLTK_CFLAGS +TCLTK_LIBS +X11_CFLAGS +X11_LIBS +GDBM_CFLAGS +GDBM_LIBS +ZLIB_CFLAGS +ZLIB_LIBS +BZIP2_CFLAGS +BZIP2_LIBS +LIBLZMA_CFLAGS +LIBLZMA_LIBS +LIBZSTD_CFLAGS +LIBZSTD_LIBS +LIBREADLINE_CFLAGS +LIBREADLINE_LIBS +LIBEDIT_CFLAGS +LIBEDIT_LIBS +CURSES_CFLAGS +CURSES_LIBS +PANEL_CFLAGS +PANEL_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: '$ac_option' +Try '$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: '$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: '$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +'configure' configures python 3.16 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print 'checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for '--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or '..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, 'make install' will install all the files in +'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc. You can specify +an installation prefix other than '$ac_default_prefix' using '--prefix', +for instance '--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/python] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of python 3.16:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-universalsdk[=SDKDIR] + create a universal binary build. SDKDIR specifies + which macOS SDK should be used to perform the build, + see Mac/README.rst. (default is no) + --enable-framework[=INSTALLDIR] + create a Python.framework rather than a traditional + Unix install. optional INSTALLDIR specifies the + installation path. see Mac/README.rst (default is + no) + --enable-wasm-dynamic-linking + Enable dynamic linking support for WebAssembly + (default is no); WASI requires an external dynamic + loader to handle imports + --enable-wasm-pthreads Enable pthread emulation for WebAssembly (default is + no) + --disable-emscripten-syscalls + Disable the Emscripten syscall overrides in + Python/emscripten_syscalls.c (default is enabled for + Emscripten) + --enable-shared enable building a shared Python library (default is + no) + --enable-static-libpython-for-interpreter + even with --enable-shared, statically link libpython + into the interpreter (default is to use the shared + library) + --enable-profiling enable C-level code profiling with gprof (default is + no) + --disable-gil enable support for running without the GIL (default + is no) + --enable-pystats enable internal statistics gathering (default is no) + --enable-optimizations enable expensive, stable optimizations (PGO, etc.) + (default is no) + --enable-bolt enable usage of the llvm-bolt post-link optimizer + (default is no) + --enable-safety enable usage of the security compiler options with + no performance overhead + --enable-slower-safety enable usage of the security compiler options with + performance overhead + --enable-experimental-jit[=no|yes|yes-off|interpreter] + build the experimental just-in-time compiler + (default is no) + --enable-loadable-sqlite-extensions + support loadable extensions in the sqlite3 module, + see Doc/library/sqlite3.rst (default is no) + --enable-ipv6 enable ipv6 (with ipv4) support, see + Doc/library/socket.rst (default is yes if supported) + --disable-epoll disable epoll (default is yes if supported) + --enable-big-digits[=15|30] + use big digits (30 or 15 bits) for Python longs + (default is 30)] + --disable-test-modules don't build nor install test modules + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-build-python=python3.16 + path to build python binary for cross compiling + (default: _bootstrap_python or python3.16) + --with-pkg-config=[yes|no|check] + use pkg-config to detect build options (default is + check) + --with-missing-stdlib-config=FILE + File with custom module error messages for missing + stdlib modules + --with-universal-archs=ARCH + specify the kind of macOS universal binary that + should be created. This option is only valid when + --enable-universalsdk is set; options are: + ("universal2", "intel-64", "intel-32", "intel", + "32-bit", "64-bit", "3-way", or "all") see + Mac/README.rst + --with-framework-name=FRAMEWORK + specify the name for the python framework on macOS + only valid when --enable-framework is set. see + Mac/README.rst (default is 'Python') + --with-app-store-compliance=[PATCH-FILE] + Enable any patches required for compiliance with app + stores. Optional PATCH-FILE specifies the custom + patch to apply. + --with-suffix=SUFFIX set executable suffix to SUFFIX (default is empty, + yes is mapped to '.exe') + --without-static-libpython + do not build libpythonMAJOR.MINOR.a and do not + install python.o (default is yes) + --with-pydebug build with Py_DEBUG defined (default is no) + --with-trace-refs enable tracing references for debugging purpose + (default is no) + --with-assertions build with C assertions enabled (default is no) + --with-lto=[full|thin|no|yes] + enable Link-Time-Optimization in any build (default + is no) + --with-strict-overflow if 'yes', add -fstrict-overflow to CFLAGS, else add + -fno-strict-overflow (default is no) + --without-frame-pointers + build without frame pointers (default is no) + --with-dsymutil link debug information into final executable with + dsymutil in macOS (default is no) + --with-address-sanitizer + enable AddressSanitizer memory error detector, + 'asan' (default is no) + --with-memory-sanitizer enable MemorySanitizer allocation error detector, + 'msan' (default is no) + --with-undefined-behavior-sanitizer + enable UndefinedBehaviorSanitizer undefined + behaviour detector, 'ubsan' (default is no) + --with-thread-sanitizer enable ThreadSanitizer data race detector, 'tsan' + (default is no) + --with-hash-algorithm=[fnv|siphash13|siphash24] + select hash algorithm for use in Python/pyhash.c + (default is SipHash13) + --with-tzpath=<list of absolute paths separated by pathsep> + Select the default time zone search path for + zoneinfo.TZPATH + --with-libs='lib1 ...' link against additional libs (default is no) + --with-system-expat build pyexpat module using an installed expat + library, see Doc/library/pyexpat.rst (default is no) + --with-decimal-contextvar + build _decimal module using a coroutine-local rather + than a thread-local context (default is yes) + --with-dbmliborder=db1:db2:... + override order to check db backends for dbm; a valid + value is a colon separated string with the backend + names `ndbm', `gdbm' and `bdb'. + --with-doc-strings enable documentation strings (default is yes) + --with-mimalloc build with mimalloc memory allocator (default is yes + if C11 stdatomic.h is available.) + --with-pymalloc enable specialized mallocs (default is yes) + --with-pymalloc-hugepages + enable huge page support for pymalloc arenas + (default is no) + --with-c-locale-coercion + enable C locale coercion to a UTF-8 based locale + (default is yes) + --with-valgrind enable Valgrind support (default is no) + --with-dtrace enable DTrace support (default is no) + --with(out)-zlib[=zlib|zlib-ng|zlib-rs|no] + select the zlib implementation to link against, or + disable zlib support (default: auto) + --with(out)-bzip2[=bzip2|bzip2-rs|no] + select the bzip2 implementation to link against, or + disable bzip2 support (default: auto) + --with-libm=STRING override libm math library to STRING (default is + system-dependent) + --with-libc=STRING override libc C library to STRING (default is + system-dependent) + --with-platlibdir=DIRNAME + Python library directory name (default is "lib") + --with-wheel-pkg-dir=PATH + Directory of wheel packages used by ensurepip + (default: none) + --with(out)-readline[=editline|readline|no] + use libedit for backend or disable readline module + --with(out)-curses[=ncursesw|ncurses|curses|no] + select the curses backend for the curses and + _curses_panel modules, or disable them (default: + auto) + --with-computed-gotos enable computed gotos in evaluation loop (enabled by + default on supported compilers) + --with-tail-call-interp enable tail-calling interpreter in evaluation loop + and rest of CPython + --with-remote-debug enable remote debugging support (default is yes) + --with-ensurepip[=install|upgrade|no] + "install" or "upgrade" using bundled pip (default is + upgrade) + --with-openssl=DIR root of the OpenSSL directory + --with-openssl-rpath=[DIR|auto|no] + Set runtime library directory (rpath) for OpenSSL + libraries, no (default): don't set rpath, auto: + auto-detect rpath from --with-openssl and + pkg-config, DIR: set an explicit rpath + --with-ssl-default-suites=[python|openssl|STRING] + override default cipher suites string, python: use + Python's preferred selection (default), openssl: + leave OpenSSL's defaults untouched, STRING: use a + custom string, python and STRING also set TLS 1.2 as + minimum TLS version + --with-builtin-hashlib-hashes=md5,sha1,sha2,sha3,blake2 + builtin hash modules, md5, sha1, sha2, sha3 (with + shake), blake2 + --with-build-details-suffix= + rename build-details.json to permit multiple + colocated Python installs; optionally specify a + custom suffix (default: no) + +Some influential environment variables: + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + MACHDEP name for machine-dependent library files + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + PROFILE_TASK + Python args for PGO generation task + BOLT_COMMON_FLAGS + Common arguments to llvm-bolt when instrumenting and applying + BOLT_INSTRUMENT_FLAGS + Arguments to llvm-bolt when instrumenting binaries + BOLT_APPLY_FLAGS + Arguments to llvm-bolt when creating a BOLT optimized binary + LIBUUID_CFLAGS + C compiler flags for LIBUUID, overriding pkg-config + LIBUUID_LIBS + linker flags for LIBUUID, overriding pkg-config + LIBFFI_CFLAGS + C compiler flags for LIBFFI, overriding pkg-config + LIBFFI_LIBS linker flags for LIBFFI, overriding pkg-config + LIBMPDEC_CFLAGS + C compiler flags for LIBMPDEC, overriding pkg-config + LIBMPDEC_LIBS + linker flags for LIBMPDEC, overriding pkg-config + LIBSQLITE3_CFLAGS + C compiler flags for LIBSQLITE3, overriding pkg-config + LIBSQLITE3_LIBS + linker flags for LIBSQLITE3, overriding pkg-config + TCLTK_CFLAGS + C compiler flags for TCLTK, overriding pkg-config + TCLTK_LIBS linker flags for TCLTK, overriding pkg-config + X11_CFLAGS C compiler flags for X11, overriding pkg-config + X11_LIBS linker flags for X11, overriding pkg-config + GDBM_CFLAGS C compiler flags for gdbm + GDBM_LIBS additional linker flags for gdbm + ZLIB_CFLAGS C compiler flags for ZLIB, overriding pkg-config + ZLIB_LIBS linker flags for ZLIB, overriding pkg-config + BZIP2_CFLAGS + C compiler flags for BZIP2, overriding pkg-config + BZIP2_LIBS linker flags for BZIP2, overriding pkg-config + LIBLZMA_CFLAGS + C compiler flags for LIBLZMA, overriding pkg-config + LIBLZMA_LIBS + linker flags for LIBLZMA, overriding pkg-config + LIBZSTD_CFLAGS + C compiler flags for LIBZSTD, overriding pkg-config + LIBZSTD_LIBS + linker flags for LIBZSTD, overriding pkg-config + LIBREADLINE_CFLAGS + C compiler flags for LIBREADLINE, overriding pkg-config + LIBREADLINE_LIBS + linker flags for LIBREADLINE, overriding pkg-config + LIBEDIT_CFLAGS + C compiler flags for LIBEDIT, overriding pkg-config + LIBEDIT_LIBS + linker flags for LIBEDIT, overriding pkg-config + CURSES_CFLAGS + C compiler flags for CURSES, overriding pkg-config + CURSES_LIBS linker flags for CURSES, overriding pkg-config + PANEL_CFLAGS + C compiler flags for PANEL, overriding pkg-config + PANEL_LIBS linker flags for PANEL, overriding pkg-config + +Use these variables to override the choices made by 'configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <https://github.com/python/cpython/issues/>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +python configure 3.16 +generated by GNU Autoconf 2.72 + +Copyright (C) 2023 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 ;; +esac +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + } +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 ;; +esac +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else case e in #( + e) eval "$3=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 ;; +esac +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status ;; +esac +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR +# ------------------------------------------------------------------ +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. +ac_fn_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +printf %s "checking whether $as_decl_name is declared... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + eval ac_save_FLAGS=\$$6 + as_fn_append $6 " $5" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else case e in #( + e) eval "$3=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + eval $6=\$ac_save_FLAGS + ;; +esac +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_check_decl + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else case e in #( + e) eval "$3=yes" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=$ac_mid; break +else case e in #( + e) as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_lo=$ac_mid; break +else case e in #( + e) as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done +else case e in #( + e) ac_lo= ac_hi= ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=$ac_mid +else case e in #( + e) as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval (void) { return $2; } +static unsigned long int ulongval (void) { return $2; } +#include <stdio.h> +#include <stdlib.h> +int +main (void) +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + echo >>conftest.val; read $3 <conftest.val; ac_retval=0 +else case e in #( + e) ac_retval=1 ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (void); below. */ + +#include <limits.h> +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (void); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main (void) +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$3=yes" +else case e in #( + e) eval "$3=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext ;; +esac +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +printf %s "checking for $2.$3... " >&6; } +if eval test \${$4+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main (void) +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$4=yes" +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main (void) +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$4=yes" +else case e in #( + e) eval "$4=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +eval ac_res=\$$4 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by python $as_me 3.16, which was +generated by GNU Autoconf 2.72. Invocation command line was + + $ $0$ac_configure_args_raw + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" + # Save into config.log some information that might help in debugging. + { + echo + + printf "%s\n" "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + printf "%s\n" "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + printf "%s\n" "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + printf "%s\n" "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +printf "%s\n" "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + ac_site_files="$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" +else + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" +fi + +for ac_site_file in $ac_site_files +do + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See 'config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include <stddef.h> +#include <stdarg.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (char **p, int i) +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* C89 style stringification. */ +#define noexpand_stringify(a) #a +const char *stringified = noexpand_stringify(arbitrary+token=sequence); + +/* C89 style token pasting. Exercises some of the corner cases that + e.g. old MSVC gets wrong, but not very hard. */ +#define noexpand_concat(a,b) a##b +#define expand_concat(a,b) noexpand_concat(a,b) +extern int vA; +extern int vbee; +#define aye A +#define bee B +int *pvA = &expand_concat(v,aye); +int *pvbee = &noexpand_concat(v,bee); + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +/* Does the compiler advertise C99 conformance? */ +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +// See if C++-style comments work. + +#include <stdbool.h> +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); +extern void free (void *); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + // Work around memory leak warnings. + free (ia); + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +/* Does the compiler advertise C11 conformance? */ +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" +as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" +as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" +as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" +as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" +as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" +as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" +as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" +as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" +as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H" +as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H" +as_fn_append ac_func_c_list " acospi HAVE_ACOSPI" +as_fn_append ac_func_c_list " asinpi HAVE_ASINPI" +as_fn_append ac_func_c_list " atanpi HAVE_ATANPI" +as_fn_append ac_func_c_list " atan2pi HAVE_ATAN2PI" +as_fn_append ac_func_c_list " cospi HAVE_COSPI" +as_fn_append ac_func_c_list " sinpi HAVE_SINPI" +as_fn_append ac_func_c_list " tanpi HAVE_TANPI" + +# Auxiliary files required by this configure script. +ac_aux_files="install-sh config.guess config.sub" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else case e in #( + e) as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 ;; +esac +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file' + and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + +if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then + # If we're building out-of-tree, we need to make sure the following + # resources get picked up before their $srcdir counterparts. + # Objects/ -> slots_generated.c + # Include/ -> Python.h + # (A side effect of this is that these resources will automatically be + # regenerated when building out-of-tree, regardless of whether or not + # the $srcdir counterpart is up-to-date. This is an acceptable trade + # off.) + BASECPPFLAGS="-IObjects -IInclude -IPython" +else + BASECPPFLAGS="" +fi + + + + + +if test -e $srcdir/.git +then +# Extract the first word of "git", so it can be a program name with args. +set dummy git; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_HAS_GIT+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$HAS_GIT"; then + ac_cv_prog_HAS_GIT="$HAS_GIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_HAS_GIT="found" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAS_GIT" && ac_cv_prog_HAS_GIT="not-found" +fi ;; +esac +fi +HAS_GIT=$ac_cv_prog_HAS_GIT +if test -n "$HAS_GIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HAS_GIT" >&5 +printf "%s\n" "$HAS_GIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +else +HAS_GIT=no-repository +fi +if test $HAS_GIT = found +then + GITVERSION="git --git-dir \$(srcdir)/.git rev-parse --short HEAD" + GITTAG="git --git-dir \$(srcdir)/.git describe --all --always --dirty" + GITBRANCH="git --git-dir \$(srcdir)/.git name-rev --name-only HEAD" +else + GITVERSION="" + GITTAG="" + GITBRANCH="" +fi + + +ac_config_headers="$ac_config_headers pyconfig.h" + + + + + + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + + +if test "x$cross_compiling" = xmaybe +then : + as_fn_error $? "Cross compiling required --host=HOST-TUPLE and --build=ARCH" "$LINENO" 5 + +fi + +# pybuilddir.txt will be created by --generate-posix-vars in the Makefile +rm -f pybuilddir.txt + + +# Check whether --with-build-python was given. +if test ${with_build_python+y} +then : + withval=$with_build_python; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-build-python" >&5 +printf %s "checking for --with-build-python... " >&6; } + + if test "x$with_build_python" = xyes +then : + with_build_python=python$PACKAGE_VERSION +fi + if test "x$with_build_python" = xno +then : + as_fn_error $? "invalid --with-build-python option: expected path or \"yes\", not \"no\"" "$LINENO" 5 +fi + + if ! $(command -v "$with_build_python" >/dev/null 2>&1); then + as_fn_error $? "invalid or missing build python binary \"$with_build_python\"" "$LINENO" 5 + fi + build_python_ver=$($with_build_python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") + if test "$build_python_ver" != "$PACKAGE_VERSION"; then + as_fn_error $? "\"$with_build_python\" has incompatible version $build_python_ver (expected: $PACKAGE_VERSION)" "$LINENO" 5 + fi + ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python + PYTHON_FOR_FREEZE="$with_build_python" + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_build_python" >&5 +printf "%s\n" "$with_build_python" >&6; } + +else case e in #( + e) + if test "x$cross_compiling" = xyes +then : + as_fn_error $? "Cross compiling requires --with-build-python" "$LINENO" 5 + +fi + PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' + PYTHON_FOR_FREEZE="./_bootstrap_python" + + ;; +esac +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python interpreter freezing" >&5 +printf %s "checking for Python interpreter freezing... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_FREEZE" >&5 +printf "%s\n" "$PYTHON_FOR_FREEZE" >&6; } + + +if test "x$cross_compiling" = xyes +then : + + FREEZE_MODULE_BOOTSTRAP='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_BOOTSTRAP_DEPS='$(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE='$(FREEZE_MODULE_BOOTSTRAP)' + FREEZE_MODULE_DEPS='$(FREEZE_MODULE_BOOTSTRAP_DEPS)' + PYTHON_FOR_BUILD_DEPS='' + +else case e in #( + e) + FREEZE_MODULE_BOOTSTRAP='./Programs/_freeze_module' + FREEZE_MODULE_BOOTSTRAP_DEPS="Programs/_freeze_module" + FREEZE_MODULE='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_DEPS="_bootstrap_python \$(srcdir)/Programs/_freeze_module.py" + PYTHON_FOR_BUILD_DEPS='$(BUILDPYTHON)' + + ;; +esac +fi + + + + + + +for ac_prog in python$PACKAGE_VERSION python3.16 python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 python3 python +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PYTHON_FOR_REGEN+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$PYTHON_FOR_REGEN"; then + ac_cv_prog_PYTHON_FOR_REGEN="$PYTHON_FOR_REGEN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PYTHON_FOR_REGEN="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +PYTHON_FOR_REGEN=$ac_cv_prog_PYTHON_FOR_REGEN +if test -n "$PYTHON_FOR_REGEN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_REGEN" >&5 +printf "%s\n" "$PYTHON_FOR_REGEN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$PYTHON_FOR_REGEN" && break +done +test -n "$PYTHON_FOR_REGEN" || PYTHON_FOR_REGEN="python3" + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Python for regen version" >&5 +printf %s "checking Python for regen version... " >&6; } +if command -v "$PYTHON_FOR_REGEN" >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $($PYTHON_FOR_REGEN -V 2>/dev/null)" >&5 +printf "%s\n" "$($PYTHON_FOR_REGEN -V 2>/dev/null)" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: missing" >&5 +printf "%s\n" "missing" >&6; } +fi + + +if test "$prefix" != "/"; then + prefix=`echo "$prefix" | sed -e 's/\/$//g'` +fi + + + + +# We don't use PACKAGE_ variables, and they cause conflicts +# with other autoconf-based packages that include Python.h +grep -v 'define PACKAGE_' <confdefs.h >confdefs.h.new +rm confdefs.h +mv confdefs.h.new confdefs.h + + +VERSION=3.16 + +# Version number of Python's own shared library file. + +SOVERSION=1.0 + +# The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables +# certain features on NetBSD, so we need _NETBSD_SOURCE to re-enable +# them. + +printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h + + +# The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables +# certain features on FreeBSD, so we need __BSD_VISIBLE to re-enable +# them. + +printf "%s\n" "#define __BSD_VISIBLE 1" >>confdefs.h + + +# The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables +# certain features on Mac OS X, so we need _DARWIN_C_SOURCE to re-enable +# them. + +printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h + + + +define_xopen_source=yes + +# Arguments passed to configure. + +CONFIG_ARGS="$ac_configure_args" + + +# Check whether --with-pkg-config was given. +if test ${with_pkg_config+y} +then : + withval=$with_pkg_config; +else case e in #( + e) with_pkg_config=check + ;; +esac +fi + +case $with_pkg_config in #( + yes|check) : + + if test -z "$PKG_CONFIG"; then + { PKG_CONFIG=; unset PKG_CONFIG;} + { ac_cv_path_ac_pt_PKG_CONFIG=; unset ac_cv_path_ac_pt_PKG_CONFIG;} + { ac_cv_prog_ac_ct_PKG_CONFIG=; unset ac_cv_prog_ac_ct_PKG_CONFIG;} + fi + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + PKG_CONFIG="" + fi +fi + ;; #( + no) : + + PKG_CONFIG='' + ac_cv_path_ac_pt_PKG_CONFIG='' + ac_cv_prog_ac_ct_PKG_CONFIG='' + ;; #( + *) : + as_fn_error $? "invalid argument --with-pkg-config=$with_pkg_config" "$LINENO" 5 + ;; +esac +if test "$with_pkg_config" = yes -a -z "$PKG_CONFIG"; then + as_fn_error $? "pkg-config is required" "$LINENO" 5] +fi + + +# Check whether --with-missing-stdlib-config was given. +if test ${with_missing_stdlib_config+y} +then : + withval=$with_missing_stdlib_config; MISSING_STDLIB_CONFIG="$withval" +else case e in #( + e) MISSING_STDLIB_CONFIG="" + ;; +esac +fi + + + +# Set name for machine-dependent library files + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking MACHDEP" >&5 +printf %s "checking MACHDEP... " >&6; } +if test -z "$MACHDEP" +then + # avoid using uname for cross builds + if test "$cross_compiling" = yes; then + # ac_sys_system and ac_sys_release are used for setting + # a lot of different things including 'define_xopen_source' + # in the case statement below. + case "$host" in + *-*-linux-android*) + ac_sys_system=Linux-android + ;; + *-*-linux*) + ac_sys_system=Linux + ;; + *-*-cygwin*) + ac_sys_system=CYGWIN + ;; + *-apple-ios*) + ac_sys_system=iOS + ;; + *-*-darwin*) + ac_sys_system=Darwin + ;; + *-gnu) + ac_sys_system=GNU + ;; + *-*-vxworks*) + ac_sys_system=VxWorks + ;; + *-*-emscripten) + ac_sys_system=Emscripten + ;; + *-*-wasi*) + ac_sys_system=WASI + ;; + *) + # for now, limit cross builds to known configurations + MACHDEP="unknown" + as_fn_error $? "cross build not supported for $host" "$LINENO" 5 + esac + ac_sys_release= + else + ac_sys_system=`uname -s` + if test "$ac_sys_system" = "AIX" \ + -o "$ac_sys_system" = "UnixWare" -o "$ac_sys_system" = "OpenUNIX"; then + ac_sys_release=`uname -v` + else + ac_sys_release=`uname -r` + fi + fi + ac_md_system=`echo $ac_sys_system | + tr -d '/ ' | tr '[A-Z]' '[a-z]'` + ac_md_release=`echo $ac_sys_release | + tr -d '/ ' | sed 's/^[A-Z]\.//' | sed 's/\..*//'` + MACHDEP="$ac_md_system$ac_md_release" + + case $MACHDEP in + aix*) MACHDEP="aix";; + freebsd*) MACHDEP="freebsd";; + linux-android*) MACHDEP="android";; + linux*) MACHDEP="linux";; + cygwin*) MACHDEP="cygwin";; + darwin*) MACHDEP="darwin";; + '') MACHDEP="unknown";; + esac + + if test "$ac_sys_system" = "SunOS"; then + # For Solaris, there isn't an OS version specific macro defined + # in most compilers, so we define one here. + SUNOS_VERSION=`echo $ac_sys_release | sed -e 's!\.\(0-9\)$!.0\1!g' | tr -d '.'` + +printf "%s\n" "#define Py_SUNOS_VERSION $SUNOS_VERSION" >>confdefs.h + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$MACHDEP\"" >&5 +printf "%s\n" "\"$MACHDEP\"" >&6; } + + +if test -z "$host_prefix"; then + case $ac_sys_system in #( + Emscripten) : + host_prefix=/ ;; #( + *) : + host_prefix='${prefix}' + ;; +esac +fi + + +if test -z "$host_exec_prefix"; then + case $ac_sys_system in #( + Emscripten) : + host_exec_prefix=$host_prefix ;; #( + *) : + host_exec_prefix='${exec_prefix}' + ;; +esac +fi + + +# On cross-compile builds, configure will look for a host-specific compiler by +# prepending the user-provided host triple to the required binary name. +# +# On iOS, this results in binaries like "arm64-apple-ios13.0-simulator-gcc", +# which isn't a binary that exists, and isn't very convenient, as it contains the +# iOS version. As the default cross-compiler name won't exist, configure falls +# back to gcc, which *definitely* won't work. We're providing wrapper scripts for +# these tools; the binary names of these scripts are better defaults than "gcc". +# This only requires that the user put the platform scripts folder (e.g., +# "iOS/Resources/bin") in their path, rather than defining platform-specific +# names/paths for AR, CC, CPP, and CXX explicitly; and if the user forgets to +# either put the platform scripts folder in the path, or specify CC etc, +# configure will fail. +if test -z "$AR"; then + case "$host" in + aarch64-apple-ios*-simulator) AR=arm64-apple-ios-simulator-ar ;; + aarch64-apple-ios*) AR=arm64-apple-ios-ar ;; + x86_64-apple-ios*-simulator) AR=x86_64-apple-ios-simulator-ar ;; + *) + esac +fi +if test -z "$CC"; then + case "$host" in + aarch64-apple-ios*-simulator) CC=arm64-apple-ios-simulator-clang ;; + aarch64-apple-ios*) CC=arm64-apple-ios-clang ;; + x86_64-apple-ios*-simulator) CC=x86_64-apple-ios-simulator-clang ;; + *) + esac +fi +if test -z "$CPP"; then + case "$host" in + aarch64-apple-ios*-simulator) CPP=arm64-apple-ios-simulator-cpp ;; + aarch64-apple-ios*) CPP=arm64-apple-ios-cpp ;; + x86_64-apple-ios*-simulator) CPP=x86_64-apple-ios-simulator-cpp ;; + *) + esac +fi +if test -z "$CXX"; then + case "$host" in + aarch64-apple-ios*-simulator) CXX=arm64-apple-ios-simulator-clang++ ;; + aarch64-apple-ios*) CXX=arm64-apple-ios-clang++ ;; + x86_64-apple-ios*-simulator) CXX=x86_64-apple-ios-simulator-clang++ ;; + *) + esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-universalsdk" >&5 +printf %s "checking for --enable-universalsdk... " >&6; } +# Check whether --enable-universalsdk was given. +if test ${enable_universalsdk+y} +then : + enableval=$enable_universalsdk; + case $enableval in + yes) + # Locate the best usable SDK, see Mac/README for more + # information + enableval="`/usr/bin/xcodebuild -version -sdk macosx Path 2>/dev/null`" + if ! ( echo $enableval | grep -E '\.sdk' 1>/dev/null ) + then + enableval=/Developer/SDKs/MacOSX10.4u.sdk + if test ! -d "${enableval}" + then + enableval=/ + fi + fi + ;; + esac + case $enableval in + no) + UNIVERSALSDK= + enable_universalsdk= + ;; + *) + UNIVERSALSDK=$enableval + if test ! -d "${UNIVERSALSDK}" + then + as_fn_error $? "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5 + fi + ;; + esac + + +else case e in #( + e) + UNIVERSALSDK= + enable_universalsdk= + ;; +esac +fi + +if test -n "${UNIVERSALSDK}" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${UNIVERSALSDK}" >&5 +printf "%s\n" "${UNIVERSALSDK}" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + +ARCH_RUN_32BIT="" + +# For backward compatibility reasons we prefer to select '32-bit' if available, +# otherwise use 'intel' +UNIVERSAL_ARCHS="32-bit" +if test "`uname -s`" = "Darwin" +then + if test -n "${UNIVERSALSDK}" + then + if test -z "`/usr/bin/file -L "${UNIVERSALSDK}/usr/lib/libSystem.dylib" | grep ppc`" + then + UNIVERSAL_ARCHS="intel" + fi + fi +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-universal-archs" >&5 +printf %s "checking for --with-universal-archs... " >&6; } + +# Check whether --with-universal-archs was given. +if test ${with_universal_archs+y} +then : + withval=$with_universal_archs; + UNIVERSAL_ARCHS="$withval" + +fi + +if test -n "${UNIVERSALSDK}" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${UNIVERSAL_ARCHS}" >&5 +printf "%s\n" "${UNIVERSAL_ARCHS}" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +# Check whether --with-framework-name was given. +if test ${with_framework_name+y} +then : + withval=$with_framework_name; + PYTHONFRAMEWORK=${withval} + PYTHONFRAMEWORKDIR=${withval}.framework + PYTHONFRAMEWORKIDENTIFIER=org.python.`echo $withval | tr 'A-Z' 'a-z'` + +else case e in #( + e) + PYTHONFRAMEWORK=Python + PYTHONFRAMEWORKDIR=Python.framework + PYTHONFRAMEWORKIDENTIFIER=org.python.python + ;; +esac +fi + +# Check whether --enable-framework was given. +if test ${enable_framework+y} +then : + enableval=$enable_framework; + case $enableval in + yes) + case $ac_sys_system in + Darwin) enableval=/Library/Frameworks ;; + iOS) enableval=Platforms/Apple/iOS/Frameworks/\$\(MULTIARCH\) ;; + *) as_fn_error $? "Unknown platform for framework build" "$LINENO" 5 + esac + esac + + case $enableval in + no) + case $ac_sys_system in + iOS) as_fn_error $? "iOS builds must use --enable-framework" "$LINENO" 5 ;; + *) + PYTHONFRAMEWORK= + PYTHONFRAMEWORKDIR=no-framework + PYTHONFRAMEWORKPREFIX= + PYTHONFRAMEWORKINSTALLDIR= + PYTHONFRAMEWORKINSTALLNAMEPREFIX= + RESSRCDIR= + FRAMEWORKINSTALLFIRST= + FRAMEWORKINSTALLLAST= + FRAMEWORKALTINSTALLFIRST= + FRAMEWORKALTINSTALLLAST= + FRAMEWORKPYTHONW= + INSTALLTARGETS="commoninstall bininstall maninstall" + + if test "x${prefix}" = "xNONE"; then + FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi + enable_framework= + esac + ;; + *) + PYTHONFRAMEWORKPREFIX="${enableval}" + PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR + + case $ac_sys_system in #( + Darwin) : + FRAMEWORKINSTALLFIRST="frameworkinstallversionedstructure" + FRAMEWORKALTINSTALLFIRST="frameworkinstallversionedstructure " + FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" + FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" + FRAMEWORKPYTHONW="frameworkpythonw" + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + INSTALLTARGETS="commoninstall bininstall maninstall" + + if test "x${prefix}" = "xNONE" ; then + FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" + + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi + + case "${enableval}" in + /System*) + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + if test "${prefix}" = "NONE" ; then + # See below + FRAMEWORKUNIXTOOLSPREFIX="/usr" + fi + ;; + + /Library*) + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + ;; + + */Library/Frameworks) + MDIR="`dirname "${enableval}"`" + MDIR="`dirname "${MDIR}"`" + FRAMEWORKINSTALLAPPSPREFIX="${MDIR}/Applications" + + if test "${prefix}" = "NONE"; then + # User hasn't specified the + # --prefix option, but wants to install + # the framework in a non-default location, + # ensure that the compatibility links get + # installed relative to that prefix as well + # instead of in /usr/local. + FRAMEWORKUNIXTOOLSPREFIX="${MDIR}" + fi + ;; + + *) + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + ;; + esac + + prefix=$PYTHONFRAMEWORKINSTALLDIR/Versions/$VERSION + PYTHONFRAMEWORKINSTALLNAMEPREFIX=${prefix} + RESSRCDIR=Mac/Resources/framework + + # Add files for Mac specific code to the list of output + # files: + ac_config_files="$ac_config_files Mac/Makefile" + + ac_config_files="$ac_config_files Mac/PythonLauncher/Makefile" + + ac_config_files="$ac_config_files Mac/Resources/framework/Info.plist" + + ac_config_files="$ac_config_files Mac/Resources/app/Info.plist" + + ;; + iOS) : + FRAMEWORKINSTALLFIRST="frameworkinstallunversionedstructure" + FRAMEWORKALTINSTALLFIRST="frameworkinstallunversionedstructure " + FRAMEWORKINSTALLLAST="frameworkinstallmobileheaders" + FRAMEWORKALTINSTALLLAST="frameworkinstallmobileheaders" + FRAMEWORKPYTHONW= + INSTALLTARGETS="libinstall inclinstall sharedinstall" + + prefix=$PYTHONFRAMEWORKPREFIX + PYTHONFRAMEWORKINSTALLNAMEPREFIX="@rpath/$PYTHONFRAMEWORKDIR" + RESSRCDIR=Platforms/Apple/iOS/Resources + + ac_config_files="$ac_config_files Platforms/Apple/iOS/Resources/Info.plist" + + ;; + *) + as_fn_error $? "Unknown platform for framework build" "$LINENO" 5 + ;; + esac + esac + +else case e in #( + e) + case $ac_sys_system in + iOS) as_fn_error $? "iOS builds must use --enable-framework" "$LINENO" 5 ;; + *) + PYTHONFRAMEWORK= + PYTHONFRAMEWORKDIR=no-framework + PYTHONFRAMEWORKPREFIX= + PYTHONFRAMEWORKINSTALLDIR= + PYTHONFRAMEWORKINSTALLNAMEPREFIX= + RESSRCDIR= + FRAMEWORKINSTALLFIRST= + FRAMEWORKINSTALLLAST= + FRAMEWORKALTINSTALLFIRST= + FRAMEWORKALTINSTALLLAST= + FRAMEWORKPYTHONW= + INSTALLTARGETS="commoninstall bininstall maninstall" + if test "x${prefix}" = "xNONE" ; then + FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi + enable_framework= + esac + ;; +esac +fi + + + + + + + + + + + + + + + + + + +printf "%s\n" "#define _PYTHONFRAMEWORK \"${PYTHONFRAMEWORK}\"" >>confdefs.h + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-app-store-compliance" >&5 +printf %s "checking for --with-app-store-compliance... " >&6; } + +# Check whether --with-app_store_compliance was given. +if test ${with_app_store_compliance+y} +then : + withval=$with_app_store_compliance; + case "$withval" in + yes) + case $ac_sys_system in + Darwin|iOS) + # iOS is able to share the macOS patch + APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch" + ;; + *) as_fn_error $? "no default app store compliance patch available for $ac_sys_system" "$LINENO" 5 ;; + esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: applying default app store compliance patch" >&5 +printf "%s\n" "applying default app store compliance patch" >&6; } + ;; + *) + APP_STORE_COMPLIANCE_PATCH="${withval}" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: applying custom app store compliance patch" >&5 +printf "%s\n" "applying custom app store compliance patch" >&6; } + ;; + esac + +else case e in #( + e) + case $ac_sys_system in + iOS) + # Always apply the compliance patch on iOS; we can use the macOS patch + APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: applying default app store compliance patch" >&5 +printf "%s\n" "applying default app store compliance patch" >&6; } + ;; + *) + # No default app compliance patching on any other platform + APP_STORE_COMPLIANCE_PATCH= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not patching for app store compliance" >&5 +printf "%s\n" "not patching for app store compliance" >&6; } + ;; + esac + ;; +esac +fi + + + + +if test "$cross_compiling" = yes; then + case "$host" in + *-*-linux*) + case "$host_cpu" in + arm*) + _host_ident=arm + ;; + *) + _host_ident=$host_cpu + esac + ;; + *-gnu) + _host_ident=$host_cpu + ;; + *-*-cygwin*) + _host_ident= + ;; + *-apple-ios*) + _host_os=`echo $host | cut -d '-' -f3` + _host_device=`echo $host | cut -d '-' -f4` + _host_device=${_host_device:=os} + + # IPHONEOS_DEPLOYMENT_TARGET is the minimum supported iOS version + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking iOS deployment target" >&5 +printf %s "checking iOS deployment target... " >&6; } + IPHONEOS_DEPLOYMENT_TARGET=$(echo ${_host_os} | cut -c4-) + IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET:=13.0} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $IPHONEOS_DEPLOYMENT_TARGET" >&5 +printf "%s\n" "$IPHONEOS_DEPLOYMENT_TARGET" >&6; } + + case "$host_cpu" in + aarch64) + _host_ident=${IPHONEOS_DEPLOYMENT_TARGET}-arm64-iphone${_host_device} + ;; + *) + _host_ident=${IPHONEOS_DEPLOYMENT_TARGET}-$host_cpu-iphone${_host_device} + ;; + esac + ;; + *-*-darwin*) + case "$host_cpu" in + arm*) + _host_ident=arm + ;; + *) + _host_ident=$host_cpu + esac + ;; + *-*-vxworks*) + _host_ident=$host_cpu + ;; + *-*-emscripten) + _host_ident=$(emcc -dumpversion | cut -f1 -d-)-$host_cpu + ;; + wasm32-*-* | wasm64-*-*) + _host_ident=$host_cpu + ;; + *) + # for now, limit cross builds to known configurations + MACHDEP="unknown" + as_fn_error $? "cross build not supported for $host" "$LINENO" 5 + esac + _PYTHON_HOST_PLATFORM="$MACHDEP${_host_ident:+-$_host_ident}" +fi + +# Some systems cannot stand _XOPEN_SOURCE being defined at all; they +# disable features if it is defined, without any means to access these +# features as extensions. For these systems, we skip the definition of +# _XOPEN_SOURCE. Before adding a system to the list to gain access to +# some feature, make sure there is no alternative way to access this +# feature. Also, when using wildcards, make sure you have verified the +# need for not defining _XOPEN_SOURCE on all systems matching the +# wildcard, and that the wildcard does not include future systems +# (which may remove their limitations). +case $ac_sys_system/$ac_sys_release in + # On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined, + # even though select is a POSIX function. Reported by J. Ribbens. + # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish. + # In addition, Stefan Krah confirms that issue #1244610 exists through + # OpenBSD 4.6, but is fixed in 4.7. + OpenBSD/2.* | OpenBSD/3.* | OpenBSD/4.[0123456]) + define_xopen_source=no + # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is + # also defined. This can be overridden by defining _BSD_SOURCE + # As this has a different meaning on Linux, only define it on OpenBSD + +printf "%s\n" "#define _BSD_SOURCE 1" >>confdefs.h + + ;; + OpenBSD/*) + # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is + # also defined. This can be overridden by defining _BSD_SOURCE + # As this has a different meaning on Linux, only define it on OpenBSD + +printf "%s\n" "#define _BSD_SOURCE 1" >>confdefs.h + + ;; + # Defining _XOPEN_SOURCE on NetBSD version prior to the introduction of + # _NETBSD_SOURCE disables certain features (eg. setgroups). Reported by + # Marc Recht + NetBSD/1.5 | NetBSD/1.5.* | NetBSD/1.6 | NetBSD/1.6.* | NetBSD/1.6[A-S]) + define_xopen_source=no;; + # On Solaris, _XOPEN_SOURCE=800 hides platform specific features. + # A lower level is defined below. + SunOS/*) + define_xopen_source=no;; + # On UnixWare 7, u_long is never defined with _XOPEN_SOURCE, + # but used in /usr/include/netinet/tcp.h. Reported by Tim Rice. + # Reconfirmed for 7.1.4 by Martin v. Loewis. + OpenUNIX/8.0.0| UnixWare/7.1.[0-4]) + define_xopen_source=no;; + # On OpenServer 5, u_short is never defined with _XOPEN_SOURCE, + # but used in struct sockaddr.sa_family. Reported by Tim Rice. + SCO_SV/3.2) + define_xopen_source=no;; + # On MacOS X 10.2, a bug in ncurses.h means that it craps out if + # _XOPEN_EXTENDED_SOURCE is defined. Apparently, this is fixed in 10.3, which + # identifies itself as Darwin/7.* + # On Mac OS X 10.4, defining _POSIX_C_SOURCE or _XOPEN_SOURCE + # disables platform specific features beyond repair. + # On Mac OS X 10.3, defining _POSIX_C_SOURCE or _XOPEN_SOURCE + # has no effect, don't bother defining them + Darwin/[6789].*) + define_xopen_source=no;; + Darwin/[12][0-9].*) + define_xopen_source=no;; + # On iOS, defining _POSIX_C_SOURCE also disables platform specific features. + iOS/*) + define_xopen_source=no;; + # On QNX 6.3.2, defining _XOPEN_SOURCE prevents netdb.h from + # defining NI_NUMERICHOST. + QNX/6.3.2) + define_xopen_source=no + ;; + # On VxWorks, defining _XOPEN_SOURCE causes compile failures + # in network headers still using system V types. + VxWorks/*) + define_xopen_source=no + ;; + + # On HP-UX, defining _XOPEN_SOURCE to 600 or greater hides + # chroot() and other functions + hp*|HP*) + define_xopen_source=no + ;; + +esac + +if test $define_xopen_source = yes +then + # X/Open 8, incorporating POSIX.1-2024 + +printf "%s\n" "#define _XOPEN_SOURCE 800" >>confdefs.h + + + # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires + # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else + # several APIs are not declared. Since this is also needed in some + # cases for HP-UX, we define it globally. + +printf "%s\n" "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h + + + +printf "%s\n" "#define _POSIX_C_SOURCE 202405L" >>confdefs.h + + + # Defining _POSIX_C_SOURCE and _XOPEN_SOURCE hides C23 library + # declarations on FreeBSD (e.g. sinpi() in math.h) when compiling + # with -std=c11. Defining _ISOC23_SOURCE makes them visible again. + +printf "%s\n" "#define _ISOC23_SOURCE 1" >>confdefs.h + +elif test "$ac_sys_system" = "SunOS" +then + # On illumos the socket ancillary-data API (CMSG_*, sendmsg(), recvmsg()) + # is declared only with _XOPEN_SOURCE >= 600; Solaris declares it anyway. + # __EXTENSIONS__ keeps the platform specific features which _XOPEN_SOURCE + # would otherwise hide. See gh-57208. + +printf "%s\n" "#define _XOPEN_SOURCE 600" >>confdefs.h + +fi + +# On HP-UX mbstate_t requires _INCLUDE__STDC_A1_SOURCE +case $ac_sys_system in + hp*|HP*) + define_stdc_a1=yes;; + *) + define_stdc_a1=no;; +esac + +if test $define_stdc_a1 = yes +then + +printf "%s\n" "#define _INCLUDE__STDC_A1_SOURCE 1" >>confdefs.h + +fi + +# Record the configure-time value of MACOSX_DEPLOYMENT_TARGET, +# it may influence the way we can build extensions, so distutils +# needs to check it + + +CONFIGURE_MACOSX_DEPLOYMENT_TARGET= +EXPORT_MACOSX_DEPLOYMENT_TARGET='#' + +# Record the value of IPHONEOS_DEPLOYMENT_TARGET enforced by the selected host triple. + + +# checks for alternative programs + +# compiler flags are generated in two sets, BASECFLAGS and OPT. OPT is just +# for debug/optimization stuff. BASECFLAGS is for flags that are required +# just to get things to compile and link. Users are free to override OPT +# when running configure or make. The build should not break if they do. +# BASECFLAGS should generally not be messed with, however. + +# If the user switches compilers, we can't believe the cache +if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" +then + as_fn_error $? "cached CC is different -- throw away $cache_file +(it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5 +fi + +# Don't let AC_PROG_CC set the default CFLAGS. It normally sets -g -O2 +# when the compiler supports them, but we don't always want -O2, and +# we set -g later. +if test -z "$CFLAGS"; then + CFLAGS= +fi + +case $host in #( + wasm64-*-emscripten) : + + as_fn_append CFLAGS " -sMEMORY64=1" + as_fn_append LDFLAGS " -sMEMORY64=1" + ;; #( + *) : + ;; +esac + +case $host in #( + *-apple-ios*-simulator) : + + as_fn_append CFLAGS " -mios-simulator-version-min=${IPHONEOS_DEPLOYMENT_TARGET}" + as_fn_append LDFLAGS " -mios-simulator-version-min=${IPHONEOS_DEPLOYMENT_TARGET}" + ;; #( + *-apple-ios*) : + + as_fn_append CFLAGS " -mios-version-min=${IPHONEOS_DEPLOYMENT_TARGET}" + as_fn_append LDFLAGS " -mios-version-min=${IPHONEOS_DEPLOYMENT_TARGET}" + ;; #( + *) : + ;; +esac + +if test "$ac_sys_system" = "Darwin" +then + # Extract the first word of "xcrun", so it can be a program name with args. +set dummy xcrun; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_HAS_XCRUN+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$HAS_XCRUN"; then + ac_cv_prog_HAS_XCRUN="$HAS_XCRUN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_HAS_XCRUN="yes" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAS_XCRUN" && ac_cv_prog_HAS_XCRUN="missing" +fi ;; +esac +fi +HAS_XCRUN=$ac_cv_prog_HAS_XCRUN +if test -n "$HAS_XCRUN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HAS_XCRUN" >&5 +printf "%s\n" "$HAS_XCRUN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking macOS SDKROOT" >&5 +printf %s "checking macOS SDKROOT... " >&6; } + if test -z "$SDKROOT"; then + if test "$HAS_XCRUN" = "yes"; then + SDKROOT=$(xcrun --show-sdk-path) + else + SDKROOT="/" + fi + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SDKROOT" >&5 +printf "%s\n" "$SDKROOT" >&6; } + + # Compiler selection on MacOSX is more complicated than + # AC_PROG_CC can handle, see Mac/README for more + # information + if test -z "${CC}" + then + found_gcc= + found_clang= + as_save_IFS=$IFS; IFS=: + for as_dir in $PATH + do + IFS=$as_save_IFS + if test -x "${as_dir}/gcc"; then + if test -z "${found_gcc}"; then + found_gcc="${as_dir}/gcc" + fi + fi + if test -x "${as_dir}/clang"; then + if test -z "${found_clang}"; then + found_clang="${as_dir}/clang" + fi + fi + done + IFS=$as_save_IFS + + if test -n "$found_gcc" -a -n "$found_clang" + then + if test -n "`"$found_gcc" --version | grep llvm-gcc`" + then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Detected llvm-gcc, falling back to clang" >&5 +printf "%s\n" "$as_me: Detected llvm-gcc, falling back to clang" >&6;} + CC="$found_clang" + CXX="$found_clang++" + fi + + + elif test -z "$found_gcc" -a -n "$found_clang" + then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No GCC found, use CLANG" >&5 +printf "%s\n" "$as_me: No GCC found, use CLANG" >&6;} + CC="$found_clang" + CXX="$found_clang++" + + elif test -z "$found_gcc" -a -z "$found_clang" + then + found_clang=`/usr/bin/xcrun -find clang 2>/dev/null` + if test -n "${found_clang}" + then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using clang from Xcode.app" >&5 +printf "%s\n" "$as_me: Using clang from Xcode.app" >&6;} + CC="${found_clang}" + CXX="`/usr/bin/xcrun -find clang++`" + + # else: use default behaviour + fi + fi + fi +fi + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" + fi +fi +fi ;; +esac +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See 'config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion -version; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'. +# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an '-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else case e in #( + e) ac_file='' ;; +esac +fi +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See 'config.log' for more details" "$LINENO" 5; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # If both 'conftest.exe' and 'conftest' are 'present' (well, observable) +# catch 'conftest.exe'. For instance with Cygwin, 'ls conftest' will +# work properly (i.e., refer to 'conftest.exe'), while it won't with +# 'rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See 'config.log' for more details" "$LINENO" 5; } ;; +esac +fi +rm -f conftest conftest$ac_cv_exeext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main (void) +{ +FILE *f = fopen ("conftest.out", "w"); + if (!f) + return 1; + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. +If you meant to cross compile, use '--host'. +See 'config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext \ + conftest.o conftest.obj conftest.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See 'config.log' for more details" "$LINENO" 5; } ;; +esac +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else case e in #( + e) ac_compiler_gnu=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+y} +ac_save_CFLAGS=$CFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +else case e in #( + e) CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else case e in #( + e) ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC ;; +esac +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else case e in #( + e) if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" ;; +esac +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 ;; +esac +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC ;; +esac +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else case e in #( + e) if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" ;; +esac +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 ;; +esac +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC ;; +esac +fi + +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else case e in #( + e) if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" ;; +esac +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 ;; +esac +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test ${ac_cv_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) # Double quotes because $CC needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else case e in #( + e) # Passes both tests. +ac_preproc_ok=: +break ;; +esac +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_prog_CPP=$CPP + ;; +esac +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +printf "%s\n" "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else case e in #( + e) # Passes both tests. +ac_preproc_ok=: +break ;; +esac +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See 'config.log' for more details" "$LINENO" 5; } ;; +esac +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in #( +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +#( +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in #( +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +#( +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +printf %s "checking for egrep... " >&6; } +if test ${ac_cv_path_EGREP+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in #( +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +#( +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +printf "%s\n" "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + EGREP_TRADITIONAL=$EGREP + ac_cv_path_EGREP_TRADITIONAL=$EGREP + + +CC_BASENAME=$(expr "//$CC" : '.*/\(.*\)') + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CC compiler name" >&5 +printf %s "checking for CC compiler name... " >&6; } +if test ${ac_cv_cc_name+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat > conftest.c <<EOF +#if defined(__EMSCRIPTEN__) + emcc +#elif defined(__INTEL_CLANG_COMPILER) || defined(__INTEL_LLVM_COMPILER) + icx +#elif defined(__INTEL_COMPILER) || defined(__ICC) + icc +#elif defined(__ibmxl__) || defined(__xlc__) || defined(__xlC__) + xlc +#elif defined(_MSC_VER) + msvc +#elif defined(__clang__) + clang +#elif defined(__GNUC__) + gcc +#else +# error unknown compiler +#endif +EOF + +if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then + ac_cv_cc_name=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` + if test "x$CC_BASENAME" = xmpicc +then : + ac_cv_cc_name=mpicc +fi +else + ac_cv_cc_name="unknown" +fi +rm -f conftest.c conftest.out + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_name" >&5 +printf "%s\n" "$ac_cv_cc_name" >&6; } + +# checks for UNIX variants that set C preprocessor variables +# may set _GNU_SOURCE, __EXTENSIONS__, _POSIX_PTHREAD_SEMANTICS, +# _POSIX_SOURCE, _POSIX_1_SOURCE, and more + +ac_header= ac_cache= +for ac_item in $ac_header_c_list +do + if test $ac_cache; then + ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" + if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then + printf "%s\n" "#define $ac_item 1" >> confdefs.h + fi + ac_header= ac_cache= + elif test $ac_header; then + ac_cache=$ac_item + else + ac_header=$ac_item + fi +done + + + + + + + + +if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes +then : + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h + +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +printf %s "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test ${ac_cv_safe_to_define___extensions__+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_safe_to_define___extensions__=yes +else case e in #( + e) ac_cv_safe_to_define___extensions__=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5 +printf %s "checking whether _XOPEN_SOURCE should be defined... " >&6; } +if test ${ac_cv_should_define__xopen_source+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_should_define__xopen_source=no + if test $ac_cv_header_wchar_h = yes +then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <wchar.h> + mbstate_t x; +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define _XOPEN_SOURCE 500 + #include <wchar.h> + mbstate_t x; +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_should_define__xopen_source=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 +printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; } + + printf "%s\n" "#define _ALL_SOURCE 1" >>confdefs.h + + printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h + + printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h + + printf "%s\n" "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h + + printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h + + printf "%s\n" "#define _OPENBSD_SOURCE 1" >>confdefs.h + + printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_IEC_60559_EXT__ 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h + + printf "%s\n" "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h + + printf "%s\n" "#define _TANDEM_SOURCE 1" >>confdefs.h + + if test $ac_cv_header_minix_config_h = yes +then : + MINIX=yes + printf "%s\n" "#define _MINIX 1" >>confdefs.h + + printf "%s\n" "#define _POSIX_SOURCE 1" >>confdefs.h + + printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h + +else case e in #( + e) MINIX= ;; +esac +fi + if test $ac_cv_safe_to_define___extensions__ = yes +then : + printf "%s\n" "#define __EXTENSIONS__ 1" >>confdefs.h + +fi + if test $ac_cv_should_define__xopen_source = yes +then : + printf "%s\n" "#define _XOPEN_SOURCE 500" >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC compatible compiler" >&5 +printf %s "checking for GCC compatible compiler... " >&6; } +if test ${ac_cv_gcc_compat+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #if !defined(__GNUC__) + #error "not GCC compatible" + #else + /* GCC compatible! */ + #endif + +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + ac_cv_gcc_compat=yes +else case e in #( + e) ac_cv_gcc_compat=no ;; +esac +fi +rm -f conftest.err conftest.i conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_compat" >&5 +printf "%s\n" "$ac_cv_gcc_compat" >&6; } + + + +preset_cxx="$CXX" +if test -z "$CXX" +then + case "$ac_cv_cc_name" in + gcc) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}g++", so it can be a program name with args. +set dummy ${ac_tool_prefix}g++; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_CXX="$CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +CXX=$ac_cv_path_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_CXX"; then + ac_pt_CXX=$CXX + # Extract the first word of "g++", so it can be a program name with args. +set dummy g++; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_CXX=$ac_cv_path_ac_pt_CXX +if test -n "$ac_pt_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_CXX" = x; then + CXX="notfound" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_pt_CXX + fi +else + CXX="$ac_cv_path_CXX" +fi + ;; + cc) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}c++", so it can be a program name with args. +set dummy ${ac_tool_prefix}c++; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_CXX="$CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +CXX=$ac_cv_path_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_CXX"; then + ac_pt_CXX=$CXX + # Extract the first word of "c++", so it can be a program name with args. +set dummy c++; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_CXX=$ac_cv_path_ac_pt_CXX +if test -n "$ac_pt_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_CXX" = x; then + CXX="notfound" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_pt_CXX + fi +else + CXX="$ac_cv_path_CXX" +fi + ;; + clang) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang++", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang++; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_CXX="$CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +CXX=$ac_cv_path_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_CXX"; then + ac_pt_CXX=$CXX + # Extract the first word of "clang++", so it can be a program name with args. +set dummy clang++; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_CXX=$ac_cv_path_ac_pt_CXX +if test -n "$ac_pt_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_CXX" = x; then + CXX="notfound" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_pt_CXX + fi +else + CXX="$ac_cv_path_CXX" +fi + ;; + icx) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}icpx", so it can be a program name with args. +set dummy ${ac_tool_prefix}icpx; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_CXX="$CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +CXX=$ac_cv_path_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_CXX"; then + ac_pt_CXX=$CXX + # Extract the first word of "icpx", so it can be a program name with args. +set dummy icpx; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_CXX=$ac_cv_path_ac_pt_CXX +if test -n "$ac_pt_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_CXX" = x; then + CXX="notfound" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_pt_CXX + fi +else + CXX="$ac_cv_path_CXX" +fi + ;; + icc) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}icpc", so it can be a program name with args. +set dummy ${ac_tool_prefix}icpc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_CXX="$CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +CXX=$ac_cv_path_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_CXX"; then + ac_pt_CXX=$CXX + # Extract the first word of "icpc", so it can be a program name with args. +set dummy icpc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_CXX in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_CXX=$ac_cv_path_ac_pt_CXX +if test -n "$ac_pt_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_CXX" = x; then + CXX="notfound" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_pt_CXX + fi +else + CXX="$ac_cv_path_CXX" +fi + ;; + esac + if test "$CXX" = "notfound" + then + CXX="" + fi +fi +if test -z "$CXX" +then + if test -n "$ac_tool_prefix"; then + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +printf "%s\n" "$ac_ct_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="notfound" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + if test "$CXX" = "notfound" + then + CXX="" + fi +fi +if test "$preset_cxx" != "$CXX" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: + + By default, distutils will build C++ extension modules with \"$CXX\". + If this is not intended, then set CXX on the configure command line. + " >&5 +printf "%s\n" "$as_me: + + By default, distutils will build C++ extension modules with \"$CXX\". + If this is not intended, then set CXX on the configure command line. + " >&6;} +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 +printf %s "checking for the platform triplet based on compiler characteristics... " >&6; } +if $CPP $CPPFLAGS $srcdir/Misc/platform_triplet.c >conftest.out 2>/dev/null; then + PLATFORM_TRIPLET=`grep '^PLATFORM_TRIPLET=' conftest.out | tr -d ' '` + PLATFORM_TRIPLET="${PLATFORM_TRIPLET#PLATFORM_TRIPLET=}" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PLATFORM_TRIPLET" >&5 +printf "%s\n" "$PLATFORM_TRIPLET" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } +fi +rm -f conftest.out + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for multiarch" >&5 +printf %s "checking for multiarch... " >&6; } +case $ac_sys_system in #( + Darwin*) : + MULTIARCH="" ;; #( + iOS) : + MULTIARCH="" ;; #( + FreeBSD*) : + MULTIARCH="" ;; #( + OpenBSD*) : + MULTIARCH="" ;; #( + *) : + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + ;; +esac + + +if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then + if test x$PLATFORM_TRIPLET != x$MULTIARCH; then + as_fn_error $? "internal configure error for the platform triplet, please file a bug report" "$LINENO" 5 + fi +elif test x$PLATFORM_TRIPLET != x && test x$MULTIARCH = x; then + MULTIARCH=$PLATFORM_TRIPLET +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MULTIARCH" >&5 +printf "%s\n" "$MULTIARCH" >&6; } + +case $ac_sys_system in #( + iOS) : + SOABI_PLATFORM=`echo "$PLATFORM_TRIPLET" | cut -d '-' -f2` ;; #( + *) : + SOABI_PLATFORM=$PLATFORM_TRIPLET + ;; +esac + +if test x$SOABI_PLATFORM != x; then + +printf "%s\n" "#define SOABI_PLATFORM \"${SOABI_PLATFORM}\"" >>confdefs.h + +fi + +if test x$MULTIARCH != x; then + MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" +fi + + +# Guess C stack direction +case $host in #( + hppa*) : + _Py_STACK_GROWS_DOWN=0 ;; #( + *) : + _Py_STACK_GROWS_DOWN=1 ;; +esac + +printf "%s\n" "#define _Py_STACK_GROWS_DOWN $_Py_STACK_GROWS_DOWN" >>confdefs.h + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PEP 11 support tier" >&5 +printf %s "checking for PEP 11 support tier... " >&6; } +case $host/$ac_cv_cc_name in #( + x86_64-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=1 ;; #( + x86_64-apple-darwin*/clang) : + PY_SUPPORT_TIER=1 ;; #( + aarch64-apple-darwin*/clang) : + PY_SUPPORT_TIER=1 ;; #( + i686-pc-windows-msvc/msvc) : + PY_SUPPORT_TIER=1 ;; #( + x86_64-pc-windows-msvc/msvc) : + PY_SUPPORT_TIER=1 ;; #( + + aarch64-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=2 ;; #( + aarch64-*-linux-gnu/clang) : + PY_SUPPORT_TIER=2 ;; #( + powerpc64le-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=2 ;; #( + wasm32-unknown-wasip1/clang) : + PY_SUPPORT_TIER=2 ;; #( + x86_64-*-linux-gnu/clang) : + PY_SUPPORT_TIER=2 ;; #( + + aarch64-pc-windows-msvc/msvc) : + PY_SUPPORT_TIER=3 ;; #( + armv7l-*-linux-gnueabihf/gcc) : + PY_SUPPORT_TIER=3 ;; #( + powerpc64le-*-linux-gnu/clang) : + PY_SUPPORT_TIER=3 ;; #( + riscv64-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=3 ;; #( + riscv64-*-linux-gnu/clang) : + PY_SUPPORT_TIER=3 ;; #( + s390x-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=3 ;; #( + x86_64-*-freebsd*/clang) : + PY_SUPPORT_TIER=3 ;; #( + aarch64-apple-ios*-simulator/clang) : + PY_SUPPORT_TIER=3 ;; #( + aarch64-apple-ios*/clang) : + PY_SUPPORT_TIER=3 ;; #( + aarch64-*-linux-android/clang) : + PY_SUPPORT_TIER=3 ;; #( + x86_64-*-linux-android/clang) : + PY_SUPPORT_TIER=3 ;; #( + wasm32-*-emscripten/emcc) : + PY_SUPPORT_TIER=3 ;; #( + *) : + + PY_SUPPORT_TIER=0 + ;; +esac + +case $PY_SUPPORT_TIER in #( + 1) : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 1 (supported)" >&5 +printf "%s\n" "$host/$ac_cv_cc_name has tier 1 (supported)" >&6; } ;; #( + 2) : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 2 (supported)" >&5 +printf "%s\n" "$host/$ac_cv_cc_name has tier 2 (supported)" >&6; } ;; #( + 3) : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 3 (partially supported)" >&5 +printf "%s\n" "$host/$ac_cv_cc_name has tier 3 (partially supported)" >&6; } ;; #( + *) : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $host/$ac_cv_cc_name is not supported" >&5 +printf "%s\n" "$as_me: WARNING: $host/$ac_cv_cc_name is not supported" >&2;} + ;; +esac + + +printf "%s\n" "#define PY_SUPPORT_TIER $PY_SUPPORT_TIER" >>confdefs.h + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -Wl,--no-as-needed" >&5 +printf %s "checking for -Wl,--no-as-needed... " >&6; } +if test ${ac_cv_wl_no_as_needed+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + save_LDFLAGS="$LDFLAGS" + as_fn_append LDFLAGS " -Wl,--no-as-needed" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + NO_AS_NEEDED="-Wl,--no-as-needed" + ac_cv_wl_no_as_needed=yes +else case e in #( + e) NO_AS_NEEDED="" + ac_cv_wl_no_as_needed=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_wl_no_as_needed" >&5 +printf "%s\n" "$ac_cv_wl_no_as_needed" >&6; } + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the Android API level" >&5 +printf %s "checking for the Android API level... " >&6; } +cat > conftest.c <<EOF +#ifdef __ANDROID__ +android_api = __ANDROID_API__ +arm_arch = __ARM_ARCH +#else +#error not Android +#endif +EOF + +if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then + ANDROID_API_LEVEL=`sed -n -e '/__ANDROID_API__/d' -e 's/^android_api = //p' conftest.out` + _arm_arch=`sed -n -e '/__ARM_ARCH/d' -e 's/^arm_arch = //p' conftest.out` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ANDROID_API_LEVEL" >&5 +printf "%s\n" "$ANDROID_API_LEVEL" >&6; } + if test -z "$ANDROID_API_LEVEL"; then + as_fn_error $? "Fatal: you must define __ANDROID_API__" "$LINENO" 5 + fi + +printf "%s\n" "#define ANDROID_API_LEVEL $ANDROID_API_LEVEL" >>confdefs.h + + + # For __android_log_write() in Python/pylifecycle.c. + LIBS="$LIBS -llog" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the Android arm ABI" >&5 +printf %s "checking for the Android arm ABI... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $_arm_arch" >&5 +printf "%s\n" "$_arm_arch" >&6; } + if test "$_arm_arch" = 7; then + BASECFLAGS="${BASECFLAGS} -mfloat-abi=softfp -mfpu=vfpv3-d16" + LDFLAGS="${LDFLAGS} -march=armv7-a -Wl,--fix-cortex-a8" + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not Android" >&5 +printf "%s\n" "not Android" >&6; } +fi +rm -f conftest.c conftest.out + +# Check for unsupported systems +case $ac_sys_system/$ac_sys_release in #( + atheos*|Linux*/1*) : + + as_fn_error $? "This system \($ac_sys_system/$ac_sys_release\) is no longer supported. See README for details." "$LINENO" 5 + + ;; #( + *) : + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-dynamic-linking" >&5 +printf %s "checking for --enable-wasm-dynamic-linking... " >&6; } +# Check whether --enable-wasm-dynamic-linking was given. +if test ${enable_wasm_dynamic_linking+y} +then : + enableval=$enable_wasm_dynamic_linking; + case $ac_sys_system in #( + Emscripten) : + ;; #( + WASI) : + ;; #( + *) : + as_fn_error $? "--enable-wasm-dynamic-linking only applies to Emscripten and WASI" "$LINENO" 5 + ;; +esac + +else case e in #( + e) + enable_wasm_dynamic_linking=missing + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_dynamic_linking" >&5 +printf "%s\n" "$enable_wasm_dynamic_linking" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-pthreads" >&5 +printf %s "checking for --enable-wasm-pthreads... " >&6; } +# Check whether --enable-wasm-pthreads was given. +if test ${enable_wasm_pthreads+y} +then : + enableval=$enable_wasm_pthreads; + case $ac_sys_system in #( + Emscripten) : + ;; #( + WASI) : + ;; #( + *) : + as_fn_error $? "--enable-wasm-pthreads only applies to Emscripten and WASI" "$LINENO" 5 + ;; +esac + +else case e in #( + e) + enable_wasm_pthreads=missing + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_pthreads" >&5 +printf "%s\n" "$enable_wasm_pthreads" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-emscripten-syscalls" >&5 +printf %s "checking for --enable-emscripten-syscalls... " >&6; } +# Check whether --enable-emscripten-syscalls was given. +if test ${enable_emscripten_syscalls+y} +then : + enableval=$enable_emscripten_syscalls; + case $ac_sys_system in #( + Emscripten) : + ;; #( + *) : + as_fn_error $? "--enable-emscripten-syscalls only applies to Emscripten" "$LINENO" 5 + ;; +esac + +else case e in #( + e) + enable_emscripten_syscalls=yes + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_emscripten_syscalls" >&5 +printf "%s\n" "$enable_emscripten_syscalls" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-suffix" >&5 +printf %s "checking for --with-suffix... " >&6; } + +# Check whether --with-suffix was given. +if test ${with_suffix+y} +then : + withval=$with_suffix; + case $with_suffix in #( + no) : + EXEEXT= ;; #( + yes) : + EXEEXT=.exe ;; #( + *) : + EXEEXT=$with_suffix + ;; +esac + +else case e in #( + e) + case $ac_sys_system in #( + Emscripten) : + EXEEXT=.mjs ;; #( + WASI) : + EXEEXT=.wasm ;; #( + *) : + EXEEXT= + ;; +esac + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXEEXT" >&5 +printf "%s\n" "$EXEEXT" >&6; } + +# Make sure we keep EXEEXT and ac_exeext sync'ed. +ac_exeext=$EXEEXT + +# Test whether we're running on a non-case-sensitive system, in which +# case we give a warning if no ext is given + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for case-insensitive build directory" >&5 +printf %s "checking for case-insensitive build directory... " >&6; } +if test ! -d CaseSensitiveTestDir; then +mkdir CaseSensitiveTestDir +fi + +if test -d casesensitivetestdir && test -z "$EXEEXT" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + BUILDEXEEXT=.exe +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + BUILDEXEEXT=$EXEEXT +fi +rmdir CaseSensitiveTestDir + +case $ac_sys_system in +hp*|HP*) + case $ac_cv_cc_name in + cc|*/cc) CC="$CC -Ae";; + esac;; +esac + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LIBRARY" >&5 +printf %s "checking LIBRARY... " >&6; } +if test -z "$LIBRARY" +then + LIBRARY='libpython$(VERSION)$(ABIFLAGS).a' +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBRARY" >&5 +printf "%s\n" "$LIBRARY" >&6; } + +# LDLIBRARY is the name of the library to link against (as opposed to the +# name of the library into which to insert object files). BLDLIBRARY is also +# the library to link against, usually. On Mac OS X frameworks, BLDLIBRARY +# is blank as the main program is not linked directly against LDLIBRARY. +# LDLIBRARYDIR is the path to LDLIBRARY, which is made in a subdirectory. On +# systems without shared libraries, LDLIBRARY is the same as LIBRARY +# (defined in the Makefiles). On Cygwin LDLIBRARY is the import library, +# DLLLIBRARY is the shared (i.e., DLL) library. +# +# RUNSHARED is used to run shared python without installed libraries +# +# INSTSONAME is the name of the shared library that will be use to install +# on the system - some systems like version suffix, others don't +# +# LDVERSION is the shared library version number, normally the Python version +# with the ABI build flags appended. + + + + + + + + +LDLIBRARY="$LIBRARY" +BLDLIBRARY='$(LDLIBRARY)' +INSTSONAME='$(LDLIBRARY)' +DLLLIBRARY='' +LDLIBRARYDIR='' +RUNSHARED='' +LDVERSION="$VERSION" + +# LINKCC is the command that links the python executable -- default is $(CC). +# If CXX is set, and if it is needed to link a main function that was +# compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable: +# python might then depend on the C++ runtime + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LINKCC" >&5 +printf %s "checking LINKCC... " >&6; } +if test -z "$LINKCC" +then + LINKCC='$(PURIFY) $(CC)' + case $ac_sys_system in + QNX*) + # qcc must be used because the other compilers do not + # support -N. + LINKCC=qcc;; + esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LINKCC" >&5 +printf "%s\n" "$LINKCC" >&6; } + +# EXPORTSYMS holds the list of exported symbols for AIX. +# EXPORTSFROM holds the module name exporting symbols on AIX. +EXPORTSYMS= +EXPORTSFROM= + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking EXPORTSYMS" >&5 +printf %s "checking EXPORTSYMS... " >&6; } +case $ac_sys_system in +AIX*) + EXPORTSYMS="Modules/python.exp" + EXPORTSFROM=. # the main executable + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXPORTSYMS" >&5 +printf "%s\n" "$EXPORTSYMS" >&6; } + +# GNULD is set to "yes" if the GNU linker is used. If this goes wrong +# make sure we default having it set to "no": this is used by +# distutils.unixccompiler to know if it should add --enable-new-dtags +# to linker command lines, and failing to detect GNU ld simply results +# in the same behaviour as before. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } +ac_prog=ld +if test "$ac_cv_cc_name" = "gcc"; then + ac_prog=`$CC -print-prog-name=ld` +fi +case `"$ac_prog" -V 2>&1 < /dev/null` in + *GNU*) + GNULD=yes;; + *) + GNULD=no;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GNULD" >&5 +printf "%s\n" "$GNULD" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-shared" >&5 +printf %s "checking for --enable-shared... " >&6; } +# Check whether --enable-shared was given. +if test ${enable_shared+y} +then : + enableval=$enable_shared; +fi + + +if test -z "$enable_shared" +then + case $ac_sys_system in + CYGWIN*) + enable_shared="yes";; + *) + enable_shared="no";; + esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +printf "%s\n" "$enable_shared" >&6; } + +# --with-static-libpython +STATIC_LIBPYTHON=1 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-static-libpython" >&5 +printf %s "checking for --with-static-libpython... " >&6; } + +# Check whether --with-static-libpython was given. +if test ${with_static_libpython+y} +then : + withval=$with_static_libpython; +if test "$withval" = no +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; + STATIC_LIBPYTHON=0 +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; +esac +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-static-libpython-for-interpreter" >&5 +printf %s "checking for --enable-static-libpython-for-interpreter... " >&6; } +# Check whether --enable-static-libpython-for-interpreter was given. +if test ${enable_static_libpython_for_interpreter+y} +then : + enableval=$enable_static_libpython_for_interpreter; +fi + + +if test -z "$enable_static_libpython_for_interpreter" +then + enable_static_libpython_for_interpreter="no" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static_libpython_for_interpreter" >&5 +printf "%s\n" "$enable_static_libpython_for_interpreter" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-profiling" >&5 +printf %s "checking for --enable-profiling... " >&6; } +# Check whether --enable-profiling was given. +if test ${enable_profiling+y} +then : + enableval=$enable_profiling; +fi + +if test "x$enable_profiling" = xyes; then + ac_save_cc="$CC" + CC="$CC -pg" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + +else case e in #( + e) enable_profiling=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + CC="$ac_save_cc" +else + enable_profiling=no +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_profiling" >&5 +printf "%s\n" "$enable_profiling" >&6; } + +if test "x$enable_profiling" = xyes; then + BASECFLAGS="-pg $BASECFLAGS" + LDFLAGS="-pg $LDFLAGS" +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDLIBRARY" >&5 +printf %s "checking LDLIBRARY... " >&6; } + +# Apple framework builds need more magic. LDLIBRARY is the dynamic +# library that we build, but we do not want to link against it (we +# will find it with a -framework option). For this reason there is an +# extra variable BLDLIBRARY against which Python and the extension +# modules are linked, BLDLIBRARY. This is normally the same as +# LDLIBRARY, but empty for MacOSX framework builds. iOS does the same, +# but uses a non-versioned framework layout. +if test "$enable_framework" +then + case $ac_sys_system in + Darwin) + LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)';; + iOS) + LDLIBRARY='$(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)';; + *) + as_fn_error $? "Unknown platform for framework build" "$LINENO" 5;; + esac + BLDLIBRARY='' + RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}} +else + BLDLIBRARY='$(LDLIBRARY)' +fi + +# Other platforms follow +if test $enable_shared = "yes"; then + PY_ENABLE_SHARED=1 + +printf "%s\n" "#define Py_ENABLE_SHARED 1" >>confdefs.h + + case $ac_sys_system in + CYGWIN*) + LDLIBRARY='libpython$(LDVERSION).dll.a' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + DLLLIBRARY='cygpython$(LDVERSION).dll' + ;; + SunOS*) + LDLIBRARY='libpython$(LDVERSION).so' + BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + INSTSONAME="$LDLIBRARY".$SOVERSION + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so + fi + ;; + Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*|VxWorks*) + LDLIBRARY='libpython$(LDVERSION).so' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + + # The Android Gradle plugin will only package libraries whose names end + # with ".so". + if test "$ac_sys_system" != "Linux-android"; then + INSTSONAME="$LDLIBRARY".$SOVERSION + fi + + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so + fi + ;; + hp*|HP*) + case `uname -m` in + ia64) + LDLIBRARY='libpython$(LDVERSION).so' + ;; + *) + LDLIBRARY='libpython$(LDVERSION).sl' + ;; + esac + BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)' + RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}} + ;; + Darwin*) + LDLIBRARY='libpython$(LDVERSION).dylib' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}} + ;; + iOS) + LDLIBRARY='libpython$(LDVERSION).dylib' + ;; + AIX*) + LDLIBRARY='libpython$(LDVERSION).so' + RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}} + ;; + + esac +else # shared is disabled + PY_ENABLE_SHARED=0 + case $ac_sys_system in + CYGWIN*) + BLDLIBRARY='$(LIBRARY)' + LDLIBRARY='libpython$(LDVERSION).a' + ;; + esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDLIBRARY" >&5 +printf "%s\n" "$LDLIBRARY" >&6; } + +# HOSTRUNNER - Program to run CPython for the host platform +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking HOSTRUNNER" >&5 +printf %s "checking HOSTRUNNER... " >&6; } +if test -z "$HOSTRUNNER" +then + case $ac_sys_system in #( + Emscripten) : + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}node", so it can be a program name with args. +set dummy ${ac_tool_prefix}node; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_NODE+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $NODE in + [\\/]* | ?:[\\/]*) + ac_cv_path_NODE="$NODE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_NODE="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +NODE=$ac_cv_path_NODE +if test -n "$NODE"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NODE" >&5 +printf "%s\n" "$NODE" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_NODE"; then + ac_pt_NODE=$NODE + # Extract the first word of "node", so it can be a program name with args. +set dummy node; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_NODE+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_NODE in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_NODE="$ac_pt_NODE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_NODE="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_NODE=$ac_cv_path_ac_pt_NODE +if test -n "$ac_pt_NODE"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_NODE" >&5 +printf "%s\n" "$ac_pt_NODE" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_NODE" = x; then + NODE="node" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NODE=$ac_pt_NODE + fi +else + NODE="$ac_cv_path_NODE" +fi + + HOSTRUNNER="$NODE" + if test "x$host_cpu" = xwasm64 +then : + as_fn_append HOSTRUNNER " --experimental-wasm-memory64" +fi + ;; #( + WASI) : + + as_fn_error $? "HOSTRUNNER must be set when cross-compiling to WASI" "$LINENO" 5 + ;; #( + *) : + HOSTRUNNER='' + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HOSTRUNNER" >&5 +printf "%s\n" "$HOSTRUNNER" >&6; } + +if test -n "$HOSTRUNNER"; then + PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" +fi + +# LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable +LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)' + +LINK_PYTHON_DEPS='$(LIBRARY_DEPS)' +if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then + LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS" + if test "$STATIC_LIBPYTHON" = 1; then + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + fi + # Link Python program to the shared library + if test "$enable_static_libpython_for_interpreter" = "yes"; then + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' + else + LINK_PYTHON_OBJS='$(BLDLIBRARY)' + fi +else + if test "$STATIC_LIBPYTHON" = 0; then + # Build Python needs object files but don't need to build + # Python static library + LINK_PYTHON_DEPS="$LIBRARY_DEPS \$(LIBRARY_OBJS)" + fi + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + # Link Python program to object files + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' +fi + + + + +# ar program + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar aal + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar aal +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="ar" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + + +# tweak ARFLAGS only if the user didn't set it on the command line + +if test -z "$ARFLAGS" +then + ARFLAGS="rcs" +fi + +case $MACHDEP in +hp*|HP*) + # install -d does not work on HP-UX + if test -z "$INSTALL" + then + INSTALL="${srcdir}/install-sh -c" + fi +esac + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + ;; +esac +fi + if test ${ac_cv_path_install+y}; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 +printf %s "checking for a race-free mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test ${ac_cv_path_mkdir+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue + case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir ('*'coreutils) '* | \ + *'BusyBox '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + ;; +esac +fi + + test -d ./--version && rmdir ./--version + if test ${ac_cv_path_mkdir+y}; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use plain mkdir -p, + # in the hope it doesn't have the bugs of ancient mkdir. + MKDIR_P='mkdir -p' + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +printf "%s\n" "$MKDIR_P" >&6; } + + +# Not every filesystem supports hard links + +if test -z "$LN" ; then + case $ac_sys_system in + CYGWIN*) LN="ln -s";; + *) LN=ln;; + esac +fi + +# For calculating the .so ABI tag. + + +ABIFLAGS="" +ABI_THREAD="" + +# Check for --disable-gil +# --disable-gil +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --disable-gil" >&5 +printf %s "checking for --disable-gil... " >&6; } +# Check whether --enable-gil was given. +if test ${enable_gil+y} +then : + enableval=$enable_gil; if test "x$enable_gil" = xyes +then : + disable_gil=no +else case e in #( + e) disable_gil=yes ;; +esac +fi +else case e in #( + e) disable_gil=no + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $disable_gil" >&5 +printf "%s\n" "$disable_gil" >&6; } + +if test "$disable_gil" = "yes" +then + +printf "%s\n" "#define Py_GIL_DISABLED 1" >>confdefs.h + + # Add "t" for "threaded" + ABIFLAGS="${ABIFLAGS}t" + ABI_THREAD="t" +fi + +# Check for --with-pydebug +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-pydebug" >&5 +printf %s "checking for --with-pydebug... " >&6; } + +# Check whether --with-pydebug was given. +if test ${with_pydebug+y} +then : + withval=$with_pydebug; +if test "$withval" != no +then + +printf "%s\n" "#define Py_DEBUG 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; + Py_DEBUG='true' + ABIFLAGS="${ABIFLAGS}d" +else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; Py_DEBUG='false' +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + +# Check for --with-trace-refs +# --with-trace-refs +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-trace-refs" >&5 +printf %s "checking for --with-trace-refs... " >&6; } + +# Check whether --with-trace-refs was given. +if test ${with_trace_refs+y} +then : + withval=$with_trace_refs; +else case e in #( + e) with_trace_refs=no + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_trace_refs" >&5 +printf "%s\n" "$with_trace_refs" >&6; } + +if test "$with_trace_refs" = "yes" +then + +printf "%s\n" "#define Py_TRACE_REFS 1" >>confdefs.h + +fi + +if test "$disable_gil" = "yes" -a "$with_trace_refs" = "yes"; +then + as_fn_error $? "--disable-gil cannot be used with --with-trace-refs" "$LINENO" 5 +fi + +# Check for --enable-pystats +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-pystats" >&5 +printf %s "checking for --enable-pystats... " >&6; } +# Check whether --enable-pystats was given. +if test ${enable_pystats+y} +then : + enableval=$enable_pystats; +else case e in #( + e) enable_pystats=no + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_pystats" >&5 +printf "%s\n" "$enable_pystats" >&6; } + +if test "x$enable_pystats" = xyes +then : + + +printf "%s\n" "#define Py_STATS 1" >>confdefs.h + + +fi + +# Check for --with-assertions. +# This allows enabling assertions without Py_DEBUG. +assertions='false' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-assertions" >&5 +printf %s "checking for --with-assertions... " >&6; } + +# Check whether --with-assertions was given. +if test ${with_assertions+y} +then : + withval=$with_assertions; +if test "$withval" != no +then + assertions='true' +fi +fi + +if test "$assertions" = 'true'; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +elif test "$Py_DEBUG" = 'true'; then + assertions='true' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: implied by --with-pydebug" >&5 +printf "%s\n" "implied by --with-pydebug" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + +# Enable optimization flags + + +Py_OPT='false' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-optimizations" >&5 +printf %s "checking for --enable-optimizations... " >&6; } +# Check whether --enable-optimizations was given. +if test ${enable_optimizations+y} +then : + enableval=$enable_optimizations; +if test "$enableval" != no +then + Py_OPT='true' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; +else + Py_OPT='false' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + +if test "$Py_OPT" = 'true' ; then + # Check for conflicting CFLAGS=-O0 and --enable-optimizations + case "$CFLAGS" in + *-O0*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: CFLAGS contains -O0 which may conflict with --enable-optimizations. Consider removing -O0 from CFLAGS for optimal performance." >&5 +printf "%s\n" "$as_me: WARNING: CFLAGS contains -O0 which may conflict with --enable-optimizations. Consider removing -O0 from CFLAGS for optimal performance." >&2;} + ;; + esac + # Intentionally not forcing Py_LTO='true' here. Too many toolchains do not + # compile working code using it and both test_distutils and test_gdb are + # broken when you do manage to get a toolchain that works with it. People + # who want LTO need to use --with-lto themselves. + DEF_MAKE_ALL_RULE="profile-opt" + REQUIRE_PGO="yes" + DEF_MAKE_RULE="build_all" + if test "x$ac_cv_gcc_compat" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-semantic-interposition" >&5 +printf %s "checking whether C compiler accepts -fno-semantic-interposition... " >&6; } +if test ${ax_cv_check_cflags__Werror__fno_semantic_interposition+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -fno-semantic-interposition" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__fno_semantic_interposition=yes +else case e in #( + e) ax_cv_check_cflags__Werror__fno_semantic_interposition=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__fno_semantic_interposition" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__fno_semantic_interposition" >&6; } +if test "x$ax_cv_check_cflags__Werror__fno_semantic_interposition" = xyes +then : + + CFLAGS_NODIST="$CFLAGS_NODIST -fno-semantic-interposition" + LDFLAGS_NODIST="$LDFLAGS_NODIST -fno-semantic-interposition" + +else case e in #( + e) : ;; +esac +fi + + +fi +elif test "$ac_sys_system" = "Emscripten"; then + DEF_MAKE_ALL_RULE="build_emscripten" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" +elif test "$ac_sys_system" = "WASI"; then + DEF_MAKE_ALL_RULE="build_wasm" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" +else + DEF_MAKE_ALL_RULE="build_all" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PROFILE_TASK" >&5 +printf %s "checking PROFILE_TASK... " >&6; } +if test -z "$PROFILE_TASK" +then + PROFILE_TASK='-m test --pgo --timeout=$(TESTTIMEOUT)' +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PROFILE_TASK" >&5 +printf "%s\n" "$PROFILE_TASK" >&6; } + +# Make llvm-related checks work on systems where llvm tools are not installed with their +# normal names in the default $PATH (ie: Ubuntu). They exist under the +# non-suffixed name in their versioned llvm directory. + +llvm_bin_dir='' +llvm_path="${PATH}" +if test "${ac_cv_cc_name}" = "clang" +then + clang_bin=`which clang` + # Some systems install clang elsewhere as a symlink to the real path + # which is where the related llvm tools are located. + if test -L "${clang_bin}" + then + clang_dir=`dirname "${clang_bin}"` + clang_bin=`readlink "${clang_bin}"` + llvm_bin_dir="${clang_dir}/"`dirname "${clang_bin}"` + llvm_path="${llvm_path}${PATH_SEPARATOR}${llvm_bin_dir}" + fi +fi + +# Enable LTO flags +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-lto" >&5 +printf %s "checking for --with-lto... " >&6; } + +# Check whether --with-lto was given. +if test ${with_lto+y} +then : + withval=$with_lto; +case "$withval" in + full) + Py_LTO='true' + Py_LTO_POLICY='full' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + ;; + thin) + Py_LTO='true' + Py_LTO_POLICY='thin' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + ;; + yes) + Py_LTO='true' + Py_LTO_POLICY='default' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + ;; + no) + Py_LTO='false' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; + *) + Py_LTO='false' + as_fn_error $? "unknown lto option: '$withval'" "$LINENO" 5 + ;; +esac + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + +if test "$Py_LTO" = 'true' ; then + case $ac_cv_cc_name in + clang) + LDFLAGS_NOLTO="-fno-lto" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +printf %s "checking whether C compiler accepts -flto=thin... " >&6; } +if test ${ax_cv_check_cflags___flto_thin+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___flto_thin=yes +else case e in #( + e) ax_cv_check_cflags___flto_thin=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +printf "%s\n" "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes +then : + LDFLAGS_NOLTO="-flto=thin" +else case e in #( + e) LDFLAGS_NOLTO="-flto" ;; +esac +fi + + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-ar; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LLVM_AR+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $LLVM_AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_AR="$LLVM_AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_AR="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +LLVM_AR=$ac_cv_path_LLVM_AR +if test -n "$LLVM_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLVM_AR" >&5 +printf "%s\n" "$LLVM_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_LLVM_AR"; then + ac_pt_LLVM_AR=$LLVM_AR + # Extract the first word of "llvm-ar", so it can be a program name with args. +set dummy llvm-ar; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_LLVM_AR+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_LLVM_AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LLVM_AR="$ac_pt_LLVM_AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_AR="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_LLVM_AR=$ac_cv_path_ac_pt_LLVM_AR +if test -n "$ac_pt_LLVM_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_AR" >&5 +printf "%s\n" "$ac_pt_LLVM_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_LLVM_AR" = x; then + LLVM_AR="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LLVM_AR=$ac_pt_LLVM_AR + fi +else + LLVM_AR="$ac_cv_path_LLVM_AR" +fi + + + if test -n "${LLVM_AR}" -a -x "${LLVM_AR}" + then + LLVM_AR_FOUND="found" + else + LLVM_AR_FOUND="not-found" + fi + if test "$ac_sys_system" = "Darwin" -a "${LLVM_AR_FOUND}" = "not-found" + then + # The Apple-supplied ar in Xcode or the Command Line Tools is apparently sufficient + found_llvm_ar=`/usr/bin/xcrun -find ar 2>/dev/null` + if test -n "${found_llvm_ar}" + then + LLVM_AR='/usr/bin/xcrun ar' + LLVM_AR_FOUND=found + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: llvm-ar found via xcrun: ${LLVM_AR}" >&5 +printf "%s\n" "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} + fi + fi + if test $LLVM_AR_FOUND = not-found + then + LLVM_PROFR_ERR=yes + as_fn_error $? "llvm-ar is required for a --with-lto build with clang but could not be found." "$LINENO" 5 + else + LLVM_AR_ERR=no + fi + AR="${LLVM_AR}" + case $ac_sys_system in + Darwin*) + # Any changes made here should be reflected in the GCC+Darwin case below + if test $Py_LTO_POLICY = default + then + # Check that ThinLTO is accepted. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +printf %s "checking whether C compiler accepts -flto=thin... " >&6; } +if test ${ax_cv_check_cflags___flto_thin+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___flto_thin=yes +else case e in #( + e) ax_cv_check_cflags___flto_thin=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +printf "%s\n" "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes +then : + + LTOFLAGS="-flto=thin -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=thin" + +else case e in #( + e) + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + + ;; +esac +fi + + else + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=${Py_LTO_POLICY}" + fi + ;; + *) + if test $Py_LTO_POLICY = default + then + # Check that ThinLTO is accepted + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +printf %s "checking whether C compiler accepts -flto=thin... " >&6; } +if test ${ax_cv_check_cflags___flto_thin+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___flto_thin=yes +else case e in #( + e) ax_cv_check_cflags___flto_thin=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +printf "%s\n" "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes +then : + LTOFLAGS="-flto=thin" +else case e in #( + e) LTOFLAGS="-flto" ;; +esac +fi + + else + LTOFLAGS="-flto=${Py_LTO_POLICY}" + fi + ;; + esac + ;; + emcc) + if test "$Py_LTO_POLICY" != "default"; then + as_fn_error $? "emcc supports only default lto." "$LINENO" 5 + fi + LTOFLAGS="-flto" + LTOCFLAGS="-flto" + ;; + gcc) + if test $Py_LTO_POLICY = thin + then + as_fn_error $? "thin lto is not supported under gcc compiler." "$LINENO" 5 + fi + LDFLAGS_NOLTO="-fno-lto" + case $ac_sys_system in + Darwin*) + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + ;; + *) + LTOFLAGS="-flto -fuse-linker-plugin -ffat-lto-objects" + ;; + esac + ;; + esac + + if test "$ac_cv_prog_cc_g" = "yes" + then + # bpo-30345: Add -g to LDFLAGS when compiling with LTO + # to get debug symbols. + LTOFLAGS="$LTOFLAGS -g" + fi + + CFLAGS_NODIST="$CFLAGS_NODIST ${LTOCFLAGS-$LTOFLAGS}" + LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS" +fi + +# Enable PGO flags. + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-profdata", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-profdata; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LLVM_PROFDATA+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $LLVM_PROFDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_PROFDATA="$LLVM_PROFDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_PROFDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +LLVM_PROFDATA=$ac_cv_path_LLVM_PROFDATA +if test -n "$LLVM_PROFDATA"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLVM_PROFDATA" >&5 +printf "%s\n" "$LLVM_PROFDATA" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_LLVM_PROFDATA"; then + ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA + # Extract the first word of "llvm-profdata", so it can be a program name with args. +set dummy llvm-profdata; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_LLVM_PROFDATA+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_LLVM_PROFDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LLVM_PROFDATA="$ac_pt_LLVM_PROFDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_PROFDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_LLVM_PROFDATA=$ac_cv_path_ac_pt_LLVM_PROFDATA +if test -n "$ac_pt_LLVM_PROFDATA"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_PROFDATA" >&5 +printf "%s\n" "$ac_pt_LLVM_PROFDATA" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_LLVM_PROFDATA" = x; then + LLVM_PROFDATA="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LLVM_PROFDATA=$ac_pt_LLVM_PROFDATA + fi +else + LLVM_PROFDATA="$ac_cv_path_LLVM_PROFDATA" +fi + + +if test -n "${LLVM_PROFDATA}" -a -x "${LLVM_PROFDATA}" +then + LLVM_PROF_FOUND="found" +else + LLVM_PROF_FOUND="not-found" +fi +if test "$ac_sys_system" = "Darwin" -a "${LLVM_PROF_FOUND}" = "not-found" +then + found_llvm_profdata=`/usr/bin/xcrun -find llvm-profdata 2>/dev/null` + if test -n "${found_llvm_profdata}" + then + # llvm-profdata isn't directly in $PATH in some cases. + # https://apple.stackexchange.com/questions/197053/ + LLVM_PROFDATA='/usr/bin/xcrun llvm-profdata' + LLVM_PROF_FOUND=found + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&5 +printf "%s\n" "$as_me: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&6;} + fi +fi +LLVM_PROF_ERR=no + +case "$ac_cv_cc_name" in + clang|icx) + # Any changes made here should be reflected in the GCC+Darwin case below + PGO_PROF_GEN_FLAG="-fprofile-instr-generate" + PGO_PROF_USE_FLAG="-fprofile-instr-use=\"\$(shell pwd)/code.profclangd\"" + LLVM_PROF_MERGER=" ${LLVM_PROFDATA} merge -output=\"\$(shell pwd)/code.profclangd\" \"\$(shell pwd)\"/*.profclangr " + LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"\$(shell pwd)/code-%p.profclangr\"" + if test $LLVM_PROF_FOUND = not-found + then + LLVM_PROF_ERR=yes + if test "${REQUIRE_PGO}" = "yes" + then + as_fn_error $? "llvm-profdata is required for a --enable-optimizations build but could not be found." "$LINENO" 5 + fi + fi + ;; + gcc) + # Check for 32-bit x86 ISA + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for i686" >&5 +printf %s "checking for i686... " >&6; } +if test ${ac_cv_i686+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #ifdef __i386__ + # error "i386" + #endif + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_i686=no +else case e in #( + e) ac_cv_i686=yes ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_i686" >&5 +printf "%s\n" "$ac_cv_i686" >&6; } + + PGO_PROF_GEN_FLAG="-fprofile-generate" + + # Use -fprofile-update=atomic to fix a random GCC internal error on PGO + # build (gh-145801) caused by corruption of profile data (.gcda files). + # + # gh-148535: On i686, using -fprofile-update=atomic makes the PGO build + # way slower (up to 47x slower). So far, the GCC internal error on PGO + # build was not seen on i686, so don't use this flag on i686. + if test "x$ac_cv_i686" = xno +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fprofile-update=atomic" >&5 +printf %s "checking whether C compiler accepts -fprofile-update=atomic... " >&6; } +if test ${ax_cv_check_cflags___fprofile_update_atomic+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fprofile-update=atomic" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___fprofile_update_atomic=yes +else case e in #( + e) ax_cv_check_cflags___fprofile_update_atomic=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fprofile_update_atomic" >&5 +printf "%s\n" "$ax_cv_check_cflags___fprofile_update_atomic" >&6; } +if test "x$ax_cv_check_cflags___fprofile_update_atomic" = xyes +then : + PGO_PROF_GEN_FLAG="$PGO_PROF_GEN_FLAG -fprofile-update=atomic" +else case e in #( + e) : ;; +esac +fi + + +fi + + PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction" + LLVM_PROF_MERGER="true" + LLVM_PROF_FILE="" + ;; + icc) + PGO_PROF_GEN_FLAG="-prof-gen" + PGO_PROF_USE_FLAG="-prof-use" + LLVM_PROF_MERGER="true" + LLVM_PROF_FILE="" + ;; +esac + +# BOLT optimization. Always configured after PGO since it always runs after PGO. +Py_BOLT='false' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-bolt" >&5 +printf %s "checking for --enable-bolt... " >&6; } +# Check whether --enable-bolt was given. +if test ${enable_bolt+y} +then : + enableval=$enable_bolt; +if test "$enableval" != no +then + Py_BOLT='true' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; +else + Py_BOLT='false' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + + +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" + + # -fno-reorder-blocks-and-partition is required for bolt to work. + # Possibly GCC only. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-reorder-blocks-and-partition" >&5 +printf %s "checking whether C compiler accepts -fno-reorder-blocks-and-partition... " >&6; } +if test ${ax_cv_check_cflags___fno_reorder_blocks_and_partition+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fno-reorder-blocks-and-partition" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___fno_reorder_blocks_and_partition=yes +else case e in #( + e) ax_cv_check_cflags___fno_reorder_blocks_and_partition=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_reorder_blocks_and_partition" >&5 +printf "%s\n" "$ax_cv_check_cflags___fno_reorder_blocks_and_partition" >&6; } +if test "x$ax_cv_check_cflags___fno_reorder_blocks_and_partition" = xyes +then : + + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + +else case e in #( + e) : ;; +esac +fi + + + # These flags are required for bolt to work: + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" + + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-bolt", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-bolt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LLVM_BOLT+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_BOLT="$LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_BOLT="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +LLVM_BOLT=$ac_cv_path_LLVM_BOLT +if test -n "$LLVM_BOLT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLVM_BOLT" >&5 +printf "%s\n" "$LLVM_BOLT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_LLVM_BOLT"; then + ac_pt_LLVM_BOLT=$LLVM_BOLT + # Extract the first word of "llvm-bolt", so it can be a program name with args. +set dummy llvm-bolt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_LLVM_BOLT+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LLVM_BOLT="$ac_pt_LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_BOLT="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_LLVM_BOLT=$ac_cv_path_ac_pt_LLVM_BOLT +if test -n "$ac_pt_LLVM_BOLT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_BOLT" >&5 +printf "%s\n" "$ac_pt_LLVM_BOLT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_LLVM_BOLT" = x; then + LLVM_BOLT="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LLVM_BOLT=$ac_pt_LLVM_BOLT + fi +else + LLVM_BOLT="$ac_cv_path_LLVM_BOLT" +fi + + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"Found llvm-bolt\"" >&5 +printf "%s\n" "\"Found llvm-bolt\"" >&6; } + else + as_fn_error $? "llvm-bolt is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi + + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}merge-fdata", so it can be a program name with args. +set dummy ${ac_tool_prefix}merge-fdata; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_MERGE_FDATA+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_MERGE_FDATA="$MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_MERGE_FDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +MERGE_FDATA=$ac_cv_path_MERGE_FDATA +if test -n "$MERGE_FDATA"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MERGE_FDATA" >&5 +printf "%s\n" "$MERGE_FDATA" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_MERGE_FDATA"; then + ac_pt_MERGE_FDATA=$MERGE_FDATA + # Extract the first word of "merge-fdata", so it can be a program name with args. +set dummy merge-fdata; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_MERGE_FDATA+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $ac_pt_MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_MERGE_FDATA="$ac_pt_MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_MERGE_FDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac ;; +esac +fi +ac_pt_MERGE_FDATA=$ac_cv_path_ac_pt_MERGE_FDATA +if test -n "$ac_pt_MERGE_FDATA"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_MERGE_FDATA" >&5 +printf "%s\n" "$ac_pt_MERGE_FDATA" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_MERGE_FDATA" = x; then + MERGE_FDATA="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MERGE_FDATA=$ac_pt_MERGE_FDATA + fi +else + MERGE_FDATA="$ac_cv_path_MERGE_FDATA" +fi + + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"Found merge-fdata\"" >&5 +printf "%s\n" "\"Found merge-fdata\"" >&6; } + else + as_fn_error $? "merge-fdata is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi +fi + + +BOLT_BINARIES='$(BUILDPYTHON)' +if test "x$enable_shared" = xyes +then : + + if test "x$enable_static_libpython_for_interpreter" = xno +then : + + BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" + +fi + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking BOLT_COMMON_FLAGS" >&5 +printf %s "checking BOLT_COMMON_FLAGS... " >&6; } +if test -z "${BOLT_COMMON_FLAGS}" +then + BOLT_COMMON_FLAGS=" -update-debug-sections -skip-funcs=_PyEval_EvalFrameDefault,sre_ucs1_match/1,sre_ucs2_match/1,sre_ucs4_match/1,sre_ucs1_match.lto_priv.0/1,sre_ucs2_match.lto_priv.0/1,sre_ucs4_match.lto_priv.0/1 " + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking BOLT_INSTRUMENT_FLAGS" >&5 +printf %s "checking BOLT_INSTRUMENT_FLAGS... " >&6; } +if test -z "${BOLT_INSTRUMENT_FLAGS}" +then + BOLT_INSTRUMENT_FLAGS="${BOLT_COMMON_FLAGS}" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BOLT_INSTRUMENT_FLAGS" >&5 +printf "%s\n" "$BOLT_INSTRUMENT_FLAGS" >&6; } + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking BOLT_APPLY_FLAGS" >&5 +printf %s "checking BOLT_APPLY_FLAGS... " >&6; } +if test -z "${BOLT_APPLY_FLAGS}" +then + BOLT_APPLY_FLAGS=" ${BOLT_COMMON_FLAGS} -reorder-blocks=ext-tsp -reorder-functions=cdsort -split-functions -icf=0 -inline-all -split-eh -reorder-functions-use-hot-size -peepholes=none -jump-tables=aggressive -inline-ap -indirect-call-promotion=all -dyno-stats -use-gnu-stack -frame-opt=hot " + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BOLT_APPLY_FLAGS" >&5 +printf "%s\n" "$BOLT_APPLY_FLAGS" >&6; } + +# XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be +# merged with this chunk of code? + +# Optimizer/debugger flags +# ------------------------ +# (The following bit of code is complicated enough - please keep things +# indented properly. Just pretend you're editing Python code. ;-) + +# There are two parallel sets of case statements below, one that checks to +# see if OPT was set and one that does BASECFLAGS setting based upon +# compiler and platform. BASECFLAGS tweaks need to be made even if the +# user set OPT. + +save_CFLAGS=$CFLAGS +CFLAGS="-fstrict-overflow -fno-strict-overflow" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports -fstrict-overflow and -fno-strict-overflow" >&5 +printf %s "checking if $CC supports -fstrict-overflow and -fno-strict-overflow... " >&6; } +if test ${ac_cv_cc_supports_fstrict_overflow+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_cc_supports_fstrict_overflow=yes +else case e in #( + e) ac_cv_cc_supports_fstrict_overflow=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_supports_fstrict_overflow" >&5 +printf "%s\n" "$ac_cv_cc_supports_fstrict_overflow" >&6; } +CFLAGS=$save_CFLAGS + +if test "x$ac_cv_cc_supports_fstrict_overflow" = xyes +then : + STRICT_OVERFLOW_CFLAGS="-fstrict-overflow" + NO_STRICT_OVERFLOW_CFLAGS="-fno-strict-overflow" +else case e in #( + e) STRICT_OVERFLOW_CFLAGS="" + NO_STRICT_OVERFLOW_CFLAGS="" ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-strict-overflow" >&5 +printf %s "checking for --with-strict-overflow... " >&6; } + +# Check whether --with-strict-overflow was given. +if test ${with_strict_overflow+y} +then : + withval=$with_strict_overflow; + if test "x$ac_cv_cc_supports_fstrict_overflow" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --with-strict-overflow=yes requires a compiler that supports -fstrict-overflow" >&5 +printf "%s\n" "$as_me: WARNING: --with-strict-overflow=yes requires a compiler that supports -fstrict-overflow" >&2;} +fi + +else case e in #( + e) with_strict_overflow=no + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_strict_overflow" >&5 +printf "%s\n" "$with_strict_overflow" >&6; } + +# Check if CC supports -Og optimization level +save_CFLAGS=$CFLAGS +CFLAGS="-Og" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Og optimization level" >&5 +printf %s "checking if $CC supports -Og optimization level... " >&6; } +if test ${ac_cv_cc_supports_og+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + ac_cv_cc_supports_og=yes + +else case e in #( + e) + ac_cv_cc_supports_og=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_supports_og" >&5 +printf "%s\n" "$ac_cv_cc_supports_og" >&6; } +CFLAGS=$save_CFLAGS + +# Optimization messes up debuggers, so turn it off for +# debug builds. +PYDEBUG_CFLAGS="-O0" +if test "x$ac_cv_cc_supports_og" = xyes +then : + PYDEBUG_CFLAGS="-Og" +fi + +# gh-120688: WASI uses -O3 in debug mode to support more recursive calls +if test "$ac_sys_system" = "WASI"; then + PYDEBUG_CFLAGS="-O3" +fi + +# tweak OPT based on compiler and platform, only if the user didn't set +# it on the command line + + +if test "${OPT-unset}" = "unset" +then + case $GCC in + yes) + if test "${ac_cv_cc_name}" != "clang" + then + # bpo-30104: disable strict aliasing to compile correctly dtoa.c, + # see Makefile.pre.in for more information + CFLAGS_ALIASING="-fno-strict-aliasing" + fi + + case $ac_cv_prog_cc_g in + yes) + if test "$Py_DEBUG" = 'true' ; then + OPT="-g $PYDEBUG_CFLAGS -Wall" + else + OPT="-g -O3 -Wall" + fi + ;; + *) + OPT="-O3 -Wall" + ;; + esac + + case $ac_sys_system in + SCO_SV*) OPT="$OPT -m486 -DSCO5" + ;; + esac + ;; + + *) + OPT="-O" + ;; + esac +fi + +# WASM flags +case $ac_sys_system in #( + Emscripten) : + + if test "x$Py_DEBUG" = xyes +then : + wasm_debug=yes +else case e in #( + e) wasm_debug=no ;; +esac +fi + + as_fn_append LINKFORSHARED " -sALLOW_MEMORY_GROWTH -sINITIAL_MEMORY=20971520" + + as_fn_append LDFLAGS_NODIST " -sWASM_BIGINT" + + as_fn_append LINKFORSHARED " -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js" + as_fn_append LINKFORSHARED " -sEXPORTED_RUNTIME_METHODS=FS,callMain,ENV,HEAPU32,TTY,ERRNO_CODES" + as_fn_append LINKFORSHARED " -sEXPORTED_FUNCTIONS=_main,_Py_Version,__PyRuntime,_PyGILState_GetThisThreadState,__PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET" + as_fn_append LINKFORSHARED " -sSTACK_SIZE=5MB" + as_fn_append LINKFORSHARED " -sTEXTDECODER=2" + + if test "x$enable_wasm_dynamic_linking" = xyes +then : + + as_fn_append LINKFORSHARED " -sMAIN_MODULE" + +fi + + if test "x$enable_wasm_pthreads" = xyes +then : + + as_fn_append CFLAGS_NODIST " -pthread" + as_fn_append LDFLAGS_NODIST " -sUSE_PTHREADS" + as_fn_append LINKFORSHARED " -sPROXY_TO_PTHREAD" + +fi + as_fn_append LDFLAGS_NODIST " -sEXIT_RUNTIME" + WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map" + + if test "x$wasm_debug" = xyes +then : + + as_fn_append LDFLAGS_NODIST " -sASSERTIONS" + as_fn_append LINKFORSHARED " $WASM_LINKFORSHARED_DEBUG" + +else case e in #( + e) + as_fn_append LINKFORSHARED " -O2 -g0" + ;; +esac +fi + ;; #( + WASI) : + + +printf "%s\n" "#define _WASI_EMULATED_SIGNAL 1" >>confdefs.h + + +printf "%s\n" "#define _WASI_EMULATED_GETPID 1" >>confdefs.h + + +printf "%s\n" "#define _WASI_EMULATED_PROCESS_CLOCKS 1" >>confdefs.h + + LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" + echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h + + if test "x$enable_wasm_pthreads" = xyes +then : + + # Note: update CFLAGS because ac_compile/ac_link needs this too. + # without this, configure fails to find pthread_create, sem_init, + # etc because they are only available in the sysroot for + # wasm32-wasi-threads. + # Note: wasi-threads requires --import-memory. + # Note: wasi requires --export-memory. + # Note: --export-memory is implicit unless --import-memory is given + # Note: this requires LLVM >= 16. + as_fn_append CFLAGS " -target wasm32-wasi-threads -pthread" + as_fn_append CFLAGS_NODIST " -target wasm32-wasi-threads -pthread" + as_fn_append LDFLAGS_NODIST " -target wasm32-wasi-threads -pthread" + as_fn_append LDFLAGS_NODIST " -Wl,--import-memory" + as_fn_append LDFLAGS_NODIST " -Wl,--export-memory" + as_fn_append LDFLAGS_NODIST " -Wl,--max-memory=10485760" + +fi + + as_fn_append LDFLAGS_NODIST " -z stack-size=16777216 -Wl,--stack-first -Wl,--initial-memory=41943040" + + ;; #( + *) : + ;; +esac + +if test "$ac_sys_system" = "Linux" -a "$cross_compiling" = no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for thread stack size" >&5 +printf %s "checking for thread stack size... " >&6; } +if test ${ac_cv_thread_stack_size+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat > conftest.c <<EOF +#include <pthread.h> + +int main() +{ + pthread_attr_t attrs; + size_t size; + + int rc = pthread_attr_init(&attrs); + if (rc != 0) { + return 2; + } + + rc = pthread_attr_getstacksize(&attrs, &size); + if (rc != 0) { + return 2; + } + + if (size < 1024 * 1024) { + return 1; + } + return 0; +} +EOF + + ac_cv_thread_stack_size=unknown + if $CC -pthread $CFLAGS conftest.c -o conftest &>/dev/null; then + ./conftest &>/dev/null + exitcode=$? + if test $exitcode -eq 1; then + ac_cv_thread_stack_size=1048576 + elif test $exitcode -eq 0; then + ac_cv_thread_stack_size="default" + fi + fi + rm -f conftest.c conftest + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_thread_stack_size" >&5 +printf "%s\n" "$ac_cv_thread_stack_size" >&6; } + + if test "$ac_cv_thread_stack_size" != "default" -a "$ac_cv_thread_stack_size" != "unknown"; then + LDFLAGS="$LDFLAGS -Wl,-z,stack-size=$ac_cv_thread_stack_size" + # Stack size used by Python/ceval.c to set Py_C_STACK_SIZE + +printf "%s\n" "#define _Py_LINKER_THREAD_STACK_SIZE $ac_cv_thread_stack_size" >>confdefs.h + + fi +fi + +case $enable_wasm_dynamic_linking in #( + yes) : + ac_cv_func_dlopen=yes ;; #( + no) : + ac_cv_func_dlopen=no ;; #( + missing) : + + ;; #( + *) : + ;; +esac + + + + + + + + + +# The -arch flags for universal builds on macOS +UNIVERSAL_ARCH_FLAGS= + + + + +# tweak BASECFLAGS based on compiler and platform +if test "x$with_strict_overflow" = xyes +then : + BASECFLAGS="$BASECFLAGS $STRICT_OVERFLOW_CFLAGS" +else case e in #( + e) BASECFLAGS="$BASECFLAGS $NO_STRICT_OVERFLOW_CFLAGS" ;; +esac +fi + +# Enable flags that warn and protect for potential security vulnerabilities. +# These flags should be enabled by default for all builds. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-safety" >&5 +printf %s "checking for --enable-safety... " >&6; } +# Check whether --enable-safety was given. +if test ${enable_safety+y} +then : + enableval=$enable_safety; if test "x$disable_safety" = xyes +then : + enable_safety=no +else case e in #( + e) enable_safety=yes ;; +esac +fi +else case e in #( + e) enable_safety=no ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_safety" >&5 +printf "%s\n" "$enable_safety" >&6; } + +if test "$enable_safety" = "yes" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fstack-protector-strong" >&5 +printf %s "checking whether C compiler accepts -fstack-protector-strong... " >&6; } +if test ${ax_cv_check_cflags__Werror__fstack_protector_strong+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -fstack-protector-strong" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__fstack_protector_strong=yes +else case e in #( + e) ax_cv_check_cflags__Werror__fstack_protector_strong=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__fstack_protector_strong" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__fstack_protector_strong" >&6; } +if test "x$ax_cv_check_cflags__Werror__fstack_protector_strong" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -fstack-protector-strong" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: -fstack-protector-strong not supported" >&5 +printf "%s\n" "$as_me: WARNING: -fstack-protector-strong not supported" >&2;} ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wtrampolines" >&5 +printf %s "checking whether C compiler accepts -Wtrampolines... " >&6; } +if test ${ax_cv_check_cflags__Werror__Wtrampolines+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -Wtrampolines" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__Wtrampolines=yes +else case e in #( + e) ax_cv_check_cflags__Werror__Wtrampolines=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__Wtrampolines" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__Wtrampolines" >&6; } +if test "x$ax_cv_check_cflags__Werror__Wtrampolines" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wtrampolines" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: -Wtrampolines not supported" >&5 +printf "%s\n" "$as_me: WARNING: -Wtrampolines not supported" >&2;} ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wimplicit-fallthrough" >&5 +printf %s "checking whether C compiler accepts -Wimplicit-fallthrough... " >&6; } +if test ${ax_cv_check_cflags__Werror__Wimplicit_fallthrough+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -Wimplicit-fallthrough" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__Wimplicit_fallthrough=yes +else case e in #( + e) ax_cv_check_cflags__Werror__Wimplicit_fallthrough=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__Wimplicit_fallthrough" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__Wimplicit_fallthrough" >&6; } +if test "x$ax_cv_check_cflags__Werror__Wimplicit_fallthrough" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wimplicit-fallthrough" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: -Wimplicit-fallthrough not supported" >&5 +printf "%s\n" "$as_me: WARNING: -Wimplicit-fallthrough not supported" >&2;} ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Werror=format-security" >&5 +printf %s "checking whether C compiler accepts -Werror=format-security... " >&6; } +if test ${ax_cv_check_cflags__Werror__Werror_format_security+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -Werror=format-security" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__Werror_format_security=yes +else case e in #( + e) ax_cv_check_cflags__Werror__Werror_format_security=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__Werror_format_security" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__Werror_format_security" >&6; } +if test "x$ax_cv_check_cflags__Werror__Werror_format_security" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Werror=format-security" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: -Werror=format-security not supported" >&5 +printf "%s\n" "$as_me: WARNING: -Werror=format-security not supported" >&2;} ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wbidi-chars=any" >&5 +printf %s "checking whether C compiler accepts -Wbidi-chars=any... " >&6; } +if test ${ax_cv_check_cflags__Werror__Wbidi_chars_any+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -Wbidi-chars=any" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__Wbidi_chars_any=yes +else case e in #( + e) ax_cv_check_cflags__Werror__Wbidi_chars_any=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__Wbidi_chars_any" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__Wbidi_chars_any" >&6; } +if test "x$ax_cv_check_cflags__Werror__Wbidi_chars_any" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wbidi-chars=any" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: -Wbidi-chars=any not supported" >&5 +printf "%s\n" "$as_me: WARNING: -Wbidi-chars=any not supported" >&2;} ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wall" >&5 +printf %s "checking whether C compiler accepts -Wall... " >&6; } +if test ${ax_cv_check_cflags__Werror__Wall+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -Wall" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__Wall=yes +else case e in #( + e) ax_cv_check_cflags__Werror__Wall=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__Wall" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__Wall" >&6; } +if test "x$ax_cv_check_cflags__Werror__Wall" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wall" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: -Wall not supported" >&5 +printf "%s\n" "$as_me: WARNING: -Wall not supported" >&2;} ;; +esac +fi + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-slower-safety" >&5 +printf %s "checking for --enable-slower-safety... " >&6; } +# Check whether --enable-slower-safety was given. +if test ${enable_slower_safety+y} +then : + enableval=$enable_slower_safety; if test "x$disable_slower_safety" = xyes +then : + enable_slower_safety=no +else case e in #( + e) enable_slower_safety=yes ;; +esac +fi +else case e in #( + e) enable_slower_safety=no ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_slower_safety" >&5 +printf "%s\n" "$enable_slower_safety" >&6; } + +if test "$enable_slower_safety" = "yes" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -D_FORTIFY_SOURCE=3" >&5 +printf %s "checking whether C compiler accepts -D_FORTIFY_SOURCE=3... " >&6; } +if test ${ax_cv_check_cflags__Werror__D_FORTIFY_SOURCE_3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -D_FORTIFY_SOURCE=3" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__D_FORTIFY_SOURCE_3=yes +else case e in #( + e) ax_cv_check_cflags__Werror__D_FORTIFY_SOURCE_3=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__D_FORTIFY_SOURCE_3" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__D_FORTIFY_SOURCE_3" >&6; } +if test "x$ax_cv_check_cflags__Werror__D_FORTIFY_SOURCE_3" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: -D_FORTIFY_SOURCE=3 not supported" >&5 +printf "%s\n" "$as_me: WARNING: -D_FORTIFY_SOURCE=3 not supported" >&2;} ;; +esac +fi + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build with frame pointers" >&5 +printf %s "checking whether to build with frame pointers... " >&6; } + +# Check whether --with-frame-pointers was given. +if test ${with_frame_pointers+y} +then : + withval=$with_frame_pointers; +else case e in #( + e) with_frame_pointers=yes ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_frame_pointers" >&5 +printf "%s\n" "$with_frame_pointers" >&6; } + +if test "x$ac_cv_gcc_compat" = xyes +then : + + frame_pointer_cflags= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-omit-frame-pointer" >&5 +printf %s "checking whether C compiler accepts -fno-omit-frame-pointer... " >&6; } +if test ${ax_cv_check_cflags__Werror__fno_omit_frame_pointer+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -fno-omit-frame-pointer" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__fno_omit_frame_pointer=yes +else case e in #( + e) ax_cv_check_cflags__Werror__fno_omit_frame_pointer=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__fno_omit_frame_pointer" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__fno_omit_frame_pointer" >&6; } +if test "x$ax_cv_check_cflags__Werror__fno_omit_frame_pointer" = xyes +then : + + frame_pointer_cflags="-fno-omit-frame-pointer" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -mno-omit-leaf-frame-pointer" >&5 +printf %s "checking whether C compiler accepts -mno-omit-leaf-frame-pointer... " >&6; } +if test ${ax_cv_check_cflags__Werror__mno_omit_leaf_frame_pointer+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -mno-omit-leaf-frame-pointer" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__mno_omit_leaf_frame_pointer=yes +else case e in #( + e) ax_cv_check_cflags__Werror__mno_omit_leaf_frame_pointer=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__mno_omit_leaf_frame_pointer" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__mno_omit_leaf_frame_pointer" >&6; } +if test "x$ax_cv_check_cflags__Werror__mno_omit_leaf_frame_pointer" = xyes +then : + + frame_pointer_cflags="$frame_pointer_cflags -mno-omit-leaf-frame-pointer" + +else case e in #( + e) : ;; +esac +fi + + case $host_cpu in #( + arm|armv*) : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -marm" >&5 +printf %s "checking whether C compiler accepts -marm... " >&6; } +if test ${ax_cv_check_cflags__Werror__marm+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -marm" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__marm=yes +else case e in #( + e) ax_cv_check_cflags__Werror__marm=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__marm" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__marm" >&6; } +if test "x$ax_cv_check_cflags__Werror__marm" = xyes +then : + + frame_pointer_cflags="$frame_pointer_cflags -marm" + +else case e in #( + e) : ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -mno-thumb" >&5 +printf %s "checking whether C compiler accepts -mno-thumb... " >&6; } +if test ${ax_cv_check_cflags__Werror__mno_thumb+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -mno-thumb" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__mno_thumb=yes +else case e in #( + e) ax_cv_check_cflags__Werror__mno_thumb=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__mno_thumb" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__mno_thumb" >&6; } +if test "x$ax_cv_check_cflags__Werror__mno_thumb" = xyes +then : + + frame_pointer_cflags="$frame_pointer_cflags -mno-thumb" + +else case e in #( + e) : ;; +esac +fi + + ;; #( + *) : + ;; +esac + case $host_cpu in #( + powerpc64le) : + + frame_pointer_cflags="" + ;; #( + *) : + ;; +esac + case $host_cpu in #( + s390*) : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -mbackchain" >&5 +printf %s "checking whether C compiler accepts -mbackchain... " >&6; } +if test ${ax_cv_check_cflags__Werror__mbackchain+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -mbackchain" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__mbackchain=yes +else case e in #( + e) ax_cv_check_cflags__Werror__mbackchain=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__mbackchain" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__mbackchain" >&6; } +if test "x$ax_cv_check_cflags__Werror__mbackchain" = xyes +then : + + frame_pointer_cflags="-mbackchain" + +else case e in #( + e) : ;; +esac +fi + + ;; #( + *) : + ;; +esac + +else case e in #( + e) : ;; +esac +fi + + if test -n "$frame_pointer_cflags" && test "x$with_frame_pointers" != xno; then + BASECFLAGS="$frame_pointer_cflags $BASECFLAGS" + +printf "%s\n" "#define _Py_WITH_FRAME_POINTERS 1" >>confdefs.h + + fi + + CFLAGS_NODIST="$CFLAGS_NODIST -std=c11" + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can add -Wextra" >&5 +printf %s "checking if we can add -Wextra... " >&6; } +if test ${ac_cv_enable_extra_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wextra -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_enable_extra_warning=yes +else case e in #( + e) ac_cv_enable_extra_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_extra_warning" >&5 +printf "%s\n" "$ac_cv_enable_extra_warning" >&6; } + + + if test "x$ac_cv_enable_extra_warning" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wextra" +fi + + # Python doesn't violate C99 aliasing rules, but older versions of + # GCC produce warnings for legal Python code. Enable + # -fno-strict-aliasing on versions of GCC that support but produce + # warnings. See Issue3326 + ac_save_cc="$CC" + CC="$CC -fno-strict-aliasing" + save_CFLAGS="$CFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts and needs -fno-strict-aliasing" >&5 +printf %s "checking whether $CC accepts and needs -fno-strict-aliasing... " >&6; } +if test ${ac_cv_no_strict_aliasing+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + CC="$ac_save_cc -fstrict-aliasing" + CFLAGS="$CFLAGS -Werror -Wstrict-aliasing" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + void f(int **x) {} +int +main (void) +{ +double *x; f((int **) &x); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + ac_cv_no_strict_aliasing=no + +else case e in #( + e) + ac_cv_no_strict_aliasing=yes + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +else case e in #( + e) + ac_cv_no_strict_aliasing=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_no_strict_aliasing" >&5 +printf "%s\n" "$ac_cv_no_strict_aliasing" >&6; } + CFLAGS="$save_CFLAGS" + CC="$ac_save_cc" + if test "x$ac_cv_no_strict_aliasing" = xyes +then : + BASECFLAGS="$BASECFLAGS -fno-strict-aliasing" +fi + + # ICC doesn't recognize the option, but only emits a warning + ## XXX does it emit an unused result warning and can it be disabled? + case "$ac_cv_cc_name" in #( + icc) : + ac_cv_disable_unused_result_warning=no + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC unused-result warning" >&5 +printf %s "checking if we can disable $CC unused-result warning... " >&6; } +if test ${ac_cv_disable_unused_result_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wunused-result -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_disable_unused_result_warning=yes +else case e in #( + e) ac_cv_disable_unused_result_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_unused_result_warning" >&5 +printf "%s\n" "$ac_cv_disable_unused_result_warning" >&6; } + + ;; #( + *) : + ;; +esac + if test "x$ac_cv_disable_unused_result_warning" = xyes +then : + BASECFLAGS="$BASECFLAGS -Wno-unused-result" + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-result" +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC unused-parameter warning" >&5 +printf %s "checking if we can disable $CC unused-parameter warning... " >&6; } +if test ${ac_cv_disable_unused_parameter_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wunused-parameter -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_disable_unused_parameter_warning=yes +else case e in #( + e) ac_cv_disable_unused_parameter_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_unused_parameter_warning" >&5 +printf "%s\n" "$ac_cv_disable_unused_parameter_warning" >&6; } + + + if test "x$ac_cv_disable_unused_parameter_warning" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-parameter" +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC int-conversion warning" >&5 +printf %s "checking if we can disable $CC int-conversion warning... " >&6; } +if test ${ac_cv_disable_int_conversion_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wint-conversion -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_disable_int_conversion_warning=yes +else case e in #( + e) ac_cv_disable_int_conversion_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_int_conversion_warning" >&5 +printf "%s\n" "$ac_cv_disable_int_conversion_warning" >&6; } + + + if test "x$ac_cv_disable_int_conversion" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-int-conversion" +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC missing-field-initializers warning" >&5 +printf %s "checking if we can disable $CC missing-field-initializers warning... " >&6; } +if test ${ac_cv_disable_missing_field_initializers_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wmissing-field-initializers -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_disable_missing_field_initializers_warning=yes +else case e in #( + e) ac_cv_disable_missing_field_initializers_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_missing_field_initializers_warning" >&5 +printf "%s\n" "$ac_cv_disable_missing_field_initializers_warning" >&6; } + + + if test "x$ac_cv_disable_missing_field_initializers_warning" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-missing-field-initializers" +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC sign-compare warning" >&5 +printf %s "checking if we can enable $CC sign-compare warning... " >&6; } +if test ${ac_cv_enable_sign_compare_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wsign-compare -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_enable_sign_compare_warning=yes +else case e in #( + e) ac_cv_enable_sign_compare_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_sign_compare_warning" >&5 +printf "%s\n" "$ac_cv_enable_sign_compare_warning" >&6; } + + + if test "x$ac_cv_enable_sign_compare_warning" = xyes +then : + BASECFLAGS="$BASECFLAGS -Wsign-compare" +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC unreachable-code warning" >&5 +printf %s "checking if we can enable $CC unreachable-code warning... " >&6; } +if test ${ac_cv_enable_unreachable_code_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wunreachable-code -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_enable_unreachable_code_warning=yes +else case e in #( + e) ac_cv_enable_unreachable_code_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_unreachable_code_warning" >&5 +printf "%s\n" "$ac_cv_enable_unreachable_code_warning" >&6; } + + + # Don't enable unreachable code warning in debug mode, since it usually + # results in non-standard code paths. + # Issue #24324: Unfortunately, the unreachable code warning does not work + # correctly on gcc and has been silently removed from the compiler. + # It is supported on clang but on OS X systems gcc may be an alias + # for clang. Try to determine if the compiler is not really gcc and, + # if so, only then enable the warning. + if test $ac_cv_enable_unreachable_code_warning = yes && \ + test "$Py_DEBUG" != "true" && \ + test -z "`$CC --version 2>/dev/null | grep 'Free Software Foundation'`" + then + BASECFLAGS="$BASECFLAGS -Wunreachable-code" + else + ac_cv_enable_unreachable_code_warning=no + fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC strict-prototypes warning" >&5 +printf %s "checking if we can enable $CC strict-prototypes warning... " >&6; } +if test ${ac_cv_enable_strict_prototypes_warning+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + py_cflags=$CFLAGS + as_fn_append CFLAGS " -Wstrict-prototypes -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_enable_strict_prototypes_warning=yes +else case e in #( + e) ac_cv_enable_strict_prototypes_warning=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_strict_prototypes_warning" >&5 +printf "%s\n" "$ac_cv_enable_strict_prototypes_warning" >&6; } + + + if test "x$ac_cv_enable_strict_prototypes_warning" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wstrict-prototypes" +fi + + ac_save_cc="$CC" + CC="$CC -Werror=implicit-function-declaration" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can make implicit function declaration an error in $CC" >&5 +printf %s "checking if we can make implicit function declaration an error in $CC... " >&6; } +if test ${ac_cv_enable_implicit_function_declaration_error+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + ac_cv_enable_implicit_function_declaration_error=yes + +else case e in #( + e) + ac_cv_enable_implicit_function_declaration_error=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_implicit_function_declaration_error" >&5 +printf "%s\n" "$ac_cv_enable_implicit_function_declaration_error" >&6; } + CC="$ac_save_cc" + + if test "x$ac_cv_enable_implicit_function_declaration_error" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Werror=implicit-function-declaration" +fi + + ac_save_cc="$CC" + CC="$CC -fvisibility=hidden" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can use visibility in $CC" >&5 +printf %s "checking if we can use visibility in $CC... " >&6; } +if test ${ac_cv_enable_visibility+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + ac_cv_enable_visibility=yes + +else case e in #( + e) + ac_cv_enable_visibility=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_visibility" >&5 +printf "%s\n" "$ac_cv_enable_visibility" >&6; } + CC="$ac_save_cc" + + if test "x$ac_cv_enable_visibility" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -fvisibility=hidden" +fi + + # if using gcc on alpha, use -mieee to get (near) full IEEE 754 + # support. Without this, treatment of subnormals doesn't follow + # the standard. + case $host in + alpha*) + BASECFLAGS="$BASECFLAGS -mieee" + ;; + esac + + case $ac_sys_system in + SCO_SV*) + BASECFLAGS="$BASECFLAGS -m486 -DSCO5" + ;; + + Darwin*) + # -Wno-long-double, -no-cpp-precomp, and -mno-fused-madd + # used to be here, but non-Apple gcc doesn't accept them. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which compiler should be used" >&5 +printf %s "checking which compiler should be used... " >&6; } + case "${UNIVERSALSDK}" in + */MacOSX10.4u.sdk) + # Build using 10.4 SDK, force usage of gcc when the + # compiler is gcc, otherwise the user will get very + # confusing error messages when building on OSX 10.6 + CC=gcc-4.0 + CPP=cpp-4.0 + ;; + esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } + + # Error on unguarded use of new symbols, which will fail at runtime for + # users on older versions of macOS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunguarded-availability" >&5 +printf %s "checking whether C compiler accepts -Wunguarded-availability... " >&6; } +if test ${ax_cv_check_cflags__Werror__Wunguarded_availability+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -Wunguarded-availability" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__Wunguarded_availability=yes +else case e in #( + e) ax_cv_check_cflags__Werror__Wunguarded_availability=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__Wunguarded_availability" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__Wunguarded_availability" >&6; } +if test "x$ax_cv_check_cflags__Werror__Wunguarded_availability" = xyes +then : + as_fn_append CFLAGS_NODIST " -Werror=unguarded-availability" +else case e in #( + e) : ;; +esac +fi + + + LIPO_INTEL64_FLAGS="" + if test "${enable_universalsdk}" + then + case "$UNIVERSAL_ARCHS" in + 32-bit) + UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="" + ARCH_TRIPLES=`echo {ppc,i386}-apple-darwin` + ;; + 64-bit) + UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="true" + ARCH_TRIPLES=`echo {ppc64,x86_64}-apple-darwin` + ;; + all) + UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc" + ARCH_TRIPLES=`echo {i386,ppc,ppc64,x86_64}-apple-darwin` + ;; + universal2) + UNIVERSAL_ARCH_FLAGS="-arch arm64 -arch x86_64" + LIPO_32BIT_FLAGS="" + LIPO_INTEL64_FLAGS="-extract x86_64" + ARCH_RUN_32BIT="true" + ARCH_TRIPLES=`echo {aarch64,x86_64}-apple-darwin` + ;; + intel) + UNIVERSAL_ARCH_FLAGS="-arch i386 -arch x86_64" + LIPO_32BIT_FLAGS="-extract i386" + ARCH_RUN_32BIT="/usr/bin/arch -i386" + ARCH_TRIPLES=`echo {i386,x86_64}-apple-darwin` + ;; + intel-32) + UNIVERSAL_ARCH_FLAGS="-arch i386" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="" + ARCH_TRIPLES=i386-apple-darwin + ;; + intel-64) + UNIVERSAL_ARCH_FLAGS="-arch x86_64" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="true" + ARCH_TRIPLES=x86_64-apple-darwin + ;; + 3-way) + UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc" + ARCH_TRIPLES=`echo {i386,ppc,x86_64}-apple-darwin` + ;; + *) + as_fn_error $? "proper usage is --with-universal-arch=universal2|32-bit|64-bit|all|intel|3-way" "$LINENO" 5 + ;; + esac + + if test "${UNIVERSALSDK}" != "/" + then + CFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${CFLAGS}" + LDFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${LDFLAGS}" + CPPFLAGS="-isysroot ${UNIVERSALSDK} ${CPPFLAGS}" + else + CFLAGS="${UNIVERSAL_ARCH_FLAGS} ${CFLAGS}" + LDFLAGS="${UNIVERSAL_ARCH_FLAGS} ${LDFLAGS}" + fi + fi + + # Calculate an appropriate deployment target for this build: + # The deployment target value is used explicitly to enable certain + # features are enabled (such as builtin libedit support for readline) + # through the use of Apple's Availability Macros and is used as a + # component of the string returned by distutils.get_platform(). + # + # Use the value from: + # 1. the MACOSX_DEPLOYMENT_TARGET environment variable if specified + # 2. the operating system version of the build machine if >= 10.6 + # 3. If running on OS X 10.3 through 10.5, use the legacy tests + # below to pick either 10.3, 10.4, or 10.5 as the target. + # 4. If we are running on OS X 10.2 or earlier, good luck! + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which MACOSX_DEPLOYMENT_TARGET to use" >&5 +printf %s "checking which MACOSX_DEPLOYMENT_TARGET to use... " >&6; } + cur_target_major=`sw_vers -productVersion | \ + sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'` + cur_target_minor=`sw_vers -productVersion | \ + sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'` + cur_target="${cur_target_major}.${cur_target_minor}" + if test ${cur_target_major} -eq 10 && \ + test ${cur_target_minor} -ge 3 && \ + test ${cur_target_minor} -le 5 + then + # OS X 10.3 through 10.5 + cur_target=10.3 + if test ${enable_universalsdk} + then + case "$UNIVERSAL_ARCHS" in + all|3-way|intel|64-bit) + # These configurations were first supported in 10.5 + cur_target='10.5' + ;; + esac + else + if test `/usr/bin/arch` = "i386" + then + # 10.4 was the first release to support Intel archs + cur_target="10.4" + fi + fi + fi + CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}} + + # Make sure that MACOSX_DEPLOYMENT_TARGET is set in the + # environment with a value that is the same as what we'll use + # in the Makefile to ensure that we'll get the same compiler + # environment during configure and build time. + MACOSX_DEPLOYMENT_TARGET="$CONFIGURE_MACOSX_DEPLOYMENT_TARGET" + export MACOSX_DEPLOYMENT_TARGET + EXPORT_MACOSX_DEPLOYMENT_TARGET='' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MACOSX_DEPLOYMENT_TARGET" >&5 +printf "%s\n" "$MACOSX_DEPLOYMENT_TARGET" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if specified universal architectures work" >&5 +printf %s "checking if specified universal architectures work... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main (void) +{ +printf("%d", 42); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + as_fn_error $? "check config.log and use the '--with-universal-archs' option" "$LINENO" 5 + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + # end of Darwin* tests + ;; + esac + +else case e in #( + e) + case $ac_sys_system in + OpenUNIX*|UnixWare*) + BASECFLAGS="$BASECFLAGS -K pentium,host,inline,loop_unroll,alloca " + ;; + SCO_SV*) + BASECFLAGS="$BASECFLAGS -belf -Ki486 -DSCO5" + ;; + esac + ;; +esac +fi + +# Check for --enable-experimental-jit: +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-experimental-jit" >&5 +printf %s "checking for --enable-experimental-jit... " >&6; } +# Check whether --enable-experimental-jit was given. +if test ${enable_experimental_jit+y} +then : + enableval=$enable_experimental_jit; +else case e in #( + e) enable_experimental_jit=no ;; +esac +fi + +case $enable_experimental_jit in + no) jit_flags=""; tier2_flags="" ;; + yes) jit_flags="-D_Py_JIT"; tier2_flags="-D_Py_TIER2=1" ;; + yes-off) jit_flags="-D_Py_JIT"; tier2_flags="-D_Py_TIER2=3" ;; + interpreter) jit_flags=""; tier2_flags="-D_Py_TIER2=4" ;; + interpreter-off) jit_flags=""; tier2_flags="-D_Py_TIER2=6" ;; # Secret option + *) as_fn_error $? "invalid argument: --enable-experimental-jit=$enable_experimental_jit; expected no|yes|yes-off|interpreter" "$LINENO" 5 ;; +esac +if ${tier2_flags:+false} : +then : + +else case e in #( + e) as_fn_append CFLAGS_NODIST " $tier2_flags" ;; +esac +fi +if ${jit_flags:+false} : +then : + +else case e in #( + e) as_fn_append CFLAGS_NODIST " $jit_flags" + REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\" --llvm-version=\"$LLVM_VERSION\" --llvm-tools-install-dir=\"$LLVM_TOOLS_INSTALL_DIR\"" + if test "x$Py_DEBUG" = xtrue +then : + as_fn_append REGEN_JIT_COMMAND " --debug" +fi ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tier2_flags $jit_flags" >&5 +printf "%s\n" "$tier2_flags $jit_flags" >&6; } + +if test "$disable_gil" = "yes" -a "$enable_experimental_jit" != "no"; then + # GH-133171: This configuration builds the JIT but never actually uses it, + # which is surprising (and strictly worse than not building it at all): + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-experimental-jit does not work correctly with --disable-gil." >&5 +printf "%s\n" "$as_me: WARNING: --enable-experimental-jit does not work correctly with --disable-gil." >&2;} +fi + +case "$ac_cv_cc_name" in +mpicc) + CFLAGS_NODIST="$CFLAGS_NODIST" + ;; +icx) + # ICX needs fp-model=precise (the default in clang) or floats behave badly + CFLAGS_NODIST="$CFLAGS_NODIST -ffp-model=precise" + ;; +icc) + # ICC needs -fp-model strict or floats behave badly + CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" + ;; +xlc) + CFLAGS_NODIST="$CFLAGS_NODIST -qalias=noansi -qmaxmem=-1" + ;; +esac + +if test "$assertions" = 'true'; then + : +else + OPT="-DNDEBUG $OPT" +fi + +if test "$ac_arch_flags" +then + BASECFLAGS="$BASECFLAGS $ac_arch_flags" +fi + +# On some compilers, pthreads are available without further options +# (e.g. MacOS X). On some of these systems, the compiler will not +# complain if unaccepted options are passed (e.g. gcc on Mac OS X). +# So we have to see first whether pthreads are available without +# options before we can check whether -Kpthread improves anything. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads are available without options" >&5 +printf %s "checking whether pthreads are available without options... " >&6; } +if test ${ac_cv_pthread_is_default+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_pthread_is_default=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + + ac_cv_pthread_is_default=yes + ac_cv_kthread=no + ac_cv_pthread=no + +else case e in #( + e) ac_cv_pthread_is_default=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_is_default" >&5 +printf "%s\n" "$ac_cv_pthread_is_default" >&6; } + + +if test $ac_cv_pthread_is_default = yes +then + ac_cv_kpthread=no +else +# -Kpthread, if available, provides the right #defines +# and linker options to make pthread_create available +# Some compilers won't report that they do not support -Kpthread, +# so we need to run a program to see whether it really made the +# function available. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Kpthread" >&5 +printf %s "checking whether $CC accepts -Kpthread... " >&6; } +if test ${ac_cv_kpthread+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_cc="$CC" +CC="$CC -Kpthread" +if test "$cross_compiling" = yes +then : + ac_cv_kpthread=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_kpthread=yes +else case e in #( + e) ac_cv_kpthread=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CC="$ac_save_cc" ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kpthread" >&5 +printf "%s\n" "$ac_cv_kpthread" >&6; } +fi + +if test $ac_cv_kpthread = no -a $ac_cv_pthread_is_default = no +then +# -Kthread, if available, provides the right #defines +# and linker options to make pthread_create available +# Some compilers won't report that they do not support -Kthread, +# so we need to run a program to see whether it really made the +# function available. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Kthread" >&5 +printf %s "checking whether $CC accepts -Kthread... " >&6; } +if test ${ac_cv_kthread+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_cc="$CC" +CC="$CC -Kthread" +if test "$cross_compiling" = yes +then : + ac_cv_kthread=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_kthread=yes +else case e in #( + e) ac_cv_kthread=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CC="$ac_save_cc" ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kthread" >&5 +printf "%s\n" "$ac_cv_kthread" >&6; } +fi + +if test $ac_cv_kthread = no -a $ac_cv_pthread_is_default = no +then +# -pthread, if available, provides the right #defines +# and linker options to make pthread_create available +# Some compilers won't report that they do not support -pthread, +# so we need to run a program to see whether it really made the +# function available. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -pthread" >&5 +printf %s "checking whether $CC accepts -pthread... " >&6; } +if test ${ac_cv_pthread+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_cc="$CC" +CC="$CC -pthread" +if test "$cross_compiling" = yes +then : + ac_cv_pthread=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_pthread=yes +else case e in #( + e) ac_cv_pthread=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CC="$ac_save_cc" ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread" >&5 +printf "%s\n" "$ac_cv_pthread" >&6; } +fi + +# If we have set a CC compiler flag for thread support then +# check if it works for CXX, too. +if test ! -z "$CXX" +then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX also accepts flags for thread support" >&5 +printf %s "checking whether $CXX also accepts flags for thread support... " >&6; } +if test ${ac_cv_cxx_thread+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_cxx="$CXX" + +if test "$ac_cv_kpthread" = "yes" +then + CXX="$CXX -Kpthread" + ac_cv_cxx_thread=yes +elif test "$ac_cv_kthread" = "yes" +then + CXX="$CXX -Kthread" + ac_cv_cxx_thread=yes +elif test "$ac_cv_pthread" = "yes" +then + CXX="$CXX -pthread" + ac_cv_cxx_thread=yes +else + ac_cv_cxx_thread=no +fi + +if test $ac_cv_cxx_thread = yes +then + echo 'void foo();int main(){foo();}void foo(){}' > conftest.$ac_ext + $CXX -c conftest.$ac_ext 2>&5 + if $CXX -o conftest$ac_exeext conftest.$ac_objext 2>&5 \ + && test -s conftest$ac_exeext && ./conftest$ac_exeext + then + ac_cv_cxx_thread=yes + else + ac_cv_cxx_thread=no + fi + rm -fr conftest* +fi +CXX="$ac_save_cxx" ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_thread" >&5 +printf "%s\n" "$ac_cv_cxx_thread" >&6; } +else + ac_cv_cxx_thread=no +fi + + + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h + + +# checks for header files +ac_fn_c_check_header_compile "$LINENO" "alloca.h" "ac_cv_header_alloca_h" "$ac_includes_default" +if test "x$ac_cv_header_alloca_h" = xyes +then : + printf "%s\n" "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "asm/types.h" "ac_cv_header_asm_types_h" "$ac_includes_default" +if test "x$ac_cv_header_asm_types_h" = xyes +then : + printf "%s\n" "#define HAVE_ASM_TYPES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "bluetooth.h" "ac_cv_header_bluetooth_h" "$ac_includes_default" +if test "x$ac_cv_header_bluetooth_h" = xyes +then : + printf "%s\n" "#define HAVE_BLUETOOTH_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "conio.h" "ac_cv_header_conio_h" "$ac_includes_default" +if test "x$ac_cv_header_conio_h" = xyes +then : + printf "%s\n" "#define HAVE_CONIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "direct.h" "ac_cv_header_direct_h" "$ac_includes_default" +if test "x$ac_cv_header_direct_h" = xyes +then : + printf "%s\n" "#define HAVE_DIRECT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default" +if test "x$ac_cv_header_endian_h" = xyes +then : + printf "%s\n" "#define HAVE_ENDIAN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default" +if test "x$ac_cv_header_errno_h" = xyes +then : + printf "%s\n" "#define HAVE_ERRNO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" +if test "x$ac_cv_header_fcntl_h" = xyes +then : + printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default" +if test "x$ac_cv_header_grp_h" = xyes +then : + printf "%s\n" "#define HAVE_GRP_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default" +if test "x$ac_cv_header_io_h" = xyes +then : + printf "%s\n" "#define HAVE_IO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default" +if test "x$ac_cv_header_langinfo_h" = xyes +then : + printf "%s\n" "#define HAVE_LANGINFO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" +if test "x$ac_cv_header_libintl_h" = xyes +then : + printf "%s\n" "#define HAVE_LIBINTL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "libutil.h" "ac_cv_header_libutil_h" "$ac_includes_default" +if test "x$ac_cv_header_libutil_h" = xyes +then : + printf "%s\n" "#define HAVE_LIBUTIL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/auxvec.h" "ac_cv_header_linux_auxvec_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_auxvec_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_AUXVEC_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/auxv.h" "ac_cv_header_sys_auxv_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_auxv_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_AUXV_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/fs.h" "ac_cv_header_linux_fs_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_fs_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_FS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/limits.h" "ac_cv_header_linux_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_limits_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_LIMITS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/memfd.h" "ac_cv_header_linux_memfd_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_memfd_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_MEMFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/netfilter_ipv4.h" "ac_cv_header_linux_netfilter_ipv4_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_netfilter_ipv4_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_NETFILTER_IPV4_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/random.h" "ac_cv_header_linux_random_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_random_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_RANDOM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/soundcard.h" "ac_cv_header_linux_soundcard_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_soundcard_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_SOUNDCARD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/sched.h" "ac_cv_header_linux_sched_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_sched_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_SCHED_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/tipc.h" "ac_cv_header_linux_tipc_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_tipc_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_TIPC_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/wait.h" "ac_cv_header_linux_wait_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_wait_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_WAIT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default" +if test "x$ac_cv_header_netdb_h" = xyes +then : + printf "%s\n" "#define HAVE_NETDB_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "net/ethernet.h" "ac_cv_header_net_ethernet_h" "$ac_includes_default" +if test "x$ac_cv_header_net_ethernet_h" = xyes +then : + printf "%s\n" "#define HAVE_NET_ETHERNET_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default" +if test "x$ac_cv_header_netinet_in_h" = xyes +then : + printf "%s\n" "#define HAVE_NETINET_IN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netpacket/packet.h" "ac_cv_header_netpacket_packet_h" "$ac_includes_default" +if test "x$ac_cv_header_netpacket_packet_h" = xyes +then : + printf "%s\n" "#define HAVE_NETPACKET_PACKET_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default" +if test "x$ac_cv_header_poll_h" = xyes +then : + printf "%s\n" "#define HAVE_POLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "process.h" "ac_cv_header_process_h" "$ac_includes_default" +if test "x$ac_cv_header_process_h" = xyes +then : + printf "%s\n" "#define HAVE_PROCESS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_h" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "pty.h" "ac_cv_header_pty_h" "$ac_includes_default" +if test "x$ac_cv_header_pty_h" = xyes +then : + printf "%s\n" "#define HAVE_PTY_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sched.h" "ac_cv_header_sched_h" "$ac_includes_default" +if test "x$ac_cv_header_sched_h" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "setjmp.h" "ac_cv_header_setjmp_h" "$ac_includes_default" +if test "x$ac_cv_header_setjmp_h" = xyes +then : + printf "%s\n" "#define HAVE_SETJMP_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default" +if test "x$ac_cv_header_shadow_h" = xyes +then : + printf "%s\n" "#define HAVE_SHADOW_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default" +if test "x$ac_cv_header_signal_h" = xyes +then : + printf "%s\n" "#define HAVE_SIGNAL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "spawn.h" "ac_cv_header_spawn_h" "$ac_includes_default" +if test "x$ac_cv_header_spawn_h" = xyes +then : + printf "%s\n" "#define HAVE_SPAWN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/audioio.h" "ac_cv_header_sys_audioio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_audioio_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_AUDIOIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/bsdtty.h" "ac_cv_header_sys_bsdtty_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_bsdtty_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_BSDTTY_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/devpoll.h" "ac_cv_header_sys_devpoll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_devpoll_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_DEVPOLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/endian.h" "ac_cv_header_sys_endian_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_endian_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_ENDIAN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/epoll.h" "ac_cv_header_sys_epoll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_epoll_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_EPOLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/event.h" "ac_cv_header_sys_event_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_event_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_EVENT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/eventfd.h" "ac_cv_header_sys_eventfd_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_eventfd_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_EVENTFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/file.h" "ac_cv_header_sys_file_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_file_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_FILE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_ioctl_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/kern_control.h" "ac_cv_header_sys_kern_control_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_kern_control_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_KERN_CONTROL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/loadavg.h" "ac_cv_header_sys_loadavg_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_loadavg_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_LOADAVG_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/lock.h" "ac_cv_header_sys_lock_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_lock_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_LOCK_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/memfd.h" "ac_cv_header_sys_memfd_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_memfd_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MEMFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mkdev_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MKDEV_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mman_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MMAN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/modem.h" "ac_cv_header_sys_modem_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_modem_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MODEM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_param_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_PARAM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/pidfd.h" "ac_cv_header_sys_pidfd_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_pidfd_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_PIDFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/poll.h" "ac_cv_header_sys_poll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_poll_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_POLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/random.h" "ac_cv_header_sys_random_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_random_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_RANDOM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_resource_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_RESOURCE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_select_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SELECT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/sendfile.h" "ac_cv_header_sys_sendfile_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sendfile_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SENDFILE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_socket_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/soundcard.h" "ac_cv_header_sys_soundcard_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_soundcard_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SOUNDCARD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_stat_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_STAT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_statvfs_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_STATVFS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/sys_domain.h" "ac_cv_header_sys_sys_domain_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sys_domain_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SYS_DOMAIN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/syscall.h" "ac_cv_header_sys_syscall_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_syscall_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SYSCALL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sysctl_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SYSCTL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sysmacros_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SYSMACROS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/termio.h" "ac_cv_header_sys_termio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_termio_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TERMIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_time_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/times.h" "ac_cv_header_sys_times_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_times_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TIMES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/timerfd.h" "ac_cv_header_sys_timerfd_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_timerfd_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TIMERFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_types_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TYPES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_uio_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_UIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_un_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_UN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/utsname.h" "ac_cv_header_sys_utsname_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_utsname_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_UTSNAME_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_wait_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/xattr.h" "ac_cv_header_sys_xattr_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_xattr_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_XATTR_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sysexits.h" "ac_cv_header_sysexits_h" "$ac_includes_default" +if test "x$ac_cv_header_sysexits_h" = xyes +then : + printf "%s\n" "#define HAVE_SYSEXITS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default" +if test "x$ac_cv_header_syslog_h" = xyes +then : + printf "%s\n" "#define HAVE_SYSLOG_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default" +if test "x$ac_cv_header_termios_h" = xyes +then : + printf "%s\n" "#define HAVE_TERMIOS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "util.h" "ac_cv_header_util_h" "$ac_includes_default" +if test "x$ac_cv_header_util_h" = xyes +then : + printf "%s\n" "#define HAVE_UTIL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default" +if test "x$ac_cv_header_utime_h" = xyes +then : + printf "%s\n" "#define HAVE_UTIME_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "utmp.h" "ac_cv_header_utmp_h" "$ac_includes_default" +if test "x$ac_cv_header_utmp_h" = xyes +then : + printf "%s\n" "#define HAVE_UTMP_H 1" >>confdefs.h + +fi + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`printf "%s\n" "ac_cv_header_dirent_$ac_hdr" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +printf %s "checking for $ac_hdr that defines DIR... " >&6; } +if eval test \${$as_ac_Header+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <$ac_hdr> + +int +main (void) +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$as_ac_Header=yes" +else case e in #( + e) eval "$as_ac_Header=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +eval ac_res=\$$as_ac_Header + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_hdr" | sed "$as_sed_cpp"` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +printf %s "checking for library containing opendir... " >&6; } +if test ${ac_cv_search_opendir+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (void); +int +main (void) +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_opendir+y} +then : + break +fi +done +if test ${ac_cv_search_opendir+y} +then : + +else case e in #( + e) ac_cv_search_opendir=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +printf "%s\n" "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +printf %s "checking for library containing opendir... " >&6; } +if test ${ac_cv_search_opendir+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (void); +int +main (void) +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_opendir+y} +then : + break +fi +done +if test ${ac_cv_search_opendir+y} +then : + +else case e in #( + e) ac_cv_search_opendir=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +printf "%s\n" "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + + +ac_fn_c_check_header_compile "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mkdev_h" = xyes +then : + +printf "%s\n" "#define MAJOR_IN_MKDEV 1" >>confdefs.h + +fi + +if test $ac_cv_header_sys_mkdev_h = no; then + ac_fn_c_check_header_compile "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sysmacros_h" = xyes +then : + +printf "%s\n" "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h + +fi + +fi + + +# On Linux, stropts.h may be empty +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 +printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } +if test ${ac_cv_c_undeclared_builtin_options+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_CFLAGS=$CFLAGS + ac_cv_c_undeclared_builtin_options='cannot detect' + for ac_arg in '' -fno-builtin; do + CFLAGS="$ac_save_CFLAGS $ac_arg" + # This test program should *not* compile successfully. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +(void) strchr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else case e in #( + e) # This test program should compile successfully. + # No library function is consistently available on + # freestanding implementations, so test against a dummy + # declaration. Include always-available headers on the + # off chance that they somehow elicit warnings. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <float.h> +#include <limits.h> +#include <stdarg.h> +#include <stddef.h> +extern void ac_decl (int, char *); + +int +main (void) +{ +(void) ac_decl (0, (char *) 0); + (void) ac_decl; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + if test x"$ac_arg" = x +then : + ac_cv_c_undeclared_builtin_options='none needed' +else case e in #( + e) ac_cv_c_undeclared_builtin_options=$ac_arg ;; +esac +fi + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + CFLAGS=$ac_save_CFLAGS + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 +printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } + case $ac_cv_c_undeclared_builtin_options in #( + 'cannot detect') : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "cannot make $CC report undeclared builtins +See 'config.log' for more details" "$LINENO" 5; } ;; #( + 'none needed') : + ac_c_undeclared_builtin_options='' ;; #( + *) : + ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; +esac + +ac_fn_check_decl "$LINENO" "I_PUSH" "ac_cv_have_decl_I_PUSH" " + #ifdef HAVE_SYS_TYPES_H + # include <sys/types.h> + #endif + #include <stropts.h> + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_I_PUSH" = xyes +then : + + +printf "%s\n" "#define HAVE_STROPTS_H 1" >>confdefs.h + +fi + +# bluetooth/bluetooth.h has been known to not compile with -std=c99. +# http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 +SAVE_CFLAGS=$CFLAGS +CFLAGS="-std=c99 $CFLAGS" +ac_fn_c_check_header_compile "$LINENO" "bluetooth/bluetooth.h" "ac_cv_header_bluetooth_bluetooth_h" "$ac_includes_default" +if test "x$ac_cv_header_bluetooth_bluetooth_h" = xyes +then : + printf "%s\n" "#define HAVE_BLUETOOTH_BLUETOOTH_H 1" >>confdefs.h + +fi + +CFLAGS=$SAVE_CFLAGS + +# On Darwin (OS X) net/if.h requires sys/socket.h to be imported first. +ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_net_if_h" = xyes +then : + printf "%s\n" "#define HAVE_NET_IF_H 1" >>confdefs.h + +fi + + +# On Linux, netlink.h requires asm/types.h +# On FreeBSD, netlink.h is located in netlink/netlink.h +ac_fn_c_check_header_compile "$LINENO" "linux/netlink.h" "ac_cv_header_linux_netlink_h" " +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_netlink_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_NETLINK_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netlink/netlink.h" "ac_cv_header_netlink_netlink_h" " +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_netlink_netlink_h" = xyes +then : + printf "%s\n" "#define HAVE_NETLINK_NETLINK_H 1" >>confdefs.h + +fi + + +# On Linux, qrtr.h requires asm/types.h +ac_fn_c_check_header_compile "$LINENO" "linux/qrtr.h" "ac_cv_header_linux_qrtr_h" " +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_qrtr_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_QRTR_H 1" >>confdefs.h + +fi + + +ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" " +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_vm_sockets_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_VM_SOCKETS_H 1" >>confdefs.h + +fi + + +# On Linux, can.h, can/bcm.h, can/isotp.h, can/j1939.h, can/raw.h require sys/socket.h +# On NetBSD, netcan/can.h requires sys/socket.h +ac_fn_c_check_header_compile "$LINENO" "linux/can.h" "ac_cv_header_linux_can_h" " +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_can_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/can/bcm.h" "ac_cv_header_linux_can_bcm_h" " +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_can_bcm_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_BCM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/can/isotp.h" "ac_cv_header_linux_can_isotp_h" " +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_can_isotp_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_ISOTP_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/can/j1939.h" "ac_cv_header_linux_can_j1939_h" " +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_can_j1939_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_J1939_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/can/raw.h" "ac_cv_header_linux_can_raw_h" " +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_linux_can_raw_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_RAW_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netcan/can.h" "ac_cv_header_netcan_can_h" " +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_header_netcan_can_h" = xyes +then : + printf "%s\n" "#define HAVE_NETCAN_CAN_H 1" >>confdefs.h + +fi + + +# Check for clock_t in time.h. +ac_fn_c_check_type "$LINENO" "clock_t" "ac_cv_type_clock_t" "#include <time.h> +" +if test "x$ac_cv_type_clock_t" = xyes +then : + +printf "%s\n" "#define HAVE_CLOCK_T 1" >>confdefs.h + + +else case e in #( + e) +printf "%s\n" "#define clock_t long" >>confdefs.h + ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for makedev" >&5 +printf %s "checking for makedev... " >&6; } +if test ${ac_cv_func_makedev+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if defined(MAJOR_IN_MKDEV) +#include <sys/mkdev.h> +#elif defined(MAJOR_IN_SYSMACROS) +#include <sys/sysmacros.h> +#else +#include <sys/types.h> +#endif + +int +main (void) +{ + + makedev(0, 0) + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_func_makedev=yes +else case e in #( + e) ac_cv_func_makedev=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_makedev" >&5 +printf "%s\n" "$ac_cv_func_makedev" >&6; } + +if test "x$ac_cv_func_makedev" = xyes +then : + + +printf "%s\n" "#define HAVE_MAKEDEV 1" >>confdefs.h + + +fi + +# byte swapping +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for le64toh" >&5 +printf %s "checking for le64toh... " >&6; } +if test ${ac_cv_func_le64toh+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#elif defined(HAVE_SYS_ENDIAN_H) +#include <sys/endian.h> +#endif + +int +main (void) +{ + + le64toh(1) + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_func_le64toh=yes +else case e in #( + e) ac_cv_func_le64toh=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_le64toh" >&5 +printf "%s\n" "$ac_cv_func_le64toh" >&6; } + +if test "x$ac_cv_func_le64toh" = xyes +then : + + +printf "%s\n" "#define HAVE_HTOLE64 1" >>confdefs.h + + +fi + +use_lfs=yes +# Don't use largefile support for GNU/Hurd +case $ac_sys_system in GNU*) + use_lfs=no +esac + +if test "$use_lfs" = "yes"; then +# Two defines needed to enable largefile support on various platforms +# These may affect some typedefs +case $ac_sys_system/$ac_sys_release in +AIX*) + +printf "%s\n" "#define _LARGE_FILES 1" >>confdefs.h + + ;; +esac + +printf "%s\n" "#define _LARGEFILE_SOURCE 1" >>confdefs.h + + +printf "%s\n" "#define _FILE_OFFSET_BITS 64" >>confdefs.h + +fi + +# Add some code to confdefs.h so that the test for off_t works on SCO +cat >> confdefs.h <<\EOF +#if defined(SCO_DS) +#undef _OFF_T +#endif +EOF + +# Type availability checks +ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" +if test "x$ac_cv_type_mode_t" = xyes +then : + +else case e in #( + e) +printf "%s\n" "#define mode_t int" >>confdefs.h + ;; +esac +fi + +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = xyes +then : + +else case e in #( + e) +printf "%s\n" "#define off_t long int" >>confdefs.h + ;; +esac +fi + + + ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default +" +if test "x$ac_cv_type_pid_t" = xyes +then : + +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #if defined _WIN64 && !defined __CYGWIN__ + LLP64 + #endif + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_pid_type='int' +else case e in #( + e) ac_pid_type='__int64' ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +printf "%s\n" "#define pid_t $ac_pid_type" >>confdefs.h + + ;; +esac +fi + + + +printf "%s\n" "#define RETSIGTYPE void" >>confdefs.h + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes +then : + +else case e in #( + e) +printf "%s\n" "#define size_t unsigned int" >>confdefs.h + ;; +esac +fi + +ac_fn_c_check_type "$LINENO" "uid_t" "ac_cv_type_uid_t" "$ac_includes_default" +if test "x$ac_cv_type_uid_t" = xyes +then : + +else case e in #( + e) +printf "%s\n" "#define uid_t int" >>confdefs.h + ;; +esac +fi + +ac_fn_c_check_type "$LINENO" "gid_t" "ac_cv_type_gid_t" "$ac_includes_default" +if test "x$ac_cv_type_gid_t" = xyes +then : + +else case e in #( + e) +printf "%s\n" "#define gid_t int" >>confdefs.h + ;; +esac +fi + + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" +if test "x$ac_cv_type_ssize_t" = xyes +then : + +printf "%s\n" "#define HAVE_SSIZE_T 1" >>confdefs.h + + +fi + +ac_fn_c_check_type "$LINENO" "__uint128_t" "ac_cv_type___uint128_t" "$ac_includes_default" +if test "x$ac_cv_type___uint128_t" = xyes +then : + +printf "%s\n" "#define HAVE___UINT128_T 1" >>confdefs.h + + +printf "%s\n" "#define HAVE_GCC_UINT128_T 1" >>confdefs.h + +fi + + +# Sizes and alignments of various common basic types +# ANSI C requires sizeof(char) == 1, so no need to check it +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +printf %s "checking size of int... " >&6; } +if test ${ac_cv_sizeof_int+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_int" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +printf "%s\n" "$ac_cv_sizeof_int" >&6; } + + + +printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +printf %s "checking size of long... " >&6; } +if test ${ac_cv_sizeof_long+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_long" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +printf "%s\n" "$ac_cv_sizeof_long" >&6; } + + + +printf "%s\n" "#define SIZEOF_LONG $ac_cv_sizeof_long" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking alignment of long" >&5 +printf %s "checking alignment of long... " >&6; } +if test ${ac_cv_alignof_long+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_long" "$ac_includes_default +typedef struct { char x; long y; } ac__type_alignof_;" +then : + +else case e in #( + e) if test "$ac_cv_type_long" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of long +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_long=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long" >&5 +printf "%s\n" "$ac_cv_alignof_long" >&6; } + + + +printf "%s\n" "#define ALIGNOF_LONG $ac_cv_alignof_long" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +printf %s "checking size of long long... " >&6; } +if test ${ac_cv_sizeof_long_long+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_long_long" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long long) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long_long=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +printf "%s\n" "$ac_cv_sizeof_long_long" >&6; } + + + +printf "%s\n" "#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +printf %s "checking size of void *... " >&6; } +if test ${ac_cv_sizeof_void_p+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_void_p" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void *) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_void_p=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +printf "%s\n" "$ac_cv_sizeof_void_p" >&6; } + + + +printf "%s\n" "#define SIZEOF_VOID_P $ac_cv_sizeof_void_p" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +printf %s "checking size of short... " >&6; } +if test ${ac_cv_sizeof_short+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_short" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +printf "%s\n" "$ac_cv_sizeof_short" >&6; } + + + +printf "%s\n" "#define SIZEOF_SHORT $ac_cv_sizeof_short" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of float" >&5 +printf %s "checking size of float... " >&6; } +if test ${ac_cv_sizeof_float+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (float))" "ac_cv_sizeof_float" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_float" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (float) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_float=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_float" >&5 +printf "%s\n" "$ac_cv_sizeof_float" >&6; } + + + +printf "%s\n" "#define SIZEOF_FLOAT $ac_cv_sizeof_float" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of double" >&5 +printf %s "checking size of double... " >&6; } +if test ${ac_cv_sizeof_double+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_double" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (double) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_double=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5 +printf "%s\n" "$ac_cv_sizeof_double" >&6; } + + + +printf "%s\n" "#define SIZEOF_DOUBLE $ac_cv_sizeof_double" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of fpos_t" >&5 +printf %s "checking size of fpos_t... " >&6; } +if test ${ac_cv_sizeof_fpos_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (fpos_t))" "ac_cv_sizeof_fpos_t" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_fpos_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (fpos_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_fpos_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_fpos_t" >&5 +printf "%s\n" "$ac_cv_sizeof_fpos_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_FPOS_T $ac_cv_sizeof_fpos_t" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 +printf %s "checking size of size_t... " >&6; } +if test ${ac_cv_sizeof_size_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_size_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (size_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_size_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 +printf "%s\n" "$ac_cv_sizeof_size_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking alignment of size_t" >&5 +printf %s "checking alignment of size_t... " >&6; } +if test ${ac_cv_alignof_size_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_size_t" "$ac_includes_default +typedef struct { char x; size_t y; } ac__type_alignof_;" +then : + +else case e in #( + e) if test "$ac_cv_type_size_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of size_t +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_size_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_size_t" >&5 +printf "%s\n" "$ac_cv_alignof_size_t" >&6; } + + + +printf "%s\n" "#define ALIGNOF_SIZE_T $ac_cv_alignof_size_t" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of pid_t" >&5 +printf %s "checking size of pid_t... " >&6; } +if test ${ac_cv_sizeof_pid_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pid_t))" "ac_cv_sizeof_pid_t" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_pid_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (pid_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_pid_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pid_t" >&5 +printf "%s\n" "$ac_cv_sizeof_pid_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_PID_T $ac_cv_sizeof_pid_t" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of uintptr_t" >&5 +printf %s "checking size of uintptr_t... " >&6; } +if test ${ac_cv_sizeof_uintptr_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uintptr_t))" "ac_cv_sizeof_uintptr_t" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_uintptr_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (uintptr_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_uintptr_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uintptr_t" >&5 +printf "%s\n" "$ac_cv_sizeof_uintptr_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_UINTPTR_T $ac_cv_sizeof_uintptr_t" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking alignment of max_align_t" >&5 +printf %s "checking alignment of max_align_t... " >&6; } +if test ${ac_cv_alignof_max_align_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_max_align_t" "$ac_includes_default +typedef struct { char x; max_align_t y; } ac__type_alignof_;" +then : + +else case e in #( + e) if test "$ac_cv_type_max_align_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of max_align_t +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_max_align_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_max_align_t" >&5 +printf "%s\n" "$ac_cv_alignof_max_align_t" >&6; } + + + +printf "%s\n" "#define ALIGNOF_MAX_ALIGN_T $ac_cv_alignof_max_align_t" >>confdefs.h + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 +printf %s "checking for long double... " >&6; } +if test ${ac_cv_type_long_double+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$GCC" = yes; then + ac_cv_type_long_double=yes + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* The Stardent Vistra knows sizeof (long double), but does + not support it. */ + long double foo = 0.0L; +int +main (void) +{ +static int test_array [1 - 2 * !(/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + sizeof (double) <= sizeof (long double))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_type_long_double=yes +else case e in #( + e) ac_cv_type_long_double=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double" >&5 +printf "%s\n" "$ac_cv_type_long_double" >&6; } + if test $ac_cv_type_long_double = yes; then + +printf "%s\n" "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + + fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5 +printf %s "checking size of long double... " >&6; } +if test ${ac_cv_sizeof_long_double+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type_long_double" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long double) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long_double=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5 +printf "%s\n" "$ac_cv_sizeof_long_double" >&6; } + + + +printf "%s\n" "#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double" >>confdefs.h + + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of _Bool" >&5 +printf %s "checking size of _Bool... " >&6; } +if test ${ac_cv_sizeof__Bool+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (_Bool))" "ac_cv_sizeof__Bool" "$ac_includes_default" +then : + +else case e in #( + e) if test "$ac_cv_type__Bool" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (_Bool) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof__Bool=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof__Bool" >&5 +printf "%s\n" "$ac_cv_sizeof__Bool" >&6; } + + + +printf "%s\n" "#define SIZEOF__BOOL $ac_cv_sizeof__Bool" >>confdefs.h + + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5 +printf %s "checking size of off_t... " >&6; } +if test ${ac_cv_sizeof_off_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" " +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +" +then : + +else case e in #( + e) if test "$ac_cv_type_off_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (off_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_off_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5 +printf "%s\n" "$ac_cv_sizeof_off_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_OFF_T $ac_cv_sizeof_off_t" >>confdefs.h + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable large file support" >&5 +printf %s "checking whether to enable large file support... " >&6; } +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ + "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then + have_largefile_support="yes" +else + have_largefile_support="no" +fi +if test "x$have_largefile_support" = xyes +then : + + +printf "%s\n" "#define HAVE_LARGEFILE_SUPPORT 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; +esac +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5 +printf %s "checking size of time_t... " >&6; } +if test ${ac_cv_sizeof_time_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" " +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_TIME_H +#include <time.h> +#endif + +" +then : + +else case e in #( + e) if test "$ac_cv_type_time_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (time_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_time_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5 +printf "%s\n" "$ac_cv_sizeof_time_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_TIME_T $ac_cv_sizeof_time_t" >>confdefs.h + + + +# if have pthread_t then define SIZEOF_PTHREAD_T +ac_save_cc="$CC" +if test "$ac_cv_kpthread" = "yes" +then CC="$CC -Kpthread" +elif test "$ac_cv_kthread" = "yes" +then CC="$CC -Kthread" +elif test "$ac_cv_pthread" = "yes" +then CC="$CC -pthread" +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_t" >&5 +printf %s "checking for pthread_t... " >&6; } +if test ${ac_cv_have_pthread_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <pthread.h> +int +main (void) +{ +pthread_t x; x = *(pthread_t*)0; + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_have_pthread_t=yes +else case e in #( + e) ac_cv_have_pthread_t=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_pthread_t" >&5 +printf "%s\n" "$ac_cv_have_pthread_t" >&6; } +if test "x$ac_cv_have_pthread_t" = xyes +then : + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of pthread_t" >&5 +printf %s "checking size of pthread_t... " >&6; } +if test ${ac_cv_sizeof_pthread_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_t))" "ac_cv_sizeof_pthread_t" " +#ifdef HAVE_PTHREAD_H +#include <pthread.h> +#endif + +" +then : + +else case e in #( + e) if test "$ac_cv_type_pthread_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (pthread_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_pthread_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_t" >&5 +printf "%s\n" "$ac_cv_sizeof_pthread_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_PTHREAD_T $ac_cv_sizeof_pthread_t" >>confdefs.h + + + +fi + +# Issue #25658: POSIX hasn't defined that pthread_key_t is compatible with int. +# This checking will be unnecessary after removing deprecated TLS API. +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of pthread_key_t" >&5 +printf %s "checking size of pthread_key_t... " >&6; } +if test ${ac_cv_sizeof_pthread_key_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_key_t))" "ac_cv_sizeof_pthread_key_t" "#include <pthread.h> +" +then : + +else case e in #( + e) if test "$ac_cv_type_pthread_key_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (pthread_key_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_pthread_key_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_key_t" >&5 +printf "%s\n" "$ac_cv_sizeof_pthread_key_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_PTHREAD_KEY_T $ac_cv_sizeof_pthread_key_t" >>confdefs.h + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_key_t is compatible with int" >&5 +printf %s "checking whether pthread_key_t is compatible with int... " >&6; } +if test ${ac_cv_pthread_key_t_is_arithmetic_type+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +if test "$ac_cv_sizeof_pthread_key_t" -eq "$ac_cv_sizeof_int" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <pthread.h> +int +main (void) +{ +pthread_key_t k; k * 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_pthread_key_t_is_arithmetic_type=yes +else case e in #( + e) ac_cv_pthread_key_t_is_arithmetic_type=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +else + ac_cv_pthread_key_t_is_arithmetic_type=no +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_key_t_is_arithmetic_type" >&5 +printf "%s\n" "$ac_cv_pthread_key_t_is_arithmetic_type" >&6; } +if test "x$ac_cv_pthread_key_t_is_arithmetic_type" = xyes +then : + + +printf "%s\n" "#define PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT 1" >>confdefs.h + + +fi + +CC="$ac_save_cc" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-framework" >&5 +printf %s "checking for --enable-framework... " >&6; } +if test "$enable_framework" +then + BASECFLAGS="$BASECFLAGS -fno-common -dynamic" + # -F. is needed to allow linking to the framework while + # in the build location. + +printf "%s\n" "#define WITH_NEXT_FRAMEWORK 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + if test $enable_shared = "yes" + then + as_fn_error $? "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + +# Check for --with-dsymutil + + +DSYMUTIL= +DSYMUTIL_PATH= +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-dsymutil" >&5 +printf %s "checking for --with-dsymutil... " >&6; } + +# Check whether --with-dsymutil was given. +if test ${with_dsymutil+y} +then : + withval=$with_dsymutil; +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + as_fn_error $? "dsymutil debug linking is only available in macOS." "$LINENO" 5 + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; + DSYMUTIL='true' +else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; DSYMUTIL= +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + +if test "$DSYMUTIL"; then + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_DSYMUTIL_PATH+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $DSYMUTIL_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_DSYMUTIL_PATH="$DSYMUTIL_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_DSYMUTIL_PATH="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_DSYMUTIL_PATH" && ac_cv_path_DSYMUTIL_PATH="not found" + ;; +esac ;; +esac +fi +DSYMUTIL_PATH=$ac_cv_path_DSYMUTIL_PATH +if test -n "$DSYMUTIL_PATH"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL_PATH" >&5 +printf "%s\n" "$DSYMUTIL_PATH" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + if test "$DSYMUTIL_PATH" = "not found"; then + as_fn_error $? "dsymutil command not found on \$PATH" "$LINENO" 5 + fi +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dyld" >&5 +printf %s "checking for dyld... " >&6; } +case $ac_sys_system/$ac_sys_release in + Darwin/*) + +printf "%s\n" "#define WITH_DYLD 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: always on for Darwin" >&5 +printf "%s\n" "always on for Darwin" >&6; } + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-address-sanitizer" >&5 +printf %s "checking for --with-address-sanitizer... " >&6; } + +# Check whether --with-address_sanitizer was given. +if test ${with_address_sanitizer+y} +then : + withval=$with_address_sanitizer; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS" +LDFLAGS="-fsanitize=address $LDFLAGS" +# ASan works by controlling memory allocation, our own malloc interferes. +with_pymalloc="no" + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-memory-sanitizer" >&5 +printf %s "checking for --with-memory-sanitizer... " >&6; } + +# Check whether --with-memory_sanitizer was given. +if test ${with_memory_sanitizer+y} +then : + withval=$with_memory_sanitizer; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fsanitize=memory" >&5 +printf %s "checking whether C compiler accepts -fsanitize=memory... " >&6; } +if test ${ax_cv_check_cflags___fsanitize_memory+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fsanitize=memory" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___fsanitize_memory=yes +else case e in #( + e) ax_cv_check_cflags___fsanitize_memory=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fsanitize_memory" >&5 +printf "%s\n" "$ax_cv_check_cflags___fsanitize_memory" >&6; } +if test "x$ax_cv_check_cflags___fsanitize_memory" = xyes +then : + +BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS" +LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" + +else case e in #( + e) as_fn_error $? "The selected compiler doesn't support memory sanitizer" "$LINENO" 5 ;; +esac +fi + +# MSan works by controlling memory allocation, our own malloc interferes. +with_pymalloc="no" + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-undefined-behavior-sanitizer" >&5 +printf %s "checking for --with-undefined-behavior-sanitizer... " >&6; } + +# Check whether --with-undefined_behavior_sanitizer was given. +if test ${with_undefined_behavior_sanitizer+y} +then : + withval=$with_undefined_behavior_sanitizer; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +BASECFLAGS="-fsanitize=undefined $BASECFLAGS" +LDFLAGS="-fsanitize=undefined $LDFLAGS" +with_ubsan="yes" + +else case e in #( + e) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +with_ubsan="no" + ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-thread-sanitizer" >&5 +printf %s "checking for --with-thread-sanitizer... " >&6; } + +# Check whether --with-thread_sanitizer was given. +if test ${with_thread_sanitizer+y} +then : + withval=$with_thread_sanitizer; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +BASECFLAGS="-fsanitize=thread $BASECFLAGS" +LDFLAGS="-fsanitize=thread $LDFLAGS" +with_tsan="yes" + +else case e in #( + e) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +with_tsan="no" + ;; +esac +fi + + +# Set info about shared libraries. + + + + + + + +# SHLIB_SUFFIX is the extension of shared libraries `(including the dot!) +# -- usually .so, .sl on HP-UX, .dll on Cygwin +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the extension of shared libraries" >&5 +printf %s "checking the extension of shared libraries... " >&6; } +if test -z "$SHLIB_SUFFIX"; then + case $ac_sys_system in + hp*|HP*) + case `uname -m` in + ia64) SHLIB_SUFFIX=.so;; + *) SHLIB_SUFFIX=.sl;; + esac + ;; + CYGWIN*) SHLIB_SUFFIX=.dll;; + *) SHLIB_SUFFIX=.so;; + esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SHLIB_SUFFIX" >&5 +printf "%s\n" "$SHLIB_SUFFIX" >&6; } + +# LDSHARED is the ld *command* used to create shared library +# -- "cc -G" on SunOS 5.x. +# (Shared libraries in this instance are shared modules to be loaded into +# Python, as opposed to building Python itself as a shared library.) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDSHARED" >&5 +printf %s "checking LDSHARED... " >&6; } +if test -z "$LDSHARED" +then + case $ac_sys_system/$ac_sys_release in + AIX*) + BLDSHARED="Modules/ld_so_aix \$(CC) -bI:Modules/python.exp" + LDSHARED="\$(LIBPL)/ld_so_aix \$(CC) -bI:\$(LIBPL)/python.exp" + ;; + SunOS/5*) + if test "$ac_cv_gcc_compat" = "yes" ; then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED='$(CC) -G' + LDCXXSHARED='$(CXX) -G' + fi ;; + hp*|HP*) + if test "$ac_cv_gcc_compat" = "yes" ; then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED='$(CC) -b' + LDCXXSHARED='$(CXX) -b' + fi ;; + Darwin/1.3*) + LDSHARED='$(CC) -bundle' + LDCXXSHARED='$(CXX) -bundle' + if test "$enable_framework" ; then + # Link against the framework. All externals should be defined. + BLDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDCXXSHARED="$LDCXXSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + else + # No framework. Ignore undefined symbols, assuming they come from Python + LDSHARED="$LDSHARED -undefined suppress" + LDCXXSHARED="$LDCXXSHARED -undefined suppress" + fi ;; + Darwin/1.4*|Darwin/5.*|Darwin/6.*) + LDSHARED='$(CC) -bundle' + LDCXXSHARED='$(CXX) -bundle' + if test "$enable_framework" ; then + # Link against the framework. All externals should be defined. + BLDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDCXXSHARED="$LDCXXSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + else + # No framework, use the Python app as bundle-loader + BLDSHARED="$LDSHARED "'-bundle_loader $(BUILDPYTHON)' + LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)' + LDCXXSHARED="$LDCXXSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)' + fi ;; + Darwin/*) + # Use -undefined dynamic_lookup whenever possible (10.3 and later). + # This allows an extension to be used in any Python + + dep_target_major=`echo ${MACOSX_DEPLOYMENT_TARGET} | \ + sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'` + dep_target_minor=`echo ${MACOSX_DEPLOYMENT_TARGET} | \ + sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'` + if test ${dep_target_major} -eq 10 && \ + test ${dep_target_minor} -le 2 + then + # building for OS X 10.0 through 10.2 + as_fn_error $? "MACOSX_DEPLOYMENT_TARGET too old ($MACOSX_DEPLOYMENT_TARGET), only 10.3 or later is supported" "$LINENO" 5 + else + # building for OS X 10.3 and later + LDSHARED='$(CC) -bundle -undefined dynamic_lookup' + LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup' + BLDSHARED="$LDSHARED" + fi + ;; + iOS/*) + LDSHARED='$(CC) -dynamiclib -F . -framework $(PYTHONFRAMEWORK)' + LDCXXSHARED='$(CXX) -dynamiclib -F . -framework $(PYTHONFRAMEWORK)' + BLDSHARED="$LDSHARED" + ;; + Emscripten*|WASI*) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; + Linux*|GNU*|QNX*|VxWorks*|Haiku*) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; + FreeBSD*) + if [ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ] + then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED="ld -Bshareable" + fi;; + OpenBSD*) + if [ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ] + then + LDSHARED='$(CC) -shared $(CCSHARED)' + LDCXXSHARED='$(CXX) -shared $(CCSHARED)' + else + case `uname -r` in + [01].* | 2.[0-7] | 2.[0-7].*) + LDSHARED="ld -Bshareable ${LDFLAGS}" + ;; + *) + LDSHARED='$(CC) -shared $(CCSHARED)' + LDCXXSHARED='$(CXX) -shared $(CCSHARED)' + ;; + esac + fi;; + NetBSD*|DragonFly*) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; + OpenUNIX*|UnixWare*) + if test "$ac_cv_gcc_compat" = "yes" ; then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED='$(CC) -G' + LDCXXSHARED='$(CXX) -G' + fi;; + SCO_SV*) + LDSHARED='$(CC) -Wl,-G,-Bexport' + LDCXXSHARED='$(CXX) -Wl,-G,-Bexport';; + WASI*) + if test "x$enable_wasm_dynamic_linking" = xyes +then : + + +fi;; + CYGWIN*) + LDSHARED='$(CC) -shared -Wl,--enable-auto-image-base' + LDCXXSHARED='$(CXX) -shared -Wl,--enable-auto-image-base';; + *) LDSHARED="ld";; + esac +fi + +if test "$enable_wasm_dynamic_linking" = "yes" -a "$ac_sys_system" = "Emscripten"; then + BLDSHARED='$(CC) -shared -sSIDE_MODULE=1' +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDSHARED" >&5 +printf "%s\n" "$LDSHARED" >&6; } +LDCXXSHARED=${LDCXXSHARED-$LDSHARED} + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking BLDSHARED flags" >&5 +printf %s "checking BLDSHARED flags... " >&6; } +BLDSHARED=${BLDSHARED-$LDSHARED} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BLDSHARED" >&5 +printf "%s\n" "$BLDSHARED" >&6; } + +# CCSHARED are the C *flags* used to create objects to go into a shared +# library (module) -- this is only needed for a few systems +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CCSHARED" >&5 +printf %s "checking CCSHARED... " >&6; } +if test -z "$CCSHARED" +then + case $ac_sys_system/$ac_sys_release in + SunOS*) if test "$ac_cv_gcc_compat" = "yes"; + then CCSHARED="-fPIC"; + elif test `uname -p` = sparc; + then CCSHARED="-xcode=pic32"; + else CCSHARED="-Kpic"; + fi;; + hp*|HP*) if test "$ac_cv_gcc_compat" = "yes"; + then CCSHARED="-fPIC"; + else CCSHARED="+z"; + fi;; + Linux*|GNU*) CCSHARED="-fPIC";; + Emscripten*|WASI*) + if test "x$enable_wasm_dynamic_linking" = xyes +then : + + CCSHARED="-fPIC" + +fi;; + FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) CCSHARED="-fPIC";; + Haiku*) CCSHARED="-fPIC";; + OpenUNIX*|UnixWare*) + if test "$ac_cv_gcc_compat" = "yes" + then CCSHARED="-fPIC" + else CCSHARED="-KPIC" + fi;; + SCO_SV*) + if test "$ac_cv_gcc_compat" = "yes" + then CCSHARED="-fPIC" + else CCSHARED="-Kpic -belf" + fi;; + VxWorks*) + CCSHARED="-fpic -D__SO_PICABILINUX__ -ftls-model=global-dynamic" + esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CCSHARED" >&5 +printf "%s\n" "$CCSHARED" >&6; } +# LINKFORSHARED are the flags passed to the $(CC) command that links +# the python executable -- this is only needed for a few systems +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LINKFORSHARED" >&5 +printf %s "checking LINKFORSHARED... " >&6; } +if test -z "$LINKFORSHARED" +then + case $ac_sys_system/$ac_sys_release in + AIX*) LINKFORSHARED='-Wl,-bE:Modules/python.exp -lld';; + hp*|HP*) + LINKFORSHARED="-Wl,-E -Wl,+s";; +# LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";; + Linux-android*) LINKFORSHARED="-pie -Xlinker -export-dynamic";; + Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";; + # -u libsys_s pulls in all symbols in libsys + Darwin/*|iOS/*) + LINKFORSHARED="$extra_undefs -framework CoreFoundation" + + # Issue #18075: the default maximum stack size (8MBytes) is too + # small for the default recursion limit. Increase the stack size + # to ensure that tests don't crash + stack_size="1000000" # 16 MB + if test "$with_ubsan" = "yes" + then + # Undefined behavior sanitizer requires an even deeper stack + stack_size="4000000" # 64 MB + fi + + +printf "%s\n" "#define THREAD_STACK_SIZE 0x$stack_size" >>confdefs.h + + + if test $ac_sys_system = "Darwin"; then + LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" + + if test "$enable_framework"; then + LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + fi + LINKFORSHARED="$LINKFORSHARED" + elif test $ac_sys_system = "iOS"; then + LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)' + fi + ;; + OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";; + SCO_SV*) LINKFORSHARED="-Wl,-Bexport";; + ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; + FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) + if [ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ] + then + LINKFORSHARED="-Wl,--export-dynamic" + fi;; + SunOS/5*) if test "$ac_cv_gcc_compat" = "yes"; then + if $CC -Xlinker --help 2>&1 | grep export-dynamic >/dev/null + then + LINKFORSHARED="-Xlinker --export-dynamic" + fi + fi + ;; + CYGWIN*) + if test $enable_shared = "no" + then + LINKFORSHARED='-Wl,--out-implib=$(LDLIBRARY)' + fi;; + QNX*) + # -Wl,-E causes the symbols to be added to the dynamic + # symbol table so that they can be found when a module + # is loaded. -N 2048K causes the stack size to be set + # to 2048 kilobytes so that the stack doesn't overflow + # when running test_compile.py. + LINKFORSHARED='-Wl,-E -N 2048K';; + VxWorks*) + LINKFORSHARED='-Wl,-export-dynamic';; + esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LINKFORSHARED" >&5 +printf "%s\n" "$LINKFORSHARED" >&6; } + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CFLAGSFORSHARED" >&5 +printf %s "checking CFLAGSFORSHARED... " >&6; } +if test ! "$LIBRARY" = "$LDLIBRARY" +then + case $ac_sys_system in + CYGWIN*) + # Cygwin needs CCSHARED when building extension DLLs + # but not when building the interpreter DLL. + CFLAGSFORSHARED='';; + *) + CFLAGSFORSHARED='$(CCSHARED)' + esac +fi + +if test "x$enable_wasm_dynamic_linking" = xyes +then : + + CFLAGSFORSHARED='$(CCSHARED)' + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CFLAGSFORSHARED" >&5 +printf "%s\n" "$CFLAGSFORSHARED" >&6; } + +# SHLIBS are libraries (except -lc and -lm) to link to the python shared +# library (with --enable-shared). +# For platforms on which shared libraries are not allowed to have unresolved +# symbols, this must be set to $(LIBS) (expanded by make). We do this even +# if it is not required, since it creates a dependency of the shared library +# to LIBS. This, in turn, means that applications linking the shared libpython +# don't need to link LIBS explicitly. The default should be only changed +# on systems where this approach causes problems. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SHLIBS" >&5 +printf %s "checking SHLIBS... " >&6; } +case "$ac_sys_system" in + *) + SHLIBS='$(LIBS)';; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SHLIBS" >&5 +printf "%s\n" "$SHLIBS" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking perf trampoline" >&5 +printf %s "checking perf trampoline... " >&6; } +PERF_TRAMPOLINE_OBJ="" +case $PLATFORM_TRIPLET in #( + x86_64-linux-gnu) : + perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_x86_64.o ;; #( + x86_64-linux-musl) : + perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_x86_64.o ;; #( + aarch64-linux-gnu) : + perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_aarch64.o ;; #( + aarch64-linux-musl) : + perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_aarch64.o ;; #( + darwin) : + case $MACOSX_DEPLOYMENT_TARGET in #( + 10.[0-9]|10.1[0-1]) : + perf_trampoline=no ;; #( + *) : + perf_trampoline=yes + if test "${enable_universalsdk}" && test "$UNIVERSAL_ARCHS" = "universal2"; then + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_universal2.o + else + case "$host_cpu" in + x86_64) + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_x86_64.o + ;; + aarch64|arm64) + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_aarch64.o + ;; + *) + perf_trampoline=no + ;; + esac + fi + ;; +esac ;; #( + *) : + perf_trampoline=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $perf_trampoline" >&5 +printf "%s\n" "$perf_trampoline" >&6; } + +if test "x$perf_trampoline" = xyes +then : + + +printf "%s\n" "#define PY_HAVE_PERF_TRAMPOLINE 1" >>confdefs.h + + +fi + + +# checks for libraries +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sendfile in -lsendfile" >&5 +printf %s "checking for sendfile in -lsendfile... " >&6; } +if test ${ac_cv_lib_sendfile_sendfile+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsendfile $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sendfile (void); +int +main (void) +{ +return sendfile (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sendfile_sendfile=yes +else case e in #( + e) ac_cv_lib_sendfile_sendfile=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sendfile_sendfile" >&5 +printf "%s\n" "$ac_cv_lib_sendfile_sendfile" >&6; } +if test "x$ac_cv_lib_sendfile_sendfile" = xyes +then : + printf "%s\n" "#define HAVE_LIBSENDFILE 1" >>confdefs.h + + LIBS="-lsendfile $LIBS" + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (void); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlopen=yes +else case e in #( + e) ac_cv_lib_dl_dlopen=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + printf "%s\n" "#define HAVE_LIBDL 1" >>confdefs.h + + LIBS="-ldl $LIBS" + +fi + # Dynamic linking for SunOS/Solaris and SYSV +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +printf %s "checking for shl_load in -ldld... " >&6; } +if test ${ac_cv_lib_dld_shl_load+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (void); +int +main (void) +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dld_shl_load=yes +else case e in #( + e) ac_cv_lib_dld_shl_load=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes +then : + printf "%s\n" "#define HAVE_LIBDLD 1" >>confdefs.h + + LIBS="-ldld $LIBS" + +fi + # Dynamic linking for HP-UX + +ac_fn_c_check_header_compile "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default" +if test "x$ac_cv_header_iconv_h" = xyes +then : + printf "%s\n" "#define HAVE_ICONV_H 1" >>confdefs.h + +fi + +case $ac_sys_system in #( + Emscripten|WASI) : + py_have_iconv=no ;; #( + *) : + py_have_iconv=$ac_cv_header_iconv_h ;; +esac +if test "$py_have_iconv" = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +printf %s "checking for iconv... " >&6; } +if test ${ac_cv_have_iconv+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ac_cv_have_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdlib.h> +#include <iconv.h> + +int +main (void) +{ + + iconv_t cd = iconv_open("", ""); + iconv(cd, NULL, NULL, NULL, NULL); + iconv_close(cd); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_have_iconv=yes +else case e in #( + e) + py_save_LIBS="$LIBS" + LIBS="-liconv $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdlib.h> +#include <iconv.h> + +int +main (void) +{ + + iconv_t cd = iconv_open("", ""); + iconv(cd, NULL, NULL, NULL, NULL); + iconv_close(cd); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_have_iconv=-liconv +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$py_save_LIBS" + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_iconv" >&5 +printf "%s\n" "$ac_cv_have_iconv" >&6; } + if test "$ac_cv_have_iconv" != no; then + +printf "%s\n" "#define HAVE_ICONV 1" >>confdefs.h + + if test "$ac_cv_have_iconv" = -liconv; then + LIBS="-liconv $LIBS" + fi + fi +fi + + + for ac_header in execinfo.h link.h dlfcn.h +do : + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | sed "$as_sed_sh"` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_header" | sed "$as_sed_cpp"` 1 +_ACEOF + + + for ac_func in backtrace dladdr1 +do : + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | sed "$as_sed_sh"` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_func" | sed "$as_sed_cpp"` 1 +_ACEOF + + # dladdr1 requires -ldl + ac_cv_require_ldl=yes + +fi + +done + +fi + +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libgcc frame registration functions" >&5 +printf %s "checking for libgcc frame registration functions... " >&6; } +if test ${ac_cv_have_libgcc_eh_frame_registration+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +void __register_frame(const void *); +void __deregister_frame(const void *); + +int +main (void) +{ + +__register_frame(0); +__deregister_frame(0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_have_libgcc_eh_frame_registration=yes +else case e in #( + e) ac_cv_have_libgcc_eh_frame_registration=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libgcc_eh_frame_registration" >&5 +printf "%s\n" "$ac_cv_have_libgcc_eh_frame_registration" >&6; } +if test "x$ac_cv_have_libgcc_eh_frame_registration" = xyes +then : + + +printf "%s\n" "#define _Py_HAVE_LIBGCC_EH_FRAME_REGISTRATION 1" >>confdefs.h + + +fi + +if test "x$ac_cv_require_ldl" = xyes +then : + + if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + +else case e in #( + e) + as_fn_append LDFLAGS " -ldl" + ;; +esac +fi + +fi + + + + + + +have_uuid=missing + + for ac_header in uuid.h +do : + ac_fn_c_check_header_compile "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h + + + for ac_func in uuid_create uuid_enc_be +do : + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | sed "$as_sed_sh"` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_func" | sed "$as_sed_cpp"` 1 +_ACEOF + + have_uuid=yes + ac_cv_have_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +fi + +done + +fi + +done + +if test "x$have_uuid" = xmissing +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid >= 2.20" >&5 +printf %s "checking for uuid >= 2.20... " >&6; } + +if test -n "$LIBUUID_CFLAGS"; then + pkg_cv_LIBUUID_CFLAGS="$LIBUUID_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 + ($PKG_CONFIG --exists --print-errors "uuid >= 2.20") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUUID_CFLAGS=`$PKG_CONFIG --cflags "uuid >= 2.20" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBUUID_LIBS"; then + pkg_cv_LIBUUID_LIBS="$LIBUUID_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 + ($PKG_CONFIG --exists --print-errors "uuid >= 2.20") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUUID_LIBS=`$PKG_CONFIG --libs "uuid >= 2.20" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBUUID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "uuid >= 2.20" 2>&1` + else + LIBUUID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "uuid >= 2.20" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBUUID_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + for ac_header in uuid/uuid.h +do : + ac_fn_c_check_header_compile "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + + ac_cv_have_uuid_uuid_h=yes + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 +printf %s "checking for uuid_generate_time in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char uuid_generate_time (void); +int +main (void) +{ +return uuid_generate_time (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_uuid_uuid_generate_time=yes +else case e in #( + e) ac_cv_lib_uuid_uuid_generate_time=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes +then : + have_uuid=yes +fi + +LIBS=$py_check_lib_save_LIBS + + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 +printf %s "checking for uuid_generate_time_safe in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time_safe+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char uuid_generate_time_safe (void); +int +main (void) +{ +return uuid_generate_time_safe (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_uuid_uuid_generate_time_safe=yes +else case e in #( + e) ac_cv_lib_uuid_uuid_generate_time_safe=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes +then : + + have_uuid=yes + ac_cv_have_uuid_generate_time_safe=yes + +fi + +LIBS=$py_check_lib_save_LIBS + +fi + +done + if test "x$have_uuid" = xyes +then : + + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + for ac_header in uuid/uuid.h +do : + ac_fn_c_check_header_compile "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + + ac_cv_have_uuid_uuid_h=yes + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 +printf %s "checking for uuid_generate_time in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char uuid_generate_time (void); +int +main (void) +{ +return uuid_generate_time (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_uuid_uuid_generate_time=yes +else case e in #( + e) ac_cv_lib_uuid_uuid_generate_time=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes +then : + have_uuid=yes +fi + +LIBS=$py_check_lib_save_LIBS + + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 +printf %s "checking for uuid_generate_time_safe in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time_safe+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char uuid_generate_time_safe (void); +int +main (void) +{ +return uuid_generate_time_safe (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_uuid_uuid_generate_time_safe=yes +else case e in #( + e) ac_cv_lib_uuid_uuid_generate_time_safe=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes +then : + + have_uuid=yes + ac_cv_have_uuid_generate_time_safe=yes + +fi + +LIBS=$py_check_lib_save_LIBS + +fi + +done + if test "x$have_uuid" = xyes +then : + + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + + +else + LIBUUID_CFLAGS=$pkg_cv_LIBUUID_CFLAGS + LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_uuid=yes + ac_cv_have_uuid_generate_time_safe=yes + # The uuid.h file to include may be <uuid.h> *or* <uuid/uuid.h>. + # Since pkg-config --cflags uuid may return -I/usr/include/uuid, + # it's possible to write '#include <uuid.h>' in _uuidmodule.c, + # assuming that the compiler flags are properly updated. + # + # Ideally, we should have defined HAVE_UUID_H if and only if + # #include <uuid.h> can be written, *without* assuming extra + # include path. + ac_cv_have_uuid_h=yes + +fi + +fi + +if test "x$have_uuid" = xmissing +then : + + for ac_header in uuid/uuid.h +do : + ac_fn_c_check_header_compile "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + + ac_fn_c_check_func "$LINENO" "uuid_generate_time" "ac_cv_func_uuid_generate_time" +if test "x$ac_cv_func_uuid_generate_time" = xyes +then : + + have_uuid=yes + ac_cv_have_uuid_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +fi + + +fi + +done + +fi + +if test "x$ac_cv_have_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h + +fi +if test "x$ac_cv_have_uuid_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + +fi +if test "x$ac_cv_have_uuid_generate_time_safe" = xyes +then : + + printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h + + +fi + +# gh-124228: While the libuuid library is available on NetBSD and OpenBSD, +# it supports only UUID version 4. +# This restriction inhibits the proper generation of time-based UUIDs. +if test "$ac_sys_system" = "NetBSD" || test "$ac_sys_system" = "OpenBSD"; then + have_uuid=missing + printf "%s\n" "#define HAVE_UUID_H 0" >>confdefs.h + +fi + +if test "x$have_uuid" = xmissing +then : + have_uuid=no +fi + +# gh-132710: The UUID node is fetched by using libuuid when possible +# and cached. While the node is constant within the same process, +# different interpreters may have different values as libuuid may +# randomize the node value if the latter cannot be deduced. +# +# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC +# to indicate that libuuid is unstable and should not be relied +# upon to deduce the MAC address. + + +if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if uuid_generate_time_safe() node value is stable" >&5 +printf %s "checking if uuid_generate_time_safe() node value is stable... " >&6; } + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + # Be sure to add the extra include path if we used pkg-config + # as HAVE_UUID_H may be set even though <uuid.h> is only reachable + # by adding extra -I flags. + # + # If the following script does not compile, we simply assume that + # libuuid is missing. + CFLAGS="$CFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + if test "$cross_compiling" = yes +then : + + +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <inttypes.h> // PRIu64 + #include <stdint.h> // uint64_t + #include <stdio.h> // fopen(), fclose() + + #ifdef HAVE_UUID_H + #include <uuid.h> + #else + #include <uuid/uuid.h> + #endif + + #define ERR 1 + int main(void) { + uuid_t uuid; // unsigned char[16] + (void)uuid_generate_time_safe(uuid); + uint64_t node = 0; + for (size_t i = 0; i < 6; i++) { + node |= (uint64_t)uuid[15 - i] << (8 * i); + } + FILE *fp = fopen("conftest.out", "w"); + if (fp == NULL) { + return ERR; + } + int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; + rc |= fclose(fp); + return rc == 0 ? 0 : ERR; + } +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + + py_cv_uuid_node1=`cat conftest.out` + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + # Be sure to add the extra include path if we used pkg-config + # as HAVE_UUID_H may be set even though <uuid.h> is only reachable + # by adding extra -I flags. + # + # If the following script does not compile, we simply assume that + # libuuid is missing. + CFLAGS="$CFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + if test "$cross_compiling" = yes +then : + + +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <inttypes.h> // PRIu64 + #include <stdint.h> // uint64_t + #include <stdio.h> // fopen(), fclose() + + #ifdef HAVE_UUID_H + #include <uuid.h> + #else + #include <uuid/uuid.h> + #endif + + #define ERR 1 + int main(void) { + uuid_t uuid; // unsigned char[16] + (void)uuid_generate_time_safe(uuid); + uint64_t node = 0; + for (size_t i = 0; i < 6; i++) { + node |= (uint64_t)uuid[15 - i] << (8 * i); + } + FILE *fp = fopen("conftest.out", "w"); + if (fp == NULL) { + return ERR; + } + int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; + rc |= fclose(fp); + return rc == 0 ? 0 : ERR; + } +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + + py_cv_uuid_node2=`cat conftest.out` + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" + then + printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: stable" >&5 +printf "%s\n" "stable" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unstable" >&5 +printf "%s\n" "unstable" >&6; } + fi +fi + +# 'Real Time' functions on Solaris +# posix4 on Solaris 2.6 +# pthread (first!) on Linux +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing sem_init" >&5 +printf %s "checking for library containing sem_init... " >&6; } +if test ${ac_cv_search_sem_init+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sem_init (void); +int +main (void) +{ +return sem_init (); + ; + return 0; +} +_ACEOF +for ac_lib in '' pthread rt posix4 +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_sem_init=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_sem_init+y} +then : + break +fi +done +if test ${ac_cv_search_sem_init+y} +then : + +else case e in #( + e) ac_cv_search_sem_init=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sem_init" >&5 +printf "%s\n" "$ac_cv_search_sem_init" >&6; } +ac_res=$ac_cv_search_sem_init +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +# check if we need libintl for locale functions +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for textdomain in -lintl" >&5 +printf %s "checking for textdomain in -lintl... " >&6; } +if test ${ac_cv_lib_intl_textdomain+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char textdomain (void); +int +main (void) +{ +return textdomain (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_intl_textdomain=yes +else case e in #( + e) ac_cv_lib_intl_textdomain=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_textdomain" >&5 +printf "%s\n" "$ac_cv_lib_intl_textdomain" >&6; } +if test "x$ac_cv_lib_intl_textdomain" = xyes +then : + +printf "%s\n" "#define WITH_LIBINTL 1" >>confdefs.h + + LIBS="-lintl $LIBS" +fi + + +# checks for system dependent C++ extensions support +case "$ac_sys_system" in + AIX*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for genuine AIX C++ extensions support" >&5 +printf %s "checking for genuine AIX C++ extensions support... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <load.h> +int +main (void) +{ +loadAndInit("", 0, "") + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + +printf "%s\n" "#define AIX_GENUINE_CPLUSPLUS 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +# BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag +# of the AIX system used to build/package Python executable. This tag serves +# as a baseline for bdist module packages + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the system builddate" >&5 +printf %s "checking for the system builddate... " >&6; } + AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }') + +printf "%s\n" "#define AIX_BUILDDATE $AIX_BUILDDATE" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AIX_BUILDDATE" >&5 +printf "%s\n" "$AIX_BUILDDATE" >&6; } + ;; + *) ;; +esac + +# check for systems that require aligned memory access +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking aligned memory access is required" >&5 +printf %s "checking aligned memory access is required... " >&6; } +if test ${ac_cv_aligned_required+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + +# "yes" changes the hash function to FNV, which causes problems with Numba +# (https://github.com/numba/numba/blob/0.59.0/numba/cpython/hashing.py#L470). +if test "$ac_sys_system" = "Linux-android"; then + ac_cv_aligned_required=no +else + ac_cv_aligned_required=yes +fi +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int main(void) +{ + char s[16]; + int i, *p1, *p2; + for (i=0; i < 16; i++) + s[i] = i; + p1 = (int*)(s+1); + p2 = (int*)(s+2); + if (*p1 == *p2) + return 1; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_aligned_required=no +else case e in #( + e) ac_cv_aligned_required=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_aligned_required" >&5 +printf "%s\n" "$ac_cv_aligned_required" >&6; } +if test "$ac_cv_aligned_required" = yes ; then + +printf "%s\n" "#define HAVE_ALIGNED_REQUIRED 1" >>confdefs.h + +fi + +# str, bytes and memoryview hash algorithm + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-hash-algorithm" >&5 +printf %s "checking for --with-hash-algorithm... " >&6; } + +# Check whether --with-hash_algorithm was given. +if test ${with_hash_algorithm+y} +then : + withval=$with_hash_algorithm; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +case "$withval" in + siphash13) + printf "%s\n" "#define Py_HASH_ALGORITHM 3" >>confdefs.h + + ;; + siphash24) + printf "%s\n" "#define Py_HASH_ALGORITHM 1" >>confdefs.h + + ;; + fnv) + printf "%s\n" "#define Py_HASH_ALGORITHM 2" >>confdefs.h + + ;; + *) + as_fn_error $? "unknown hash algorithm '$withval'" "$LINENO" 5 + ;; +esac + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: default" >&5 +printf "%s\n" "default" >&6; } ;; +esac +fi + + +validate_tzpath() { + # Checks that each element of the path is an absolute path + if test -z "$1"; then + # Empty string is allowed: it indicates no system TZPATH + return 0 + fi + + # Bad paths are those that don't start with / + if ( echo $1 | grep '\(^\|:\)\([^/]\|$\)' > /dev/null); then + as_fn_error $? "--with-tzpath must contain only absolute paths, not $1" "$LINENO" 5 + return 1; + fi +} + +TZPATH="/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-tzpath" >&5 +printf %s "checking for --with-tzpath... " >&6; } + +# Check whether --with-tzpath was given. +if test ${with_tzpath+y} +then : + withval=$with_tzpath; +case "$withval" in + yes) + as_fn_error $? "--with-tzpath requires a value" "$LINENO" 5 + ;; + *) + validate_tzpath "$withval" + TZPATH="$withval" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$withval\"" >&5 +printf "%s\n" "\"$withval\"" >&6; } + ;; +esac + +else case e in #( + e) validate_tzpath "$TZPATH" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$TZPATH\"" >&5 +printf "%s\n" "\"$TZPATH\"" >&6; } ;; +esac +fi + + + +# Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for t_open in -lnsl" >&5 +printf %s "checking for t_open in -lnsl... " >&6; } +if test ${ac_cv_lib_nsl_t_open+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char t_open (void); +int +main (void) +{ +return t_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_nsl_t_open=yes +else case e in #( + e) ac_cv_lib_nsl_t_open=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_t_open" >&5 +printf "%s\n" "$ac_cv_lib_nsl_t_open" >&6; } +if test "x$ac_cv_lib_nsl_t_open" = xyes +then : + LIBS="-lnsl $LIBS" +fi + # SVR4 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +printf %s "checking for socket in -lsocket... " >&6; } +if test ${ac_cv_lib_socket_socket+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char socket (void); +int +main (void) +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_socket_socket=yes +else case e in #( + e) ac_cv_lib_socket_socket=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 +printf "%s\n" "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = xyes +then : + LIBS="-lsocket $LIBS" +fi + # SVR4 sockets + +case $ac_sys_system/$ac_sys_release in + Haiku*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socket in -lnetwork" >&5 +printf %s "checking for socket in -lnetwork... " >&6; } +if test ${ac_cv_lib_network_socket+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lnetwork $LIBS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char socket (void); +int +main (void) +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_network_socket=yes +else case e in #( + e) ac_cv_lib_network_socket=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_socket" >&5 +printf "%s\n" "$ac_cv_lib_network_socket" >&6; } +if test "x$ac_cv_lib_network_socket" = xyes +then : + LIBS="-lnetwork $LIBS" +fi + + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-libs" >&5 +printf %s "checking for --with-libs... " >&6; } + +# Check whether --with-libs was given. +if test ${with_libs+y} +then : + withval=$with_libs; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +LIBS="$withval $LIBS" + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + +# Check for use of the system expat library +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-system-expat" >&5 +printf %s "checking for --with-system-expat... " >&6; } + +# Check whether --with-system_expat was given. +if test ${with_system_expat+y} +then : + withval=$with_system_expat; +else case e in #( + e) with_system_expat="no" ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_system_expat" >&5 +printf "%s\n" "$with_system_expat" >&6; } + +if test "x$with_system_expat" = xyes +then : + + LIBEXPAT_CFLAGS=${LIBEXPAT_CFLAGS-""} + LIBEXPAT_LDFLAGS=${LIBEXPAT_LDFLAGS-"-lexpat"} + LIBEXPAT_INTERNAL= + +else case e in #( + e) + LIBEXPAT_CFLAGS="-I\$(srcdir)/Modules/expat" + LIBEXPAT_LDFLAGS="-lm \$(LIBEXPAT_A)" + LIBEXPAT_INTERNAL="\$(LIBEXPAT_HEADERS) \$(LIBEXPAT_A)" + ;; +esac +fi + + + + +have_libffi=missing +if test "x$ac_sys_system" = xDarwin +then : + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CFLAGS="-I${SDKROOT}/usr/include/ffi $CFLAGS" + ac_fn_c_check_header_compile "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +printf %s "checking for ffi_call in -lffi... " >&6; } +if test ${ac_cv_lib_ffi_ffi_call+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char ffi_call (void); +int +main (void) +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ffi_ffi_call=yes +else case e in #( + e) ac_cv_lib_ffi_ffi_call=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +printf "%s\n" "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes +then : + + have_libffi=yes + LIBFFI_CFLAGS="-I${SDKROOT}/usr/include/ffi -DUSING_APPLE_OS_LIBFFI=1" + LIBFFI_LIBS="-lffi" + +fi + + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi +if test "x$have_libffi" = xmissing +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libffi" >&5 +printf %s "checking for libffi... " >&6; } + +if test -n "$LIBFFI_CFLAGS"; then + pkg_cv_LIBFFI_CFLAGS="$LIBFFI_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libffi\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libffi") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBFFI_CFLAGS=`$PKG_CONFIG --cflags "libffi" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBFFI_LIBS"; then + pkg_cv_LIBFFI_LIBS="$LIBFFI_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libffi\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libffi") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBFFI_LIBS=`$PKG_CONFIG --libs "libffi" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libffi" 2>&1` + else + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libffi" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBFFI_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LIBS="$LIBS $LIBFFI_LIBS" + ac_fn_c_check_header_compile "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +printf %s "checking for ffi_call in -lffi... " >&6; } +if test ${ac_cv_lib_ffi_ffi_call+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char ffi_call (void); +int +main (void) +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ffi_ffi_call=yes +else case e in #( + e) ac_cv_lib_ffi_ffi_call=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +printf "%s\n" "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes +then : + + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} + +else case e in #( + e) have_libffi=no ;; +esac +fi + + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LIBS="$LIBS $LIBFFI_LIBS" + ac_fn_c_check_header_compile "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +printf %s "checking for ffi_call in -lffi... " >&6; } +if test ${ac_cv_lib_ffi_ffi_call+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char ffi_call (void); +int +main (void) +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ffi_ffi_call=yes +else case e in #( + e) ac_cv_lib_ffi_ffi_call=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +printf "%s\n" "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes +then : + + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} + +else case e in #( + e) have_libffi=no ;; +esac +fi + + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS + LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_libffi=yes +fi + +fi + +if test "x$have_libffi" = xyes +then : + + ctypes_malloc_closure=no + case $ac_sys_system in #( + Darwin) : + + ctypes_malloc_closure=yes + ;; #( + iOS) : + + ctypes_malloc_closure=yes + ;; #( + sunos5) : + as_fn_append LIBFFI_LIBS " -mimpure-text" + ;; #( + *) : + ;; +esac + if test "x$ctypes_malloc_closure" = xyes +then : + + MODULE__CTYPES_MALLOC_CLOSURE=_ctypes/malloc_closure.c + as_fn_append LIBFFI_CFLAGS " -DUSING_MALLOC_CLOSURE_DOT_C=1" + +fi + + + if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + as_fn_append LIBFFI_LIBS " -ldl" +fi + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CFLAGS="$CFLAGS $LIBFFI_CFLAGS" + LIBS="$LIBS $LIBFFI_LIBS" + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_prep_cif_var" >&5 +printf %s "checking for ffi_prep_cif_var... " >&6; } +if test ${ac_cv_func_ffi_prep_cif_var+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ffi.h> +int +main (void) +{ +void *x=ffi_prep_cif_var + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ffi_prep_cif_var=yes +else case e in #( + e) ac_cv_func_ffi_prep_cif_var=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_prep_cif_var" >&5 +printf "%s\n" "$ac_cv_func_ffi_prep_cif_var" >&6; } + if test "x$ac_cv_func_ffi_prep_cif_var" = xyes +then : + +printf "%s\n" "#define HAVE_FFI_PREP_CIF_VAR 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_prep_closure_loc" >&5 +printf %s "checking for ffi_prep_closure_loc... " >&6; } +if test ${ac_cv_func_ffi_prep_closure_loc+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ffi.h> +int +main (void) +{ +void *x=ffi_prep_closure_loc + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ffi_prep_closure_loc=yes +else case e in #( + e) ac_cv_func_ffi_prep_closure_loc=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_prep_closure_loc" >&5 +printf "%s\n" "$ac_cv_func_ffi_prep_closure_loc" >&6; } + if test "x$ac_cv_func_ffi_prep_closure_loc" = xyes +then : + +printf "%s\n" "#define HAVE_FFI_PREP_CLOSURE_LOC 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_closure_alloc" >&5 +printf %s "checking for ffi_closure_alloc... " >&6; } +if test ${ac_cv_func_ffi_closure_alloc+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ffi.h> +int +main (void) +{ +void *x=ffi_closure_alloc + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ffi_closure_alloc=yes +else case e in #( + e) ac_cv_func_ffi_closure_alloc=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_closure_alloc" >&5 +printf "%s\n" "$ac_cv_func_ffi_closure_alloc" >&6; } + if test "x$ac_cv_func_ffi_closure_alloc" = xyes +then : + +printf "%s\n" "#define HAVE_FFI_CLOSURE_ALLOC 1" >>confdefs.h + +fi + + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi + +# Check for libffi with real complex double support. +# This is a workaround, since FFI_TARGET_HAS_COMPLEX_TYPE was defined in libffi v3.2.1, +# but real support was provided only in libffi v3.3.0. +# See https://github.com/python/cpython/issues/125206 for more details. +# +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking libffi has complex type support" >&5 +printf %s "checking libffi has complex type support... " >&6; } +if test ${ac_cv_ffi_complex_double_supported+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LIBS="$LIBS $LIBFFI_LIBS" +if test "$cross_compiling" = yes +then : + ac_cv_ffi_complex_double_supported=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <complex.h> +#include <ffi.h> +int z_is_expected(double complex z) +{ + const double complex expected = 1.25 - 0.5 * I; + return z == expected; +} +int main(void) +{ + double complex z = 1.25 - 0.5 * I; + ffi_type *args[1] = {&ffi_type_complex_double}; + void *values[1] = {&z}; + ffi_cif cif; + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) != FFI_OK) + { + return 2; + } + ffi_arg rc; + ffi_call(&cif, FFI_FN(z_is_expected), &rc, values); + return !rc; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_ffi_complex_double_supported=yes +else case e in #( + e) ac_cv_ffi_complex_double_supported=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ffi_complex_double_supported" >&5 +printf "%s\n" "$ac_cv_ffi_complex_double_supported" >&6; } +if test "$ac_cv_ffi_complex_double_supported" = "yes"; then + +printf "%s\n" "#define _Py_FFI_SUPPORT_C_COMPLEX 1" >>confdefs.h + +fi + +# Check for native half-float type (_Float16). +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _Float16 support" >&5 +printf %s "checking for _Float16 support... " >&6; } +if test ${ac_cv_float16_supported+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + +CFLAGS="$CFLAGS -O0" +if test "$cross_compiling" = yes +then : + ac_cv_float16_supported=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <math.h> +int main(void) +{ + _Float16 val = 1.0f16; + int test = isinf(val) || isnan(val); /* basic support from libm */ + double d = 3.14; + val = d; + return test; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_float16_supported=yes +else case e in #( + e) ac_cv_float16_supported=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_float16_supported" >&5 +printf "%s\n" "$ac_cv_float16_supported" >&6; } +if test "x$ac_cv_float16_supported" = xyes +then : + +printf "%s\n" "#define HAVE_FLOAT16 1" >>confdefs.h + +fi + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmpdec >= 2.5.0" >&5 +printf %s "checking for libmpdec >= 2.5.0... " >&6; } + +if test -n "$LIBMPDEC_CFLAGS"; then + pkg_cv_LIBMPDEC_CFLAGS="$LIBMPDEC_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpdec >= 2.5.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmpdec >= 2.5.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBMPDEC_CFLAGS=`$PKG_CONFIG --cflags "libmpdec >= 2.5.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBMPDEC_LIBS"; then + pkg_cv_LIBMPDEC_LIBS="$LIBMPDEC_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpdec >= 2.5.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmpdec >= 2.5.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBMPDEC_LIBS=`$PKG_CONFIG --libs "libmpdec >= 2.5.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBMPDEC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmpdec >= 2.5.0" 2>&1` + else + LIBMPDEC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmpdec >= 2.5.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBMPDEC_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBMPDEC_CFLAGS" + LIBS="$LIBS $LIBMPDEC_LIBS" + ac_fn_c_check_header_compile "$LINENO" "mpdecimal.h" "ac_cv_header_mpdecimal_h" "$ac_includes_default" +if test "x$ac_cv_header_mpdecimal_h" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mpd_version in -lmpdec" >&5 +printf %s "checking for mpd_version in -lmpdec... " >&6; } +if test ${ac_cv_lib_mpdec_mpd_version+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lmpdec $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char mpd_version (void); +int +main (void) +{ +return mpd_version (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_mpdec_mpd_version=yes +else case e in #( + e) ac_cv_lib_mpdec_mpd_version=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpdec_mpd_version" >&5 +printf "%s\n" "$ac_cv_lib_mpdec_mpd_version" >&6; } +if test "x$ac_cv_lib_mpdec_mpd_version" = xyes +then : + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <mpdecimal.h> + #if MPD_VERSION_HEX < 0x02050000 + # error "mpdecimal 2.5.0 or higher required" + #endif + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_mpdec=yes +else case e in #( + e) have_mpdec=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +else case e in #( + e) have_mpdec=no ;; +esac +fi + + +else case e in #( + e) have_mpdec=no ;; +esac +fi + + + if test "x$have_mpdec" = xyes +then : + + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_LIBS=${LIBMPDEC_LIBS-"-lmpdec -lm"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBMPDEC_CFLAGS" + LIBS="$LIBS $LIBMPDEC_LIBS" + ac_fn_c_check_header_compile "$LINENO" "mpdecimal.h" "ac_cv_header_mpdecimal_h" "$ac_includes_default" +if test "x$ac_cv_header_mpdecimal_h" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mpd_version in -lmpdec" >&5 +printf %s "checking for mpd_version in -lmpdec... " >&6; } +if test ${ac_cv_lib_mpdec_mpd_version+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lmpdec $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char mpd_version (void); +int +main (void) +{ +return mpd_version (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_mpdec_mpd_version=yes +else case e in #( + e) ac_cv_lib_mpdec_mpd_version=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpdec_mpd_version" >&5 +printf "%s\n" "$ac_cv_lib_mpdec_mpd_version" >&6; } +if test "x$ac_cv_lib_mpdec_mpd_version" = xyes +then : + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <mpdecimal.h> + #if MPD_VERSION_HEX < 0x02050000 + # error "mpdecimal 2.5.0 or higher required" + #endif + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_mpdec=yes +else case e in #( + e) have_mpdec=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +else case e in #( + e) have_mpdec=no ;; +esac +fi + + +else case e in #( + e) have_mpdec=no ;; +esac +fi + + + if test "x$have_mpdec" = xyes +then : + + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_LIBS=${LIBMPDEC_LIBS-"-lmpdec -lm"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBMPDEC_CFLAGS=$pkg_cv_LIBMPDEC_CFLAGS + LIBMPDEC_LIBS=$pkg_cv_LIBMPDEC_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_mpdec=yes +fi + +# Check whether _decimal should use a coroutine-local or thread-local context +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-decimal-contextvar" >&5 +printf %s "checking for --with-decimal-contextvar... " >&6; } + +# Check whether --with-decimal_contextvar was given. +if test ${with_decimal_contextvar+y} +then : + withval=$with_decimal_contextvar; +else case e in #( + e) with_decimal_contextvar="yes" ;; +esac +fi + + +if test "$with_decimal_contextvar" != "no" +then + +printf "%s\n" "#define WITH_DECIMAL_CONTEXTVAR 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_decimal_contextvar" >&5 +printf "%s\n" "$with_decimal_contextvar" >&6; } + + + + + if test "$ac_sys_system" = "Emscripten" -a -z "$LIBSQLITE3_CFLAGS" -a -z "$LIBSQLITE3_LIBS" +then : + + LIBSQLITE3_CFLAGS="-sUSE_SQLITE3" + LIBSQLITE3_LIBS="-sUSE_SQLITE3" + +fi + + + + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3 >= 3.15.2" >&5 +printf %s "checking for sqlite3 >= 3.15.2... " >&6; } + +if test -n "$LIBSQLITE3_CFLAGS"; then + pkg_cv_LIBSQLITE3_CFLAGS="$LIBSQLITE3_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.15.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sqlite3 >= 3.15.2") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBSQLITE3_CFLAGS=`$PKG_CONFIG --cflags "sqlite3 >= 3.15.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBSQLITE3_LIBS"; then + pkg_cv_LIBSQLITE3_LIBS="$LIBSQLITE3_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.15.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sqlite3 >= 3.15.2") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBSQLITE3_LIBS=`$PKG_CONFIG --libs "sqlite3 >= 3.15.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBSQLITE3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sqlite3 >= 3.15.2" 2>&1` + else + LIBSQLITE3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sqlite3 >= 3.15.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBSQLITE3_PKG_ERRORS" >&5 + + + LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} + LIBSQLITE3_LIBS=${LIBSQLITE3_LIBS-"-lsqlite3"} + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} + LIBSQLITE3_LIBS=${LIBSQLITE3_LIBS-"-lsqlite3"} + + +else + LIBSQLITE3_CFLAGS=$pkg_cv_LIBSQLITE3_CFLAGS + LIBSQLITE3_LIBS=$pkg_cv_LIBSQLITE3_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +fi +as_fn_append LIBSQLITE3_CFLAGS ' -I$(srcdir)/Modules/_sqlite' + + + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBSQLITE3_CFLAGS" + LIBS="$LIBS $LIBSQLITE3_LIBS" + + ac_fn_c_check_header_compile "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default" +if test "x$ac_cv_header_sqlite3_h" = xyes +then : + + have_sqlite3=yes + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <sqlite3.h> + #if SQLITE_VERSION_NUMBER < 3015002 + # error "SQLite 3.15.2 or higher required" + #endif + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + have_supported_sqlite3=yes + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_bind_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_bind_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_bind_double+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_bind_double (void); +int +main (void) +{ +return sqlite3_bind_double (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_bind_double=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_bind_double=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_bind_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_bind_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_bind_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_decltype in -lsqlite3" >&5 +printf %s "checking for sqlite3_column_decltype in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_column_decltype+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_column_decltype (void); +int +main (void) +{ +return sqlite3_column_decltype (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_column_decltype=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_column_decltype=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_decltype" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_column_decltype" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_column_decltype" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_column_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_column_double+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_column_double (void); +int +main (void) +{ +return sqlite3_column_double (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_column_double=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_column_double=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_column_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_column_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_complete in -lsqlite3" >&5 +printf %s "checking for sqlite3_complete in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_complete+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_complete (void); +int +main (void) +{ +return sqlite3_complete (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_complete=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_complete=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_complete" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_complete" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_complete" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_progress_handler in -lsqlite3" >&5 +printf %s "checking for sqlite3_progress_handler in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_progress_handler+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_progress_handler (void); +int +main (void) +{ +return sqlite3_progress_handler (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_progress_handler=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_progress_handler=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_progress_handler" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_progress_handler" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_progress_handler" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_result_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_result_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_result_double+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_result_double (void); +int +main (void) +{ +return sqlite3_result_double (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_result_double=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_result_double=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_result_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_result_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_result_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_set_authorizer in -lsqlite3" >&5 +printf %s "checking for sqlite3_set_authorizer in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_set_authorizer+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_set_authorizer (void); +int +main (void) +{ +return sqlite3_set_authorizer (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_set_authorizer=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_set_authorizer=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_set_authorizer" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace_v2 in -lsqlite3" >&5 +printf %s "checking for sqlite3_trace_v2 in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_trace_v2+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_trace_v2 (void); +int +main (void) +{ +return sqlite3_trace_v2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_trace_v2=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_trace_v2=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace_v2" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_trace_v2" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_trace_v2" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace in -lsqlite3" >&5 +printf %s "checking for sqlite3_trace in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_trace+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_trace (void); +int +main (void) +{ +return sqlite3_trace (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_trace=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_trace=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_trace" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_trace" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + + ;; +esac +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_value_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_value_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_value_double+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_value_double (void); +int +main (void) +{ +return sqlite3_value_double (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_value_double=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_value_double=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_value_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_value_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_value_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h + + LIBS="-lsqlite3 $LIBS" + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_load_extension in -lsqlite3" >&5 +printf %s "checking for sqlite3_load_extension in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_load_extension+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_load_extension (void); +int +main (void) +{ +return sqlite3_load_extension (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_load_extension=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_load_extension=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_load_extension" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_load_extension" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_load_extension" = xyes +then : + have_sqlite3_load_extension=yes +else case e in #( + e) have_sqlite3_load_extension=no + ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_serialize in -lsqlite3" >&5 +printf %s "checking for sqlite3_serialize in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_serialize+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_serialize (void); +int +main (void) +{ +return sqlite3_serialize (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_serialize=yes +else case e in #( + e) ac_cv_lib_sqlite3_sqlite3_serialize=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_serialize" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_serialize" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_serialize" = xyes +then : + + +printf "%s\n" "#define PY_SQLITE_HAVE_SERIALIZE 1" >>confdefs.h + + +fi + + +else case e in #( + e) + have_supported_sqlite3=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-loadable-sqlite-extensions" >&5 +printf %s "checking for --enable-loadable-sqlite-extensions... " >&6; } +# Check whether --enable-loadable-sqlite-extensions was given. +if test ${enable_loadable_sqlite_extensions+y} +then : + enableval=$enable_loadable_sqlite_extensions; + if test "x$have_sqlite3_load_extension" = xno +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: n/a" >&5 +printf "%s\n" "n/a" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Your version of SQLite does not support loadable extensions" >&5 +printf "%s\n" "$as_me: WARNING: Your version of SQLite does not support loadable extensions" >&2;} + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define PY_SQLITE_ENABLE_LOAD_EXTENSION 1" >>confdefs.h + + ;; +esac +fi + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + ;; +esac +fi + + +found_tcltk=no +for _QUERY in \ + "tcl >= 8.5.12 tk >= 8.5.12" \ + "tcl8.6 tk8.6" \ + "tcl86 tk86" \ + "tcl8.5 >= 8.5.12 tk8.5 >= 8.5.12" \ + "tcl85 >= 8.5.12 tk85 >= 8.5.12" \ +; do + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $_QUERY" >&5 +printf %s "checking for $_QUERY... " >&6; } + +if test -n "$TCLTK_CFLAGS"; then + pkg_cv_TCLTK_CFLAGS="$TCLTK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TCLTK_CFLAGS=`$PKG_CONFIG --cflags "$_QUERY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$TCLTK_LIBS"; then + pkg_cv_TCLTK_LIBS="$TCLTK_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TCLTK_LIBS=`$PKG_CONFIG --libs "$_QUERY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + TCLTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$_QUERY" 2>&1` + else + TCLTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$_QUERY" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$TCLTK_PKG_ERRORS" >&5 + + found_tcltk=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + found_tcltk=no +else + TCLTK_CFLAGS=$pkg_cv_TCLTK_CFLAGS + TCLTK_LIBS=$pkg_cv_TCLTK_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + found_tcltk=yes +fi + +fi + if test "x$found_tcltk" = xyes +then : + break +fi +done + +if test "x$found_tcltk" = xno +then : + + TCLTK_CFLAGS=${TCLTK_CFLAGS-""} + TCLTK_LIBS=${TCLTK_LIBS-""} + +fi + +case $ac_sys_system in #( + FreeBSD*) : + + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x11" >&5 +printf %s "checking for x11... " >&6; } + +if test -n "$X11_CFLAGS"; then + pkg_cv_X11_CFLAGS="$X11_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$X11_LIBS"; then + pkg_cv_X11_LIBS="$X11_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11" 2>&1` + else + X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$X11_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (x11) were not met: + +$X11_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/>. +See 'config.log' for more details" "$LINENO" 5; } +else + X11_CFLAGS=$pkg_cv_X11_CFLAGS + X11_LIBS=$pkg_cv_X11_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + TCLTK_CFLAGS="$TCLTK_CFLAGS $X11_CFLAGS" + TCLTK_LIBS="$TCLTK_LIBS $X11_LIBS" + +fi + +fi + + ;; #( + *) : + ;; +esac + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $TCLTK_CFLAGS" + LIBS="$LIBS $TCLTK_LIBS" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <tcl.h> + #include <tk.h> + #if defined(TK_HEX_VERSION) + # if TK_HEX_VERSION < 0x0805020c + # error "Tk older than 8.5.12 not supported" + # endif + #endif + #if (TCL_MAJOR_VERSION < 8) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 5)) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 5) && (TCL_RELEASE_SERIAL < 12)) + # error "Tcl older than 8.5.12 not supported" + #endif + #if (TK_MAJOR_VERSION < 8) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION < 5)) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 5) && (TK_RELEASE_SERIAL < 12)) + # error "Tk older than 8.5.12 not supported" + #endif + +int +main (void) +{ + + Tcl_Init(NULL); + Tk_Init(NULL); + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + have_tcltk=yes + as_fn_append TCLTK_CFLAGS " -Wno-strict-prototypes -DWITH_APPINIT=1" + +else case e in #( + e) + have_tcltk=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + + + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $GDBM_CFLAGS" + LIBS="$LIBS $GDBM_LIBS" + for ac_header in gdbm.h +do : + ac_fn_c_check_header_compile "$LINENO" "gdbm.h" "ac_cv_header_gdbm_h" "$ac_includes_default" +if test "x$ac_cv_header_gdbm_h" = xyes +then : + printf "%s\n" "#define HAVE_GDBM_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gdbm_open in -lgdbm" >&5 +printf %s "checking for gdbm_open in -lgdbm... " >&6; } +if test ${ac_cv_lib_gdbm_gdbm_open+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lgdbm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char gdbm_open (void); +int +main (void) +{ +return gdbm_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_gdbm_gdbm_open=yes +else case e in #( + e) ac_cv_lib_gdbm_gdbm_open=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_gdbm_open" >&5 +printf "%s\n" "$ac_cv_lib_gdbm_gdbm_open" >&6; } +if test "x$ac_cv_lib_gdbm_gdbm_open" = xyes +then : + + have_gdbm=yes + GDBM_LIBS=${GDBM_LIBS-"-lgdbm"} + +else case e in #( + e) have_gdbm=no ;; +esac +fi + + +else case e in #( + e) have_gdbm=no ;; +esac +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + + for ac_header in ndbm.h +do : + ac_fn_c_check_header_compile "$LINENO" "ndbm.h" "ac_cv_header_ndbm_h" "$ac_includes_default" +if test "x$ac_cv_header_ndbm_h" = xyes +then : + printf "%s\n" "#define HAVE_NDBM_H 1" >>confdefs.h + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dbm_open" >&5 +printf %s "checking for library containing dbm_open... " >&6; } +if test ${ac_cv_search_dbm_open+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char dbm_open (void); +int +main (void) +{ +return dbm_open (); + ; + return 0; +} +_ACEOF +for ac_lib in '' ndbm gdbm_compat +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_dbm_open=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_dbm_open+y} +then : + break +fi +done +if test ${ac_cv_search_dbm_open+y} +then : + +else case e in #( + e) ac_cv_search_dbm_open=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dbm_open" >&5 +printf "%s\n" "$ac_cv_search_dbm_open" >&6; } +ac_res=$ac_cv_search_dbm_open +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi + +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ndbm presence and linker args" >&5 +printf %s "checking for ndbm presence and linker args... " >&6; } +case $ac_cv_search_dbm_open in #( + *ndbm*|*gdbm_compat*) : + + dbm_ndbm="$ac_cv_search_dbm_open" + have_ndbm=yes + ;; #( + none*) : + + dbm_ndbm="" + have_ndbm=yes + ;; #( + no) : + have_ndbm=no + ;; #( + *) : + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_ndbm ($dbm_ndbm)" >&5 +printf "%s\n" "$have_ndbm ($dbm_ndbm)" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gdbm/ndbm.h" >&5 +printf %s "checking for gdbm/ndbm.h... " >&6; } +if test ${ac_cv_header_gdbm_slash_ndbm_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <gdbm/ndbm.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + ac_cv_header_gdbm_slash_ndbm_h=yes +else case e in #( + e) ac_cv_header_gdbm_slash_ndbm_h=no ;; +esac +fi +rm -f conftest.err conftest.i conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_gdbm_slash_ndbm_h" >&5 +printf "%s\n" "$ac_cv_header_gdbm_slash_ndbm_h" >&6; } +if test "x$ac_cv_header_gdbm_slash_ndbm_h" = xyes +then : + + +printf "%s\n" "#define HAVE_GDBM_NDBM_H 1" >>confdefs.h + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gdbm-ndbm.h" >&5 +printf %s "checking for gdbm-ndbm.h... " >&6; } +if test ${ac_cv_header_gdbm_dash_ndbm_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <gdbm-ndbm.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + ac_cv_header_gdbm_dash_ndbm_h=yes +else case e in #( + e) ac_cv_header_gdbm_dash_ndbm_h=no ;; +esac +fi +rm -f conftest.err conftest.i conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_gdbm_dash_ndbm_h" >&5 +printf "%s\n" "$ac_cv_header_gdbm_dash_ndbm_h" >&6; } +if test "x$ac_cv_header_gdbm_dash_ndbm_h" = xyes +then : + + +printf "%s\n" "#define HAVE_GDBM_DASH_NDBM_H 1" >>confdefs.h + + +fi + +if test "$ac_cv_header_gdbm_slash_ndbm_h" = yes -o "$ac_cv_header_gdbm_dash_ndbm_h" = yes; then + { ac_cv_search_dbm_open=; unset ac_cv_search_dbm_open;} + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dbm_open" >&5 +printf %s "checking for library containing dbm_open... " >&6; } +if test ${ac_cv_search_dbm_open+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char dbm_open (void); +int +main (void) +{ +return dbm_open (); + ; + return 0; +} +_ACEOF +for ac_lib in '' gdbm_compat +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_dbm_open=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_dbm_open+y} +then : + break +fi +done +if test ${ac_cv_search_dbm_open+y} +then : + +else case e in #( + e) ac_cv_search_dbm_open=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dbm_open" >&5 +printf "%s\n" "$ac_cv_search_dbm_open" >&6; } +ac_res=$ac_cv_search_dbm_open +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + have_gdbm_compat=yes +else case e in #( + e) have_gdbm_compat=no ;; +esac +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + +fi + +# Check for libdb >= 5 with dbm_open() +# db.h re-defines the name of the function + for ac_header in db.h +do : + ac_fn_c_check_header_compile "$LINENO" "db.h" "ac_cv_header_db_h" "$ac_includes_default" +if test "x$ac_cv_header_db_h" = xyes +then : + printf "%s\n" "#define HAVE_DB_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libdb" >&5 +printf %s "checking for libdb... " >&6; } +if test ${ac_cv_have_libdb+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + LIBS="$LIBS -ldb" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define DB_DBM_HSEARCH 1 + #include <db.h> + #if DB_VERSION_MAJOR < 5 + #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." + #endif + +int +main (void) +{ +DBM *dbm = dbm_open(NULL, 0, 0) + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_have_libdb=yes +else case e in #( + e) ac_cv_have_libdb=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libdb" >&5 +printf "%s\n" "$ac_cv_have_libdb" >&6; } + if test "x$ac_cv_have_libdb" = xyes +then : + + +printf "%s\n" "#define HAVE_LIBDB 1" >>confdefs.h + + +fi + +fi + +done + +# Check for --with-dbmliborder +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-dbmliborder" >&5 +printf %s "checking for --with-dbmliborder... " >&6; } + +# Check whether --with-dbmliborder was given. +if test ${with_dbmliborder+y} +then : + withval=$with_dbmliborder; +else case e in #( + e) with_dbmliborder=gdbm:ndbm:bdb ;; +esac +fi + + +have_gdbm_dbmliborder=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case $db in #( + ndbm) : + ;; #( + gdbm) : + have_gdbm_dbmliborder=yes ;; #( + bdb) : + ;; #( + *) : + with_dbmliborder=error + ;; +esac +done +IFS=$as_save_IFS +if test "x$with_dbmliborder" = xerror +then : + + as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:... (gdbm:ndbm:bdb)" "$LINENO" 5 + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_dbmliborder" >&5 +printf "%s\n" "$with_dbmliborder" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _dbm module CFLAGS and LIBS" >&5 +printf %s "checking for _dbm module CFLAGS and LIBS... " >&6; } +have_dbm=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case "$db" in + ndbm) + if test "$have_ndbm" = yes; then + DBM_CFLAGS="-DUSE_NDBM" + DBM_LIBS="$dbm_ndbm" + have_dbm=yes + break + fi + ;; + gdbm) + if test "$have_gdbm_compat" = yes; then + DBM_CFLAGS="-DUSE_GDBM_COMPAT" + DBM_LIBS="-lgdbm_compat" + have_dbm=yes + break + fi + ;; + bdb) + if test "$ac_cv_have_libdb" = yes; then + DBM_CFLAGS="-DUSE_BERKDB" + DBM_LIBS="-ldb" + have_dbm=yes + break + fi + ;; + esac +done +IFS=$as_save_IFS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DBM_CFLAGS $DBM_LIBS" >&5 +printf "%s\n" "$DBM_CFLAGS $DBM_LIBS" >&6; } + +# Templates for things AC_DEFINEd more than once. +# For a single AC_DEFINE, no template is needed. + + +if test "$ac_cv_pthread_is_default" = yes +then + # Defining _REENTRANT on system with POSIX threads should not hurt. + printf "%s\n" "#define _REENTRANT 1" >>confdefs.h + + posix_threads=yes + if test "$ac_sys_system" = "SunOS"; then + CFLAGS="$CFLAGS -D_REENTRANT" + fi +elif test "$ac_cv_kpthread" = "yes" +then + CC="$CC -Kpthread" + if test "$ac_cv_cxx_thread" = "yes"; then + CXX="$CXX -Kpthread" + fi + posix_threads=yes +elif test "$ac_cv_kthread" = "yes" +then + CC="$CC -Kthread" + if test "$ac_cv_cxx_thread" = "yes"; then + CXX="$CXX -Kthread" + fi + posix_threads=yes +elif test "$ac_cv_pthread" = "yes" +then + CC="$CC -pthread" + if test "$ac_cv_cxx_thread" = "yes"; then + CXX="$CXX -pthread" + fi + posix_threads=yes +else + if test ! -z "$withval" -a -d "$withval" + then LDFLAGS="$LDFLAGS -L$withval" + fi + + # According to the POSIX spec, a pthreads implementation must + # define _POSIX_THREADS in unistd.h. Some apparently don't + # (e.g. gnu pth with pthread emulation) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _POSIX_THREADS in unistd.h" >&5 +printf %s "checking for _POSIX_THREADS in unistd.h... " >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _POSIX_THREADS defined in unistd.h" >&5 +printf %s "checking for _POSIX_THREADS defined in unistd.h... " >&6; } +if test ${ac_cv_defined__POSIX_THREADS_unistd_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ + + #ifdef _POSIX_THREADS + int ok; + (void)ok; + #else + choke me + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_defined__POSIX_THREADS_unistd_h=yes +else case e in #( + e) ac_cv_defined__POSIX_THREADS_unistd_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_defined__POSIX_THREADS_unistd_h" >&5 +printf "%s\n" "$ac_cv_defined__POSIX_THREADS_unistd_h" >&6; } +if test $ac_cv_defined__POSIX_THREADS_unistd_h != "no" +then : + unistd_defines_pthreads=yes +else case e in #( + e) unistd_defines_pthreads=no ;; +esac +fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $unistd_defines_pthreads" >&5 +printf "%s\n" "$unistd_defines_pthreads" >&6; } + + printf "%s\n" "#define _REENTRANT 1" >>confdefs.h + + # Just looking for pthread_create in libpthread is not enough: + # on HP/UX, pthread.h renames pthread_create to a different symbol name. + # So we really have to include pthread.h, and then link. + _libs=$LIBS + LIBS="$LIBS -lpthread" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +printf %s "checking for pthread_create in -lpthread... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> + +void * start_routine (void *arg) { exit (0); } +int +main (void) +{ + +pthread_create (NULL, NULL, start_routine, NULL) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + posix_threads=yes + +else case e in #( + e) + LIBS=$_libs + ac_fn_c_check_func "$LINENO" "pthread_detach" "ac_cv_func_pthread_detach" +if test "x$ac_cv_func_pthread_detach" = xyes +then : + + posix_threads=yes + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthreads" >&5 +printf %s "checking for pthread_create in -lpthreads... " >&6; } +if test ${ac_cv_lib_pthreads_pthread_create+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthreads $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (void); +int +main (void) +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_pthreads_pthread_create=yes +else case e in #( + e) ac_cv_lib_pthreads_pthread_create=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_pthreads_pthread_create" >&6; } +if test "x$ac_cv_lib_pthreads_pthread_create" = xyes +then : + + posix_threads=yes + LIBS="$LIBS -lpthreads" + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5 +printf %s "checking for pthread_create in -lc_r... " >&6; } +if test ${ac_cv_lib_c_r_pthread_create+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lc_r $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (void); +int +main (void) +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_c_r_pthread_create=yes +else case e in #( + e) ac_cv_lib_c_r_pthread_create=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_c_r_pthread_create" >&6; } +if test "x$ac_cv_lib_c_r_pthread_create" = xyes +then : + + posix_threads=yes + LIBS="$LIBS -lc_r" + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __pthread_create_system in -lpthread" >&5 +printf %s "checking for __pthread_create_system in -lpthread... " >&6; } +if test ${ac_cv_lib_pthread___pthread_create_system+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char __pthread_create_system (void); +int +main (void) +{ +return __pthread_create_system (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_pthread___pthread_create_system=yes +else case e in #( + e) ac_cv_lib_pthread___pthread_create_system=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_create_system" >&5 +printf "%s\n" "$ac_cv_lib_pthread___pthread_create_system" >&6; } +if test "x$ac_cv_lib_pthread___pthread_create_system" = xyes +then : + + posix_threads=yes + LIBS="$LIBS -lpthread" + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lcma" >&5 +printf %s "checking for pthread_create in -lcma... " >&6; } +if test ${ac_cv_lib_cma_pthread_create+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lcma $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (void); +int +main (void) +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_cma_pthread_create=yes +else case e in #( + e) ac_cv_lib_cma_pthread_create=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cma_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_cma_pthread_create" >&6; } +if test "x$ac_cv_lib_cma_pthread_create" = xyes +then : + + posix_threads=yes + LIBS="$LIBS -lcma" + +else case e in #( + e) + case $ac_sys_system in #( + WASI) : + posix_threads=stub ;; #( + *) : + as_fn_error $? "could not find pthreads on your system" "$LINENO" 5 + ;; +esac + ;; +esac +fi + ;; +esac +fi + ;; +esac +fi + ;; +esac +fi + ;; +esac +fi + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for usconfig in -lmpc" >&5 +printf %s "checking for usconfig in -lmpc... " >&6; } +if test ${ac_cv_lib_mpc_usconfig+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lmpc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char usconfig (void); +int +main (void) +{ +return usconfig (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_mpc_usconfig=yes +else case e in #( + e) ac_cv_lib_mpc_usconfig=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpc_usconfig" >&5 +printf "%s\n" "$ac_cv_lib_mpc_usconfig" >&6; } +if test "x$ac_cv_lib_mpc_usconfig" = xyes +then : + + LIBS="$LIBS -lmpc" + +fi + + +fi + +if test "$posix_threads" = "yes"; then + if test "$unistd_defines_pthreads" = "no"; then + +printf "%s\n" "#define _POSIX_THREADS 1" >>confdefs.h + + fi + + # Bug 662787: Using semaphores causes unexplicable hangs on Solaris 8. + case $ac_sys_system/$ac_sys_release in + SunOS/5.6) +printf "%s\n" "#define HAVE_PTHREAD_DESTRUCTOR 1" >>confdefs.h + + ;; + SunOS/5.8) +printf "%s\n" "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h + + ;; + AIX/*) +printf "%s\n" "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h + + ;; + NetBSD/*) +printf "%s\n" "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h + + ;; + esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if PTHREAD_SCOPE_SYSTEM is supported" >&5 +printf %s "checking if PTHREAD_SCOPE_SYSTEM is supported... " >&6; } +if test ${ac_cv_pthread_system_supported+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_pthread_system_supported=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> + #include <pthread.h> + void *foo(void *parm) { + return NULL; + } + int main(void) { + pthread_attr_t attr; + pthread_t id; + if (pthread_attr_init(&attr)) return (-1); + if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) return (-1); + if (pthread_create(&id, &attr, foo, NULL)) return (-1); + if (pthread_join(id, NULL)) return (-1); + return (0); + } +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_pthread_system_supported=yes +else case e in #( + e) ac_cv_pthread_system_supported=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_system_supported" >&5 +printf "%s\n" "$ac_cv_pthread_system_supported" >&6; } + if test "$ac_cv_pthread_system_supported" = "yes"; then + +printf "%s\n" "#define PTHREAD_SYSTEM_SCHED_SUPPORTED 1" >>confdefs.h + + fi + + for ac_func in pthread_sigmask +do : + ac_fn_c_check_func "$LINENO" "pthread_sigmask" "ac_cv_func_pthread_sigmask" +if test "x$ac_cv_func_pthread_sigmask" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_SIGMASK 1" >>confdefs.h + case $ac_sys_system in + CYGWIN*) + +printf "%s\n" "#define HAVE_BROKEN_PTHREAD_SIGMASK 1" >>confdefs.h + + ;; + esac +fi + +done + ac_fn_c_check_func "$LINENO" "pthread_getcpuclockid" "ac_cv_func_pthread_getcpuclockid" +if test "x$ac_cv_func_pthread_getcpuclockid" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_GETCPUCLOCKID 1" >>confdefs.h + +fi + +fi + +if test "x$posix_threads" = xstub +then : + + +printf "%s\n" "#define HAVE_PTHREAD_STUBS 1" >>confdefs.h + + +fi + +# Check for enable-ipv6 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if --enable-ipv6 is specified" >&5 +printf %s "checking if --enable-ipv6 is specified... " >&6; } +# Check whether --enable-ipv6 was given. +if test ${enable_ipv6+y} +then : + enableval=$enable_ipv6; case "$enableval" in + no) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ipv6=no + ;; + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + printf "%s\n" "#define ENABLE_IPV6 1" >>confdefs.h + + ipv6=yes + ;; + esac +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + /* AF_INET6 available check */ +#include <sys/types.h> +#include <sys/socket.h> +int +main (void) +{ +int domain = AF_INET6; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + ipv6=yes + +else case e in #( + e) + ipv6=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +case $ac_sys_system in #( + WASI) : + ipv6=no + ;; #( + *) : + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ipv6" >&5 +printf "%s\n" "$ipv6" >&6; } + +if test "$ipv6" = "yes"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if RFC2553 API is available" >&5 +printf %s "checking if RFC2553 API is available... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <sys/types.h> +#include <netinet/in.h> +int +main (void) +{ +struct sockaddr_in6 x; + x.sin6_scope_id; + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + ipv6=yes + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ipv6=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +if test "$ipv6" = "yes"; then + printf "%s\n" "#define ENABLE_IPV6 1" >>confdefs.h + +fi + ;; +esac +fi + + +ipv6type=unknown +ipv6lib=none +ipv6trylibc=no + +if test "$ipv6" = yes -a "$cross_compiling" = no; then + for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta; + do + case $i in + inria) + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for IPV6_INRIA_VERSION defined in netinet/in.h" >&5 +printf %s "checking for IPV6_INRIA_VERSION defined in netinet/in.h... " >&6; } +if test ${ac_cv_defined_IPV6_INRIA_VERSION_netinet_in_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netinet/in.h> +int +main (void) +{ + + #ifdef IPV6_INRIA_VERSION + int ok; + (void)ok; + #else + choke me + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_defined_IPV6_INRIA_VERSION_netinet_in_h=yes +else case e in #( + e) ac_cv_defined_IPV6_INRIA_VERSION_netinet_in_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_defined_IPV6_INRIA_VERSION_netinet_in_h" >&5 +printf "%s\n" "$ac_cv_defined_IPV6_INRIA_VERSION_netinet_in_h" >&6; } +if test $ac_cv_defined_IPV6_INRIA_VERSION_netinet_in_h != "no" +then : + ipv6type=$i +fi + ;; + kame) + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __KAME__ defined in netinet/in.h" >&5 +printf %s "checking for __KAME__ defined in netinet/in.h... " >&6; } +if test ${ac_cv_defined___KAME___netinet_in_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netinet/in.h> +int +main (void) +{ + + #ifdef __KAME__ + int ok; + (void)ok; + #else + choke me + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_defined___KAME___netinet_in_h=yes +else case e in #( + e) ac_cv_defined___KAME___netinet_in_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_defined___KAME___netinet_in_h" >&5 +printf "%s\n" "$ac_cv_defined___KAME___netinet_in_h" >&6; } +if test $ac_cv_defined___KAME___netinet_in_h != "no" +then : + ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/local/v6/lib + ipv6trylibc=yes +fi + ;; + linux-glibc) + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __GLIBC__ defined in features.h" >&5 +printf %s "checking for __GLIBC__ defined in features.h... " >&6; } +if test ${ac_cv_defined___GLIBC___features_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <features.h> +int +main (void) +{ + + #ifdef __GLIBC__ + int ok; + (void)ok; + #else + choke me + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_defined___GLIBC___features_h=yes +else case e in #( + e) ac_cv_defined___GLIBC___features_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_defined___GLIBC___features_h" >&5 +printf "%s\n" "$ac_cv_defined___GLIBC___features_h" >&6; } +if test $ac_cv_defined___GLIBC___features_h != "no" +then : + ipv6type=$i + ipv6trylibc=yes +fi + ;; + linux-inet6) + if test -d /usr/inet6; then + ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/inet6/lib + BASECFLAGS="-I/usr/inet6/include $BASECFLAGS" + fi + ;; + solaris) + if test -f /etc/netconfig; then + if $GREP -q tcp6 /etc/netconfig; then + ipv6type=$i + ipv6trylibc=yes + fi + fi + ;; + toshiba) + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _TOSHIBA_INET6 defined in sys/param.h" >&5 +printf %s "checking for _TOSHIBA_INET6 defined in sys/param.h... " >&6; } +if test ${ac_cv_defined__TOSHIBA_INET6_sys_param_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/param.h> +int +main (void) +{ + + #ifdef _TOSHIBA_INET6 + int ok; + (void)ok; + #else + choke me + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_defined__TOSHIBA_INET6_sys_param_h=yes +else case e in #( + e) ac_cv_defined__TOSHIBA_INET6_sys_param_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_defined__TOSHIBA_INET6_sys_param_h" >&5 +printf "%s\n" "$ac_cv_defined__TOSHIBA_INET6_sys_param_h" >&6; } +if test $ac_cv_defined__TOSHIBA_INET6_sys_param_h != "no" +then : + ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/local/v6/lib +fi + ;; + v6d) + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __V6D__ defined in /usr/local/v6/include/sys/v6config.h" >&5 +printf %s "checking for __V6D__ defined in /usr/local/v6/include/sys/v6config.h... " >&6; } +if test ${ac_cv_defined___V6D____usr_local_v6_include_sys_v6config_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include </usr/local/v6/include/sys/v6config.h> +int +main (void) +{ + + #ifdef __V6D__ + int ok; + (void)ok; + #else + choke me + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_defined___V6D____usr_local_v6_include_sys_v6config_h=yes +else case e in #( + e) ac_cv_defined___V6D____usr_local_v6_include_sys_v6config_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_defined___V6D____usr_local_v6_include_sys_v6config_h" >&5 +printf "%s\n" "$ac_cv_defined___V6D____usr_local_v6_include_sys_v6config_h" >&6; } +if test $ac_cv_defined___V6D____usr_local_v6_include_sys_v6config_h != "no" +then : + ipv6type=$i + ipv6lib=v6 + ipv6libdir=/usr/local/v6/lib + BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" +fi + ;; + zeta) + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _ZETA_MINAMI_INET6 defined in sys/param.h" >&5 +printf %s "checking for _ZETA_MINAMI_INET6 defined in sys/param.h... " >&6; } +if test ${ac_cv_defined__ZETA_MINAMI_INET6_sys_param_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/param.h> +int +main (void) +{ + + #ifdef _ZETA_MINAMI_INET6 + int ok; + (void)ok; + #else + choke me + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_defined__ZETA_MINAMI_INET6_sys_param_h=yes +else case e in #( + e) ac_cv_defined__ZETA_MINAMI_INET6_sys_param_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_defined__ZETA_MINAMI_INET6_sys_param_h" >&5 +printf "%s\n" "$ac_cv_defined__ZETA_MINAMI_INET6_sys_param_h" >&6; } +if test $ac_cv_defined__ZETA_MINAMI_INET6_sys_param_h != "no" +then : + ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/local/v6/lib +fi + ;; + esac + if test "$ipv6type" != "unknown"; then + break + fi + done + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ipv6 stack type" >&5 +printf %s "checking ipv6 stack type... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ipv6type" >&5 +printf "%s\n" "$ipv6type" >&6; } +fi + +if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ipv6 library" >&5 +printf %s "checking ipv6 library... " >&6; } + if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then + LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: lib$ipv6lib" >&5 +printf "%s\n" "lib$ipv6lib" >&6; } + else + if test "x$ipv6trylibc" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: libc" >&5 +printf "%s\n" "libc" >&6; } + +else case e in #( + e) + as_fn_error $? "No $ipv6lib library found; cannot continue. You need to fetch lib$ipv6lib.a from appropriate ipv6 kit and compile beforehand." "$LINENO" 5 + ;; +esac +fi + fi +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CAN_RAW_FD_FRAMES" >&5 +printf %s "checking CAN_RAW_FD_FRAMES... " >&6; } +if test ${ac_cv_can_raw_fd_frames+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + /* CAN_RAW_FD_FRAMES available check */ +#include <linux/can/raw.h> +int +main (void) +{ +int can_raw_fd_frames = CAN_RAW_FD_FRAMES; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_can_raw_fd_frames=yes +else case e in #( + e) ac_cv_can_raw_fd_frames=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_can_raw_fd_frames" >&5 +printf "%s\n" "$ac_cv_can_raw_fd_frames" >&6; } +if test "x$ac_cv_can_raw_fd_frames" = xyes +then : + + +printf "%s\n" "#define HAVE_LINUX_CAN_RAW_FD_FRAMES 1" >>confdefs.h + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CAN_RAW_JOIN_FILTERS" >&5 +printf %s "checking for CAN_RAW_JOIN_FILTERS... " >&6; } +if test ${ac_cv_can_raw_join_filters+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <linux/can/raw.h> +int +main (void) +{ +int can_raw_join_filters = CAN_RAW_JOIN_FILTERS; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_can_raw_join_filters=yes +else case e in #( + e) ac_cv_can_raw_join_filters=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_can_raw_join_filters" >&5 +printf "%s\n" "$ac_cv_can_raw_join_filters" >&6; } +if test "x$ac_cv_can_raw_join_filters" = xyes +then : + + +printf "%s\n" "#define HAVE_LINUX_CAN_RAW_JOIN_FILTERS 1" >>confdefs.h + + +fi + +# Check for --with-doc-strings +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-doc-strings" >&5 +printf %s "checking for --with-doc-strings... " >&6; } + +# Check whether --with-doc-strings was given. +if test ${with_doc_strings+y} +then : + withval=$with_doc_strings; +fi + + +if test -z "$with_doc_strings" +then with_doc_strings="yes" +fi +if test "$with_doc_strings" != "no" +then + +printf "%s\n" "#define WITH_DOC_STRINGS 1" >>confdefs.h + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_doc_strings" >&5 +printf "%s\n" "$with_doc_strings" >&6; } + +# Check for stdatomic.h, required for mimalloc. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdatomic.h" >&5 +printf %s "checking for stdatomic.h... " >&6; } +if test ${ac_cv_header_stdatomic_h+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <stdatomic.h> + atomic_int int_var; + atomic_uintptr_t uintptr_var; + int main() { + atomic_store_explicit(&int_var, 5, memory_order_relaxed); + atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); + int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); + return 0; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_header_stdatomic_h=yes +else case e in #( + e) ac_cv_header_stdatomic_h=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdatomic_h" >&5 +printf "%s\n" "$ac_cv_header_stdatomic_h" >&6; } + +if test "x$ac_cv_header_stdatomic_h" = xyes +then : + + +printf "%s\n" "#define HAVE_STD_ATOMIC 1" >>confdefs.h + + +fi + +# Check for GCC >= 4.7 and clang __atomic builtin functions +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for builtin __atomic_load_n and __atomic_store_n functions" >&5 +printf %s "checking for builtin __atomic_load_n and __atomic_store_n functions... " >&6; } +if test ${ac_cv_builtin_atomic+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + int val; + int main() { + __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); + (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); + return 0; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_builtin_atomic=yes +else case e in #( + e) ac_cv_builtin_atomic=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_builtin_atomic" >&5 +printf "%s\n" "$ac_cv_builtin_atomic" >&6; } + +if test "x$ac_cv_builtin_atomic" = xyes +then : + + +printf "%s\n" "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h + + +fi + +# Check for __builtin_shufflevector with 128-bit vector support on an +# architecture where it compiles to worthwhile native SIMD instructions. +# Used for SIMD-accelerated bytes.hex() in Python/pystrhex.c. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __builtin_shufflevector" >&5 +printf %s "checking for __builtin_shufflevector... " >&6; } +if test ${ac_cv_efficient_builtin_shufflevector+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + /* __builtin_shufflevector is available on many platforms, but 128-bit + vector code is only worthwhile on architectures with native SIMD: + x86-64 (SSE2, always available), ARM64 (NEON, always available), + or ARM32 when NEON is enabled via compiler flags (e.g. -march=native + on RPi3+). On ARM32 without NEON (e.g. armv6 builds), the compiler + has the builtin but generates slow scalar code instead. */ + #if !defined(__x86_64__) && !defined(__aarch64__) && \ + !(defined(__arm__) && defined(__ARM_NEON)) + # error "128-bit vector SIMD not worthwhile on this architecture" + #endif + typedef unsigned char v16u8 __attribute__((vector_size(16))); + +int +main (void) +{ + + v16u8 a = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + v16u8 b = {16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + v16u8 c = __builtin_shufflevector(a, b, + 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23); + (void)c; + return 0; + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_efficient_builtin_shufflevector=yes +else case e in #( + e) ac_cv_efficient_builtin_shufflevector=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_efficient_builtin_shufflevector" >&5 +printf "%s\n" "$ac_cv_efficient_builtin_shufflevector" >&6; } + +if test "x$ac_cv_efficient_builtin_shufflevector" = xyes +then : + + +printf "%s\n" "#define _Py_HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR 1" >>confdefs.h + + +fi + +# --with-mimalloc +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-mimalloc" >&5 +printf %s "checking for --with-mimalloc... " >&6; } + +# Check whether --with-mimalloc was given. +if test ${with_mimalloc+y} +then : + withval=$with_mimalloc; +else case e in #( + e) with_mimalloc="$ac_cv_header_stdatomic_h" + ;; +esac +fi + + +if test "$with_mimalloc" != no; then + if test "$ac_cv_header_stdatomic_h" != yes; then + # mimalloc-atomic.h wants C11 stdatomic.h on POSIX + as_fn_error $? "mimalloc requires stdatomic.h, use --without-mimalloc to disable mimalloc." "$LINENO" 5 + fi + with_mimalloc=yes + +printf "%s\n" "#define WITH_MIMALLOC 1" >>confdefs.h + + MIMALLOC_HEADERS='$(MIMALLOC_HEADERS)' + +elif test "$disable_gil" = "yes"; then + as_fn_error $? "--disable-gil requires mimalloc memory allocator (--with-mimalloc)." "$LINENO" 5 +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_mimalloc" >&5 +printf "%s\n" "$with_mimalloc" >&6; } +INSTALL_MIMALLOC=$with_mimalloc + + + +# Check for Python-specific malloc support +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-pymalloc" >&5 +printf %s "checking for --with-pymalloc... " >&6; } + +# Check whether --with-pymalloc was given. +if test ${with_pymalloc+y} +then : + withval=$with_pymalloc; +fi + + +if test -z "$with_pymalloc" +then + case $ac_sys_system in #( + Emscripten) : + with_pymalloc="no" ;; #( + WASI) : + with_pymalloc="no" ;; #( + *) : + with_pymalloc="yes" + ;; +esac +fi +if test "$with_pymalloc" != "no" +then + +printf "%s\n" "#define WITH_PYMALLOC 1" >>confdefs.h + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_pymalloc" >&5 +printf "%s\n" "$with_pymalloc" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-pymalloc-hugepages" >&5 +printf %s "checking for --with-pymalloc-hugepages... " >&6; } + +# Check whether --with-pymalloc-hugepages was given. +if test ${with_pymalloc_hugepages+y} +then : + withval=$with_pymalloc_hugepages; +fi + +if test "$with_pymalloc_hugepages" = "yes" +then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/mman.h> + +int +main (void) +{ + +int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB; +(void)flags; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +printf "%s\n" "#define PYMALLOC_USE_HUGEPAGES 1" >>confdefs.h + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --with-pymalloc-hugepages requested but MAP_HUGETLB not found" >&5 +printf "%s\n" "$as_me: WARNING: --with-pymalloc-hugepages requested but MAP_HUGETLB not found" >&2;} + with_pymalloc_hugepages=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${with_pymalloc_hugepages:-no}" >&5 +printf "%s\n" "${with_pymalloc_hugepages:-no}" >&6; } + +# Check for --with-c-locale-coercion +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-c-locale-coercion" >&5 +printf %s "checking for --with-c-locale-coercion... " >&6; } + +# Check whether --with-c-locale-coercion was given. +if test ${with_c_locale_coercion+y} +then : + withval=$with_c_locale_coercion; +fi + + +if test -z "$with_c_locale_coercion" +then + with_c_locale_coercion="yes" +fi +if test "$with_c_locale_coercion" != "no" +then + +printf "%s\n" "#define PY_COERCE_C_LOCALE 1" >>confdefs.h + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_c_locale_coercion" >&5 +printf "%s\n" "$with_c_locale_coercion" >&6; } + +# Check for Valgrind support +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-valgrind" >&5 +printf %s "checking for --with-valgrind... " >&6; } + +# Check whether --with-valgrind was given. +if test ${with_valgrind+y} +then : + withval=$with_valgrind; +else case e in #( + e) with_valgrind=no + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_valgrind" >&5 +printf "%s\n" "$with_valgrind" >&6; } +if test "$with_valgrind" != no; then + ac_fn_c_check_header_compile "$LINENO" "valgrind/valgrind.h" "ac_cv_header_valgrind_valgrind_h" "$ac_includes_default" +if test "x$ac_cv_header_valgrind_valgrind_h" = xyes +then : + +printf "%s\n" "#define WITH_VALGRIND 1" >>confdefs.h + +else case e in #( + e) as_fn_error $? "Valgrind support requested but headers not available" "$LINENO" 5 + ;; +esac +fi + + OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT" +fi + +# Check for DTrace support +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-dtrace" >&5 +printf %s "checking for --with-dtrace... " >&6; } + +# Check whether --with-dtrace was given. +if test ${with_dtrace+y} +then : + withval=$with_dtrace; +else case e in #( + e) with_dtrace=no ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_dtrace" >&5 +printf "%s\n" "$with_dtrace" >&6; } + + + + + +DTRACE= +DTRACE_HEADERS= +DTRACE_OBJS= + +if test "$with_dtrace" = "yes" +then + # Extract the first word of "dtrace", so it can be a program name with args. +set dummy dtrace; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_DTRACE+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) case $DTRACE in + [\\/]* | ?:[\\/]*) + ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_DTRACE="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_DTRACE" && ac_cv_path_DTRACE="not found" + ;; +esac ;; +esac +fi +DTRACE=$ac_cv_path_DTRACE +if test -n "$DTRACE"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5 +printf "%s\n" "$DTRACE" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + if test "$DTRACE" = "not found"; then + as_fn_error $? "dtrace command not found on \$PATH" "$LINENO" 5 + fi + +printf "%s\n" "#define WITH_DTRACE 1" >>confdefs.h + + DTRACE_HEADERS="Include/pydtrace_probes.h" + + # On OS X, DTrace providers do not need to be explicitly compiled and + # linked into the binary. Correspondingly, dtrace(1) is missing the ELF + # generation flag '-G'. We check for presence of this flag, rather than + # hardcoding support by OS, in the interest of robustness. + # + # NetBSD DTrace requires the -x nolibs flag to avoid system library conflicts + # and uses header generation for testing instead of object generation. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether DTrace probes require linking" >&5 +printf %s "checking whether DTrace probes require linking... " >&6; } +if test ${ac_cv_dtrace_link+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ac_cv_dtrace_link=no + echo 'BEGIN{}' > conftest.d + case $host in + *netbsd*) + DTRACE_TEST_FLAGS="-x nolibs -h" + ;; + *) + DTRACE_TEST_FLAGS="-G" + ;; + esac + "$DTRACE" $DFLAGS $DTRACE_TEST_FLAGS -s conftest.d -o conftest.o > /dev/null 2>&1 && \ + ac_cv_dtrace_link=yes + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dtrace_link" >&5 +printf "%s\n" "$ac_cv_dtrace_link" >&6; } + if test "$ac_cv_dtrace_link" = "yes"; then + DTRACE_OBJS="Python/pydtrace.o" + fi + # Set NetBSD-specific DTrace flags in DFLAGS + case $host in + *netbsd*) + DFLAGS="$DFLAGS -x nolibs" + ;; + esac +fi + +PLATFORM_HEADERS= +PLATFORM_OBJS= + +case $ac_sys_system in #( + Emscripten) : + + as_fn_append PLATFORM_OBJS ' Python/emscripten_signal.o Python/emscripten_trampoline.o Python/emscripten_trampoline_wasm.o' + if test "x$enable_emscripten_syscalls" = xyes +then : + + as_fn_append PLATFORM_OBJS ' Python/emscripten_syscalls.o' + +fi + as_fn_append PLATFORM_HEADERS ' $(srcdir)/Include/internal/pycore_emscripten_signal.h $(srcdir)/Include/internal/pycore_emscripten_trampoline.h' + ;; #( + *) : + ;; +esac + + + +# -I${DLINCLDIR} is added to the compile rule for importdl.o + +DLINCLDIR=. + +# the dlopen() function means we might want to use dynload_shlib.o. some +# platforms have dlopen(), but don't want to use it. +ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes +then : + printf "%s\n" "#define HAVE_DLOPEN 1" >>confdefs.h + +fi + + +# Used by ctypes.util.dllist(). +ac_fn_c_check_func "$LINENO" "dl_iterate_phdr" "ac_cv_func_dl_iterate_phdr" +if test "x$ac_cv_func_dl_iterate_phdr" = xyes +then : + printf "%s\n" "#define HAVE_DL_ITERATE_PHDR 1" >>confdefs.h + +fi + + +# DYNLOADFILE specifies which dynload_*.o file we will use for dynamic +# loading of modules. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking DYNLOADFILE" >&5 +printf %s "checking DYNLOADFILE... " >&6; } +if test -z "$DYNLOADFILE" +then + case $ac_sys_system/$ac_sys_release in + hp*|HP*) DYNLOADFILE="dynload_hpux.o";; + *) + # use dynload_shlib.c and dlopen() if we have it; otherwise stub + # out any dynamic loading + if test "$ac_cv_func_dlopen" = yes + then DYNLOADFILE="dynload_shlib.o" + else DYNLOADFILE="dynload_stub.o" + fi + ;; + esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DYNLOADFILE" >&5 +printf "%s\n" "$DYNLOADFILE" >&6; } +if test "$DYNLOADFILE" != "dynload_stub.o" +then + +printf "%s\n" "#define HAVE_DYNAMIC_LOADING 1" >>confdefs.h + +fi + +# MACHDEP_OBJS can be set to platform-specific object files needed by Python + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking MACHDEP_OBJS" >&5 +printf %s "checking MACHDEP_OBJS... " >&6; } +if test -z "$MACHDEP_OBJS" +then + MACHDEP_OBJS=$extra_machdep_objs +else + MACHDEP_OBJS="$MACHDEP_OBJS $extra_machdep_objs" +fi +if test -z "$MACHDEP_OBJS"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MACHDEP_OBJS" >&5 +printf "%s\n" "$MACHDEP_OBJS" >&6; } +fi + +if test "$ac_sys_system" = "Linux-android"; then + # When these functions are used in an unprivileged process, they crash rather + # than returning an error. + blocked_funcs="chroot initgroups setegid seteuid setgid sethostname + setregid setresgid setresuid setreuid setuid" + + # These functions are unimplemented and always return an error + # (https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android13-release/public/domain.te#1044) + blocked_funcs="$blocked_funcs sem_open sem_unlink" + + # Before API level 23, when fchmodat is called with the unimplemented flag + # AT_SYMLINK_NOFOLLOW, instead of returning ENOTSUP as it should, it actually + # follows the symlink. + if test "$ANDROID_API_LEVEL" -lt 23; then + blocked_funcs="$blocked_funcs fchmodat" + fi + + for name in $blocked_funcs; do + as_func_var=`printf "%s\n" "ac_cv_func_$name" | sed "$as_sed_sh"` + + eval "$as_func_var=no" + + done +fi + +# checks for library functions +ac_fn_c_check_func "$LINENO" "accept4" "ac_cv_func_accept4" +if test "x$ac_cv_func_accept4" = xyes +then : + printf "%s\n" "#define HAVE_ACCEPT4 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "alarm" "ac_cv_func_alarm" +if test "x$ac_cv_func_alarm" = xyes +then : + printf "%s\n" "#define HAVE_ALARM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset" +if test "x$ac_cv_func_bind_textdomain_codeset" = xyes +then : + printf "%s\n" "#define HAVE_BIND_TEXTDOMAIN_CODESET 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "chmod" "ac_cv_func_chmod" +if test "x$ac_cv_func_chmod" = xyes +then : + printf "%s\n" "#define HAVE_CHMOD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "chown" "ac_cv_func_chown" +if test "x$ac_cv_func_chown" = xyes +then : + printf "%s\n" "#define HAVE_CHOWN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "clearenv" "ac_cv_func_clearenv" +if test "x$ac_cv_func_clearenv" = xyes +then : + printf "%s\n" "#define HAVE_CLEARENV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "clock" "ac_cv_func_clock" +if test "x$ac_cv_func_clock" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "closefrom" "ac_cv_func_closefrom" +if test "x$ac_cv_func_closefrom" = xyes +then : + printf "%s\n" "#define HAVE_CLOSEFROM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "close_range" "ac_cv_func_close_range" +if test "x$ac_cv_func_close_range" = xyes +then : + printf "%s\n" "#define HAVE_CLOSE_RANGE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "confstr" "ac_cv_func_confstr" +if test "x$ac_cv_func_confstr" = xyes +then : + printf "%s\n" "#define HAVE_CONFSTR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "copy_file_range" "ac_cv_func_copy_file_range" +if test "x$ac_cv_func_copy_file_range" = xyes +then : + printf "%s\n" "#define HAVE_COPY_FILE_RANGE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ctermid" "ac_cv_func_ctermid" +if test "x$ac_cv_func_ctermid" = xyes +then : + printf "%s\n" "#define HAVE_CTERMID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "dladdr" "ac_cv_func_dladdr" +if test "x$ac_cv_func_dladdr" = xyes +then : + printf "%s\n" "#define HAVE_DLADDR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "dup" "ac_cv_func_dup" +if test "x$ac_cv_func_dup" = xyes +then : + printf "%s\n" "#define HAVE_DUP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "execv" "ac_cv_func_execv" +if test "x$ac_cv_func_execv" = xyes +then : + printf "%s\n" "#define HAVE_EXECV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero" +if test "x$ac_cv_func_explicit_bzero" = xyes +then : + printf "%s\n" "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "explicit_memset" "ac_cv_func_explicit_memset" +if test "x$ac_cv_func_explicit_memset" = xyes +then : + printf "%s\n" "#define HAVE_EXPLICIT_MEMSET 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "faccessat" "ac_cv_func_faccessat" +if test "x$ac_cv_func_faccessat" = xyes +then : + printf "%s\n" "#define HAVE_FACCESSAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fchmod" "ac_cv_func_fchmod" +if test "x$ac_cv_func_fchmod" = xyes +then : + printf "%s\n" "#define HAVE_FCHMOD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fchmodat" "ac_cv_func_fchmodat" +if test "x$ac_cv_func_fchmodat" = xyes +then : + printf "%s\n" "#define HAVE_FCHMODAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fchown" "ac_cv_func_fchown" +if test "x$ac_cv_func_fchown" = xyes +then : + printf "%s\n" "#define HAVE_FCHOWN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fchownat" "ac_cv_func_fchownat" +if test "x$ac_cv_func_fchownat" = xyes +then : + printf "%s\n" "#define HAVE_FCHOWNAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fdopendir" "ac_cv_func_fdopendir" +if test "x$ac_cv_func_fdopendir" = xyes +then : + printf "%s\n" "#define HAVE_FDOPENDIR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fdwalk" "ac_cv_func_fdwalk" +if test "x$ac_cv_func_fdwalk" = xyes +then : + printf "%s\n" "#define HAVE_FDWALK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fexecve" "ac_cv_func_fexecve" +if test "x$ac_cv_func_fexecve" = xyes +then : + printf "%s\n" "#define HAVE_FEXECVE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fork" "ac_cv_func_fork" +if test "x$ac_cv_func_fork" = xyes +then : + printf "%s\n" "#define HAVE_FORK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fork1" "ac_cv_func_fork1" +if test "x$ac_cv_func_fork1" = xyes +then : + printf "%s\n" "#define HAVE_FORK1 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fpathconf" "ac_cv_func_fpathconf" +if test "x$ac_cv_func_fpathconf" = xyes +then : + printf "%s\n" "#define HAVE_FPATHCONF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fstatat" "ac_cv_func_fstatat" +if test "x$ac_cv_func_fstatat" = xyes +then : + printf "%s\n" "#define HAVE_FSTATAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ftime" "ac_cv_func_ftime" +if test "x$ac_cv_func_ftime" = xyes +then : + printf "%s\n" "#define HAVE_FTIME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ftruncate" "ac_cv_func_ftruncate" +if test "x$ac_cv_func_ftruncate" = xyes +then : + printf "%s\n" "#define HAVE_FTRUNCATE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "futimens" "ac_cv_func_futimens" +if test "x$ac_cv_func_futimens" = xyes +then : + printf "%s\n" "#define HAVE_FUTIMENS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "futimes" "ac_cv_func_futimes" +if test "x$ac_cv_func_futimes" = xyes +then : + printf "%s\n" "#define HAVE_FUTIMES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "futimesat" "ac_cv_func_futimesat" +if test "x$ac_cv_func_futimesat" = xyes +then : + printf "%s\n" "#define HAVE_FUTIMESAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "gai_strerror" "ac_cv_func_gai_strerror" +if test "x$ac_cv_func_gai_strerror" = xyes +then : + printf "%s\n" "#define HAVE_GAI_STRERROR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getdents64" "ac_cv_func_getdents64" +if test "x$ac_cv_func_getdents64" = xyes +then : + printf "%s\n" "#define HAVE_GETDENTS64 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getegid" "ac_cv_func_getegid" +if test "x$ac_cv_func_getegid" = xyes +then : + printf "%s\n" "#define HAVE_GETEGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "geteuid" "ac_cv_func_geteuid" +if test "x$ac_cv_func_geteuid" = xyes +then : + printf "%s\n" "#define HAVE_GETEUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getgid" "ac_cv_func_getgid" +if test "x$ac_cv_func_getgid" = xyes +then : + printf "%s\n" "#define HAVE_GETGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getgrent" "ac_cv_func_getgrent" +if test "x$ac_cv_func_getgrent" = xyes +then : + printf "%s\n" "#define HAVE_GETGRENT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getgrgid" "ac_cv_func_getgrgid" +if test "x$ac_cv_func_getgrgid" = xyes +then : + printf "%s\n" "#define HAVE_GETGRGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getgrgid_r" "ac_cv_func_getgrgid_r" +if test "x$ac_cv_func_getgrgid_r" = xyes +then : + printf "%s\n" "#define HAVE_GETGRGID_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getgrnam_r" "ac_cv_func_getgrnam_r" +if test "x$ac_cv_func_getgrnam_r" = xyes +then : + printf "%s\n" "#define HAVE_GETGRNAM_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist" +if test "x$ac_cv_func_getgrouplist" = xyes +then : + printf "%s\n" "#define HAVE_GETGROUPLIST 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "gethostname" "ac_cv_func_gethostname" +if test "x$ac_cv_func_gethostname" = xyes +then : + printf "%s\n" "#define HAVE_GETHOSTNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getitimer" "ac_cv_func_getitimer" +if test "x$ac_cv_func_getitimer" = xyes +then : + printf "%s\n" "#define HAVE_GETITIMER 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getloadavg" "ac_cv_func_getloadavg" +if test "x$ac_cv_func_getloadavg" = xyes +then : + printf "%s\n" "#define HAVE_GETLOADAVG 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getlogin" "ac_cv_func_getlogin" +if test "x$ac_cv_func_getlogin" = xyes +then : + printf "%s\n" "#define HAVE_GETLOGIN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getlogin_r" "ac_cv_func_getlogin_r" +if test "x$ac_cv_func_getlogin_r" = xyes +then : + printf "%s\n" "#define HAVE_GETLOGIN_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpeername" "ac_cv_func_getpeername" +if test "x$ac_cv_func_getpeername" = xyes +then : + printf "%s\n" "#define HAVE_GETPEERNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpgid" "ac_cv_func_getpgid" +if test "x$ac_cv_func_getpgid" = xyes +then : + printf "%s\n" "#define HAVE_GETPGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpid" "ac_cv_func_getpid" +if test "x$ac_cv_func_getpid" = xyes +then : + printf "%s\n" "#define HAVE_GETPID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getppid" "ac_cv_func_getppid" +if test "x$ac_cv_func_getppid" = xyes +then : + printf "%s\n" "#define HAVE_GETPPID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpriority" "ac_cv_func_getpriority" +if test "x$ac_cv_func_getpriority" = xyes +then : + printf "%s\n" "#define HAVE_GETPRIORITY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_getpty" "ac_cv_func__getpty" +if test "x$ac_cv_func__getpty" = xyes +then : + printf "%s\n" "#define HAVE__GETPTY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpwent" "ac_cv_func_getpwent" +if test "x$ac_cv_func_getpwent" = xyes +then : + printf "%s\n" "#define HAVE_GETPWENT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpwnam_r" "ac_cv_func_getpwnam_r" +if test "x$ac_cv_func_getpwnam_r" = xyes +then : + printf "%s\n" "#define HAVE_GETPWNAM_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpwuid" "ac_cv_func_getpwuid" +if test "x$ac_cv_func_getpwuid" = xyes +then : + printf "%s\n" "#define HAVE_GETPWUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getpwuid_r" "ac_cv_func_getpwuid_r" +if test "x$ac_cv_func_getpwuid_r" = xyes +then : + printf "%s\n" "#define HAVE_GETPWUID_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getresgid" "ac_cv_func_getresgid" +if test "x$ac_cv_func_getresgid" = xyes +then : + printf "%s\n" "#define HAVE_GETRESGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getresuid" "ac_cv_func_getresuid" +if test "x$ac_cv_func_getresuid" = xyes +then : + printf "%s\n" "#define HAVE_GETRESUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getrusage" "ac_cv_func_getrusage" +if test "x$ac_cv_func_getrusage" = xyes +then : + printf "%s\n" "#define HAVE_GETRUSAGE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getsid" "ac_cv_func_getsid" +if test "x$ac_cv_func_getsid" = xyes +then : + printf "%s\n" "#define HAVE_GETSID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getspent" "ac_cv_func_getspent" +if test "x$ac_cv_func_getspent" = xyes +then : + printf "%s\n" "#define HAVE_GETSPENT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getspnam" "ac_cv_func_getspnam" +if test "x$ac_cv_func_getspnam" = xyes +then : + printf "%s\n" "#define HAVE_GETSPNAM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "gettid" "ac_cv_func_gettid" +if test "x$ac_cv_func_gettid" = xyes +then : + printf "%s\n" "#define HAVE_GETTID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getuid" "ac_cv_func_getuid" +if test "x$ac_cv_func_getuid" = xyes +then : + printf "%s\n" "#define HAVE_GETUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getwd" "ac_cv_func_getwd" +if test "x$ac_cv_func_getwd" = xyes +then : + printf "%s\n" "#define HAVE_GETWD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "grantpt" "ac_cv_func_grantpt" +if test "x$ac_cv_func_grantpt" = xyes +then : + printf "%s\n" "#define HAVE_GRANTPT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "if_indextoname" "ac_cv_func_if_indextoname" +if test "x$ac_cv_func_if_indextoname" = xyes +then : + printf "%s\n" "#define HAVE_IF_INDEXTONAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "if_nameindex" "ac_cv_func_if_nameindex" +if test "x$ac_cv_func_if_nameindex" = xyes +then : + printf "%s\n" "#define HAVE_IF_NAMEINDEX 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "if_nametoindex" "ac_cv_func_if_nametoindex" +if test "x$ac_cv_func_if_nametoindex" = xyes +then : + printf "%s\n" "#define HAVE_IF_NAMETOINDEX 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "initgroups" "ac_cv_func_initgroups" +if test "x$ac_cv_func_initgroups" = xyes +then : + printf "%s\n" "#define HAVE_INITGROUPS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "kill" "ac_cv_func_kill" +if test "x$ac_cv_func_kill" = xyes +then : + printf "%s\n" "#define HAVE_KILL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "killpg" "ac_cv_func_killpg" +if test "x$ac_cv_func_killpg" = xyes +then : + printf "%s\n" "#define HAVE_KILLPG 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "lchown" "ac_cv_func_lchown" +if test "x$ac_cv_func_lchown" = xyes +then : + printf "%s\n" "#define HAVE_LCHOWN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "linkat" "ac_cv_func_linkat" +if test "x$ac_cv_func_linkat" = xyes +then : + printf "%s\n" "#define HAVE_LINKAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "lockf" "ac_cv_func_lockf" +if test "x$ac_cv_func_lockf" = xyes +then : + printf "%s\n" "#define HAVE_LOCKF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "lstat" "ac_cv_func_lstat" +if test "x$ac_cv_func_lstat" = xyes +then : + printf "%s\n" "#define HAVE_LSTAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "lutimes" "ac_cv_func_lutimes" +if test "x$ac_cv_func_lutimes" = xyes +then : + printf "%s\n" "#define HAVE_LUTIMES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "madvise" "ac_cv_func_madvise" +if test "x$ac_cv_func_madvise" = xyes +then : + printf "%s\n" "#define HAVE_MADVISE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mbrtowc" "ac_cv_func_mbrtowc" +if test "x$ac_cv_func_mbrtowc" = xyes +then : + printf "%s\n" "#define HAVE_MBRTOWC 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "memrchr" "ac_cv_func_memrchr" +if test "x$ac_cv_func_memrchr" = xyes +then : + printf "%s\n" "#define HAVE_MEMRCHR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mkdirat" "ac_cv_func_mkdirat" +if test "x$ac_cv_func_mkdirat" = xyes +then : + printf "%s\n" "#define HAVE_MKDIRAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mkfifo" "ac_cv_func_mkfifo" +if test "x$ac_cv_func_mkfifo" = xyes +then : + printf "%s\n" "#define HAVE_MKFIFO 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mkfifoat" "ac_cv_func_mkfifoat" +if test "x$ac_cv_func_mkfifoat" = xyes +then : + printf "%s\n" "#define HAVE_MKFIFOAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mknod" "ac_cv_func_mknod" +if test "x$ac_cv_func_mknod" = xyes +then : + printf "%s\n" "#define HAVE_MKNOD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mknodat" "ac_cv_func_mknodat" +if test "x$ac_cv_func_mknodat" = xyes +then : + printf "%s\n" "#define HAVE_MKNODAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mktime" "ac_cv_func_mktime" +if test "x$ac_cv_func_mktime" = xyes +then : + printf "%s\n" "#define HAVE_MKTIME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap" +if test "x$ac_cv_func_mmap" = xyes +then : + printf "%s\n" "#define HAVE_MMAP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "mremap" "ac_cv_func_mremap" +if test "x$ac_cv_func_mremap" = xyes +then : + printf "%s\n" "#define HAVE_MREMAP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "nice" "ac_cv_func_nice" +if test "x$ac_cv_func_nice" = xyes +then : + printf "%s\n" "#define HAVE_NICE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "openat" "ac_cv_func_openat" +if test "x$ac_cv_func_openat" = xyes +then : + printf "%s\n" "#define HAVE_OPENAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir" +if test "x$ac_cv_func_opendir" = xyes +then : + printf "%s\n" "#define HAVE_OPENDIR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pathconf" "ac_cv_func_pathconf" +if test "x$ac_cv_func_pathconf" = xyes +then : + printf "%s\n" "#define HAVE_PATHCONF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pause" "ac_cv_func_pause" +if test "x$ac_cv_func_pause" = xyes +then : + printf "%s\n" "#define HAVE_PAUSE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pidfd_open" "ac_cv_func_pidfd_open" +if test "x$ac_cv_func_pidfd_open" = xyes +then : + printf "%s\n" "#define HAVE_PIDFD_OPEN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pidfd_getfd" "ac_cv_func_pidfd_getfd" +if test "x$ac_cv_func_pidfd_getfd" = xyes +then : + printf "%s\n" "#define HAVE_PIDFD_GETFD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pidfd_send_signal" "ac_cv_func_pidfd_send_signal" +if test "x$ac_cv_func_pidfd_send_signal" = xyes +then : + printf "%s\n" "#define HAVE_PIDFD_SEND_SIGNAL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pipe" "ac_cv_func_pipe" +if test "x$ac_cv_func_pipe" = xyes +then : + printf "%s\n" "#define HAVE_PIPE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "plock" "ac_cv_func_plock" +if test "x$ac_cv_func_plock" = xyes +then : + printf "%s\n" "#define HAVE_PLOCK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" +if test "x$ac_cv_func_poll" = xyes +then : + printf "%s\n" "#define HAVE_POLL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ppoll" "ac_cv_func_ppoll" +if test "x$ac_cv_func_ppoll" = xyes +then : + printf "%s\n" "#define HAVE_PPOLL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_fadvise" "ac_cv_func_posix_fadvise" +if test "x$ac_cv_func_posix_fadvise" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_FADVISE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_fallocate" "ac_cv_func_posix_fallocate" +if test "x$ac_cv_func_posix_fallocate" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_openpt" "ac_cv_func_posix_openpt" +if test "x$ac_cv_func_posix_openpt" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_OPENPT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" +if test "x$ac_cv_func_posix_spawn" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_SPAWN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp" +if test "x$ac_cv_func_posix_spawnp" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_SPAWNP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_spawn_file_actions_addclosefrom_np" "ac_cv_func_posix_spawn_file_actions_addclosefrom_np" +if test "x$ac_cv_func_posix_spawn_file_actions_addclosefrom_np" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread" +if test "x$ac_cv_func_pread" = xyes +then : + printf "%s\n" "#define HAVE_PREAD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "preadv" "ac_cv_func_preadv" +if test "x$ac_cv_func_preadv" = xyes +then : + printf "%s\n" "#define HAVE_PREADV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "preadv2" "ac_cv_func_preadv2" +if test "x$ac_cv_func_preadv2" = xyes +then : + printf "%s\n" "#define HAVE_PREADV2 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "process_vm_readv" "ac_cv_func_process_vm_readv" +if test "x$ac_cv_func_process_vm_readv" = xyes +then : + printf "%s\n" "#define HAVE_PROCESS_VM_READV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_cond_timedwait_relative_np" "ac_cv_func_pthread_cond_timedwait_relative_np" +if test "x$ac_cv_func_pthread_cond_timedwait_relative_np" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_condattr_setclock" "ac_cv_func_pthread_condattr_setclock" +if test "x$ac_cv_func_pthread_condattr_setclock" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_init" "ac_cv_func_pthread_init" +if test "x$ac_cv_func_pthread_init" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_INIT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_kill" "ac_cv_func_pthread_kill" +if test "x$ac_cv_func_pthread_kill" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_KILL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_get_name_np" "ac_cv_func_pthread_get_name_np" +if test "x$ac_cv_func_pthread_get_name_np" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_GET_NAME_NP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_getname_np" "ac_cv_func_pthread_getname_np" +if test "x$ac_cv_func_pthread_getname_np" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_GETNAME_NP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_set_name_np" "ac_cv_func_pthread_set_name_np" +if test "x$ac_cv_func_pthread_set_name_np" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_SET_NAME_NP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_setname_np" "ac_cv_func_pthread_setname_np" +if test "x$ac_cv_func_pthread_setname_np" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pthread_getattr_np" "ac_cv_func_pthread_getattr_np" +if test "x$ac_cv_func_pthread_getattr_np" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_GETATTR_NP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ptsname" "ac_cv_func_ptsname" +if test "x$ac_cv_func_ptsname" = xyes +then : + printf "%s\n" "#define HAVE_PTSNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ptsname_r" "ac_cv_func_ptsname_r" +if test "x$ac_cv_func_ptsname_r" = xyes +then : + printf "%s\n" "#define HAVE_PTSNAME_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite" +if test "x$ac_cv_func_pwrite" = xyes +then : + printf "%s\n" "#define HAVE_PWRITE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pwritev" "ac_cv_func_pwritev" +if test "x$ac_cv_func_pwritev" = xyes +then : + printf "%s\n" "#define HAVE_PWRITEV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pwritev2" "ac_cv_func_pwritev2" +if test "x$ac_cv_func_pwritev2" = xyes +then : + printf "%s\n" "#define HAVE_PWRITEV2 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "readlink" "ac_cv_func_readlink" +if test "x$ac_cv_func_readlink" = xyes +then : + printf "%s\n" "#define HAVE_READLINK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "readlinkat" "ac_cv_func_readlinkat" +if test "x$ac_cv_func_readlinkat" = xyes +then : + printf "%s\n" "#define HAVE_READLINKAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "readv" "ac_cv_func_readv" +if test "x$ac_cv_func_readv" = xyes +then : + printf "%s\n" "#define HAVE_READV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" +if test "x$ac_cv_func_realpath" = xyes +then : + printf "%s\n" "#define HAVE_REALPATH 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "renameat" "ac_cv_func_renameat" +if test "x$ac_cv_func_renameat" = xyes +then : + printf "%s\n" "#define HAVE_RENAMEAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "rtpSpawn" "ac_cv_func_rtpSpawn" +if test "x$ac_cv_func_rtpSpawn" = xyes +then : + printf "%s\n" "#define HAVE_RTPSPAWN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sched_get_priority_max" "ac_cv_func_sched_get_priority_max" +if test "x$ac_cv_func_sched_get_priority_max" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_GET_PRIORITY_MAX 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sched_rr_get_interval" "ac_cv_func_sched_rr_get_interval" +if test "x$ac_cv_func_sched_rr_get_interval" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_RR_GET_INTERVAL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sched_setaffinity" "ac_cv_func_sched_setaffinity" +if test "x$ac_cv_func_sched_setaffinity" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_SETAFFINITY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sched_setparam" "ac_cv_func_sched_setparam" +if test "x$ac_cv_func_sched_setparam" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_SETPARAM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sched_setscheduler" "ac_cv_func_sched_setscheduler" +if test "x$ac_cv_func_sched_setscheduler" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_SETSCHEDULER 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sem_clockwait" "ac_cv_func_sem_clockwait" +if test "x$ac_cv_func_sem_clockwait" = xyes +then : + printf "%s\n" "#define HAVE_SEM_CLOCKWAIT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sem_getvalue" "ac_cv_func_sem_getvalue" +if test "x$ac_cv_func_sem_getvalue" = xyes +then : + printf "%s\n" "#define HAVE_SEM_GETVALUE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sem_open" "ac_cv_func_sem_open" +if test "x$ac_cv_func_sem_open" = xyes +then : + printf "%s\n" "#define HAVE_SEM_OPEN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sem_timedwait" "ac_cv_func_sem_timedwait" +if test "x$ac_cv_func_sem_timedwait" = xyes +then : + printf "%s\n" "#define HAVE_SEM_TIMEDWAIT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sem_unlink" "ac_cv_func_sem_unlink" +if test "x$ac_cv_func_sem_unlink" = xyes +then : + printf "%s\n" "#define HAVE_SEM_UNLINK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile" +if test "x$ac_cv_func_sendfile" = xyes +then : + printf "%s\n" "#define HAVE_SENDFILE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setegid" "ac_cv_func_setegid" +if test "x$ac_cv_func_setegid" = xyes +then : + printf "%s\n" "#define HAVE_SETEGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "seteuid" "ac_cv_func_seteuid" +if test "x$ac_cv_func_seteuid" = xyes +then : + printf "%s\n" "#define HAVE_SETEUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setgid" "ac_cv_func_setgid" +if test "x$ac_cv_func_setgid" = xyes +then : + printf "%s\n" "#define HAVE_SETGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sethostname" "ac_cv_func_sethostname" +if test "x$ac_cv_func_sethostname" = xyes +then : + printf "%s\n" "#define HAVE_SETHOSTNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setitimer" "ac_cv_func_setitimer" +if test "x$ac_cv_func_setitimer" = xyes +then : + printf "%s\n" "#define HAVE_SETITIMER 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" +if test "x$ac_cv_func_setlocale" = xyes +then : + printf "%s\n" "#define HAVE_SETLOCALE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setpgid" "ac_cv_func_setpgid" +if test "x$ac_cv_func_setpgid" = xyes +then : + printf "%s\n" "#define HAVE_SETPGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setpgrp" "ac_cv_func_setpgrp" +if test "x$ac_cv_func_setpgrp" = xyes +then : + printf "%s\n" "#define HAVE_SETPGRP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setpriority" "ac_cv_func_setpriority" +if test "x$ac_cv_func_setpriority" = xyes +then : + printf "%s\n" "#define HAVE_SETPRIORITY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setregid" "ac_cv_func_setregid" +if test "x$ac_cv_func_setregid" = xyes +then : + printf "%s\n" "#define HAVE_SETREGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setresgid" "ac_cv_func_setresgid" +if test "x$ac_cv_func_setresgid" = xyes +then : + printf "%s\n" "#define HAVE_SETRESGID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setresuid" "ac_cv_func_setresuid" +if test "x$ac_cv_func_setresuid" = xyes +then : + printf "%s\n" "#define HAVE_SETRESUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setreuid" "ac_cv_func_setreuid" +if test "x$ac_cv_func_setreuid" = xyes +then : + printf "%s\n" "#define HAVE_SETREUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setsid" "ac_cv_func_setsid" +if test "x$ac_cv_func_setsid" = xyes +then : + printf "%s\n" "#define HAVE_SETSID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setuid" "ac_cv_func_setuid" +if test "x$ac_cv_func_setuid" = xyes +then : + printf "%s\n" "#define HAVE_SETUID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setvbuf" "ac_cv_func_setvbuf" +if test "x$ac_cv_func_setvbuf" = xyes +then : + printf "%s\n" "#define HAVE_SETVBUF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "shutdown" "ac_cv_func_shutdown" +if test "x$ac_cv_func_shutdown" = xyes +then : + printf "%s\n" "#define HAVE_SHUTDOWN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction" +if test "x$ac_cv_func_sigaction" = xyes +then : + printf "%s\n" "#define HAVE_SIGACTION 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigaltstack" "ac_cv_func_sigaltstack" +if test "x$ac_cv_func_sigaltstack" = xyes +then : + printf "%s\n" "#define HAVE_SIGALTSTACK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigfillset" "ac_cv_func_sigfillset" +if test "x$ac_cv_func_sigfillset" = xyes +then : + printf "%s\n" "#define HAVE_SIGFILLSET 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "siginterrupt" "ac_cv_func_siginterrupt" +if test "x$ac_cv_func_siginterrupt" = xyes +then : + printf "%s\n" "#define HAVE_SIGINTERRUPT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigpending" "ac_cv_func_sigpending" +if test "x$ac_cv_func_sigpending" = xyes +then : + printf "%s\n" "#define HAVE_SIGPENDING 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigrelse" "ac_cv_func_sigrelse" +if test "x$ac_cv_func_sigrelse" = xyes +then : + printf "%s\n" "#define HAVE_SIGRELSE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigtimedwait" "ac_cv_func_sigtimedwait" +if test "x$ac_cv_func_sigtimedwait" = xyes +then : + printf "%s\n" "#define HAVE_SIGTIMEDWAIT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigwait" "ac_cv_func_sigwait" +if test "x$ac_cv_func_sigwait" = xyes +then : + printf "%s\n" "#define HAVE_SIGWAIT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigwaitinfo" "ac_cv_func_sigwaitinfo" +if test "x$ac_cv_func_sigwaitinfo" = xyes +then : + printf "%s\n" "#define HAVE_SIGWAITINFO 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" +if test "x$ac_cv_func_snprintf" = xyes +then : + printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "splice" "ac_cv_func_splice" +if test "x$ac_cv_func_splice" = xyes +then : + printf "%s\n" "#define HAVE_SPLICE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" +if test "x$ac_cv_func_strftime" = xyes +then : + printf "%s\n" "#define HAVE_STRFTIME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" +if test "x$ac_cv_func_strlcpy" = xyes +then : + printf "%s\n" "#define HAVE_STRLCPY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strsignal" "ac_cv_func_strsignal" +if test "x$ac_cv_func_strsignal" = xyes +then : + printf "%s\n" "#define HAVE_STRSIGNAL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "symlinkat" "ac_cv_func_symlinkat" +if test "x$ac_cv_func_symlinkat" = xyes +then : + printf "%s\n" "#define HAVE_SYMLINKAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sync" "ac_cv_func_sync" +if test "x$ac_cv_func_sync" = xyes +then : + printf "%s\n" "#define HAVE_SYNC 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf" +if test "x$ac_cv_func_sysconf" = xyes +then : + printf "%s\n" "#define HAVE_SYSCONF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sysctlbyname" "ac_cv_func_sysctlbyname" +if test "x$ac_cv_func_sysctlbyname" = xyes +then : + printf "%s\n" "#define HAVE_SYSCTLBYNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tcgetpgrp" "ac_cv_func_tcgetpgrp" +if test "x$ac_cv_func_tcgetpgrp" = xyes +then : + printf "%s\n" "#define HAVE_TCGETPGRP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tcsetpgrp" "ac_cv_func_tcsetpgrp" +if test "x$ac_cv_func_tcsetpgrp" = xyes +then : + printf "%s\n" "#define HAVE_TCSETPGRP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tempnam" "ac_cv_func_tempnam" +if test "x$ac_cv_func_tempnam" = xyes +then : + printf "%s\n" "#define HAVE_TEMPNAM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm" +if test "x$ac_cv_func_timegm" = xyes +then : + printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "times" "ac_cv_func_times" +if test "x$ac_cv_func_times" = xyes +then : + printf "%s\n" "#define HAVE_TIMES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tmpfile" "ac_cv_func_tmpfile" +if test "x$ac_cv_func_tmpfile" = xyes +then : + printf "%s\n" "#define HAVE_TMPFILE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tmpnam" "ac_cv_func_tmpnam" +if test "x$ac_cv_func_tmpnam" = xyes +then : + printf "%s\n" "#define HAVE_TMPNAM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tmpnam_r" "ac_cv_func_tmpnam_r" +if test "x$ac_cv_func_tmpnam_r" = xyes +then : + printf "%s\n" "#define HAVE_TMPNAM_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "truncate" "ac_cv_func_truncate" +if test "x$ac_cv_func_truncate" = xyes +then : + printf "%s\n" "#define HAVE_TRUNCATE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ttyname_r" "ac_cv_func_ttyname_r" +if test "x$ac_cv_func_ttyname_r" = xyes +then : + printf "%s\n" "#define HAVE_TTYNAME_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "umask" "ac_cv_func_umask" +if test "x$ac_cv_func_umask" = xyes +then : + printf "%s\n" "#define HAVE_UMASK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname" +if test "x$ac_cv_func_uname" = xyes +then : + printf "%s\n" "#define HAVE_UNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "unlinkat" "ac_cv_func_unlinkat" +if test "x$ac_cv_func_unlinkat" = xyes +then : + printf "%s\n" "#define HAVE_UNLINKAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "unlockpt" "ac_cv_func_unlockpt" +if test "x$ac_cv_func_unlockpt" = xyes +then : + printf "%s\n" "#define HAVE_UNLOCKPT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat" +if test "x$ac_cv_func_utimensat" = xyes +then : + printf "%s\n" "#define HAVE_UTIMENSAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes" +if test "x$ac_cv_func_utimes" = xyes +then : + printf "%s\n" "#define HAVE_UTIMES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "vfork" "ac_cv_func_vfork" +if test "x$ac_cv_func_vfork" = xyes +then : + printf "%s\n" "#define HAVE_VFORK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wait" "ac_cv_func_wait" +if test "x$ac_cv_func_wait" = xyes +then : + printf "%s\n" "#define HAVE_WAIT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wait3" "ac_cv_func_wait3" +if test "x$ac_cv_func_wait3" = xyes +then : + printf "%s\n" "#define HAVE_WAIT3 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wait4" "ac_cv_func_wait4" +if test "x$ac_cv_func_wait4" = xyes +then : + printf "%s\n" "#define HAVE_WAIT4 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "waitid" "ac_cv_func_waitid" +if test "x$ac_cv_func_waitid" = xyes +then : + printf "%s\n" "#define HAVE_WAITID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "waitpid" "ac_cv_func_waitpid" +if test "x$ac_cv_func_waitpid" = xyes +then : + printf "%s\n" "#define HAVE_WAITPID 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcscoll" "ac_cv_func_wcscoll" +if test "x$ac_cv_func_wcscoll" = xyes +then : + printf "%s\n" "#define HAVE_WCSCOLL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcsftime" "ac_cv_func_wcsftime" +if test "x$ac_cv_func_wcsftime" = xyes +then : + printf "%s\n" "#define HAVE_WCSFTIME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcsxfrm" "ac_cv_func_wcsxfrm" +if test "x$ac_cv_func_wcsxfrm" = xyes +then : + printf "%s\n" "#define HAVE_WCSXFRM 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wmemcmp" "ac_cv_func_wmemcmp" +if test "x$ac_cv_func_wmemcmp" = xyes +then : + printf "%s\n" "#define HAVE_WMEMCMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "writev" "ac_cv_func_writev" +if test "x$ac_cv_func_writev" = xyes +then : + printf "%s\n" "#define HAVE_WRITEV 1" >>confdefs.h + +fi + + +# os.statx uses Linux's statx function. AIX also has a function named statx, +# but it's unrelated. Check only on Linux (including Android). +case $ac_sys_system in #( + Linux*) : + ac_fn_c_check_func "$LINENO" "statx" "ac_cv_func_statx" +if test "x$ac_cv_func_statx" = xyes +then : + printf "%s\n" "#define HAVE_STATX 1" >>confdefs.h + +fi + + ;; #( + *) : + ;; +esac + +# Force lchmod off for Linux. Linux disallows changing the mode of symbolic +# links. Some libc implementations have a stub lchmod implementation that always +# returns an error. +if test "$MACHDEP" != linux; then + ac_fn_c_check_func "$LINENO" "lchmod" "ac_cv_func_lchmod" +if test "x$ac_cv_func_lchmod" = xyes +then : + printf "%s\n" "#define HAVE_LCHMOD 1" >>confdefs.h + +fi + +fi + +# iOS defines some system methods that can be linked (so they are +# found by configure), but either raise a compilation error (because the +# header definition prevents usage - autoconf doesn't use the headers), or +# raise an error if used at runtime. Force these symbols off. +if test "$ac_sys_system" != "iOS" ; then + ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3" +if test "x$ac_cv_func_dup3" = xyes +then : + printf "%s\n" "#define HAVE_DUP3 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy" +if test "x$ac_cv_func_getentropy" = xyes +then : + printf "%s\n" "#define HAVE_GETENTROPY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getgroups" "ac_cv_func_getgroups" +if test "x$ac_cv_func_getgroups" = xyes +then : + printf "%s\n" "#define HAVE_GETGROUPS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2" +if test "x$ac_cv_func_pipe2" = xyes +then : + printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "system" "ac_cv_func_system" +if test "x$ac_cv_func_system" = xyes +then : + printf "%s\n" "#define HAVE_SYSTEM 1" >>confdefs.h + +fi + +fi + +ac_fn_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h> + #include <dirent.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_dirfd" = xyes +then : + +printf "%s\n" "#define HAVE_DIRFD 1" >>confdefs.h + +fi + +# For some functions, having a definition is not sufficient, since +# we want to take their address. + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for chroot" >&5 +printf %s "checking for chroot... " >&6; } +if test ${ac_cv_func_chroot+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +void *x=chroot + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_chroot=yes +else case e in #( + e) ac_cv_func_chroot=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_chroot" >&5 +printf "%s\n" "$ac_cv_func_chroot" >&6; } + if test "x$ac_cv_func_chroot" = xyes +then : + +printf "%s\n" "#define HAVE_CHROOT 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for link" >&5 +printf %s "checking for link... " >&6; } +if test ${ac_cv_func_link+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +void *x=link + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_link=yes +else case e in #( + e) ac_cv_func_link=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_link" >&5 +printf "%s\n" "$ac_cv_func_link" >&6; } + if test "x$ac_cv_func_link" = xyes +then : + +printf "%s\n" "#define HAVE_LINK 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for symlink" >&5 +printf %s "checking for symlink... " >&6; } +if test ${ac_cv_func_symlink+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +void *x=symlink + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_symlink=yes +else case e in #( + e) ac_cv_func_symlink=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_symlink" >&5 +printf "%s\n" "$ac_cv_func_symlink" >&6; } + if test "x$ac_cv_func_symlink" = xyes +then : + +printf "%s\n" "#define HAVE_SYMLINK 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fchdir" >&5 +printf %s "checking for fchdir... " >&6; } +if test ${ac_cv_func_fchdir+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +void *x=fchdir + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_fchdir=yes +else case e in #( + e) ac_cv_func_fchdir=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fchdir" >&5 +printf "%s\n" "$ac_cv_func_fchdir" >&6; } + if test "x$ac_cv_func_fchdir" = xyes +then : + +printf "%s\n" "#define HAVE_FCHDIR 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fsync" >&5 +printf %s "checking for fsync... " >&6; } +if test ${ac_cv_func_fsync+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +void *x=fsync + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_fsync=yes +else case e in #( + e) ac_cv_func_fsync=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fsync" >&5 +printf "%s\n" "$ac_cv_func_fsync" >&6; } + if test "x$ac_cv_func_fsync" = xyes +then : + +printf "%s\n" "#define HAVE_FSYNC 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fdatasync" >&5 +printf %s "checking for fdatasync... " >&6; } +if test ${ac_cv_func_fdatasync+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +void *x=fdatasync + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_fdatasync=yes +else case e in #( + e) ac_cv_func_fdatasync=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fdatasync" >&5 +printf "%s\n" "$ac_cv_func_fdatasync" >&6; } + if test "x$ac_cv_func_fdatasync" = xyes +then : + +printf "%s\n" "#define HAVE_FDATASYNC 1" >>confdefs.h + +fi + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --disable-epoll" >&5 +printf %s "checking for --disable-epoll... " >&6; } +# Check whether --enable-epoll was given. +if test ${enable_epoll+y} +then : + enableval=$enable_epoll; if test "x$enable_epoll" = xno +then : + disable_epoll=yes +else case e in #( + e) disable_epoll=no ;; +esac +fi +else case e in #( + e) disable_epoll=no + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $disable_epoll" >&5 +printf "%s\n" "$disable_epoll" >&6; } +if test "$disable_epoll" = "no" +then + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for epoll_create" >&5 +printf %s "checking for epoll_create... " >&6; } +if test ${ac_cv_func_epoll_create+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/epoll.h> +int +main (void) +{ +void *x=epoll_create + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_epoll_create=yes +else case e in #( + e) ac_cv_func_epoll_create=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll_create" >&5 +printf "%s\n" "$ac_cv_func_epoll_create" >&6; } + if test "x$ac_cv_func_epoll_create" = xyes +then : + +printf "%s\n" "#define HAVE_EPOLL 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for epoll_create1" >&5 +printf %s "checking for epoll_create1... " >&6; } +if test ${ac_cv_func_epoll_create1+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/epoll.h> +int +main (void) +{ +void *x=epoll_create1 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_epoll_create1=yes +else case e in #( + e) ac_cv_func_epoll_create1=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll_create1" >&5 +printf "%s\n" "$ac_cv_func_epoll_create1" >&6; } + if test "x$ac_cv_func_epoll_create1" = xyes +then : + +printf "%s\n" "#define HAVE_EPOLL_CREATE1 1" >>confdefs.h + +fi + + + +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for kqueue" >&5 +printf %s "checking for kqueue... " >&6; } +if test ${ac_cv_func_kqueue+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/event.h> + +int +main (void) +{ +void *x=kqueue + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_kqueue=yes +else case e in #( + e) ac_cv_func_kqueue=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_kqueue" >&5 +printf "%s\n" "$ac_cv_func_kqueue" >&6; } + if test "x$ac_cv_func_kqueue" = xyes +then : + +printf "%s\n" "#define HAVE_KQUEUE 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for prlimit" >&5 +printf %s "checking for prlimit... " >&6; } +if test ${ac_cv_func_prlimit+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/time.h> +#include <sys/resource.h> + +int +main (void) +{ +void *x=prlimit + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_prlimit=yes +else case e in #( + e) ac_cv_func_prlimit=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_prlimit" >&5 +printf "%s\n" "$ac_cv_func_prlimit" >&6; } + if test "x$ac_cv_func_prlimit" = xyes +then : + +printf "%s\n" "#define HAVE_PRLIMIT 1" >>confdefs.h + +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _dyld_shared_cache_contains_path" >&5 +printf %s "checking for _dyld_shared_cache_contains_path... " >&6; } +if test ${ac_cv_func__dyld_shared_cache_contains_path+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <mach-o/dyld.h> +int +main (void) +{ +void *x=_dyld_shared_cache_contains_path + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func__dyld_shared_cache_contains_path=yes +else case e in #( + e) ac_cv_func__dyld_shared_cache_contains_path=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func__dyld_shared_cache_contains_path" >&5 +printf "%s\n" "$ac_cv_func__dyld_shared_cache_contains_path" >&6; } + if test "x$ac_cv_func__dyld_shared_cache_contains_path" = xyes +then : + +printf "%s\n" "#define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH 1" >>confdefs.h + +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for memfd_create" >&5 +printf %s "checking for memfd_create... " >&6; } +if test ${ac_cv_func_memfd_create+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif +#ifdef HAVE_SYS_MEMFD_H +#include <sys/memfd.h> +#endif + +int +main (void) +{ +void *x=memfd_create + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_memfd_create=yes +else case e in #( + e) ac_cv_func_memfd_create=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memfd_create" >&5 +printf "%s\n" "$ac_cv_func_memfd_create" >&6; } + if test "x$ac_cv_func_memfd_create" = xyes +then : + +printf "%s\n" "#define HAVE_MEMFD_CREATE 1" >>confdefs.h + +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for eventfd" >&5 +printf %s "checking for eventfd... " >&6; } +if test ${ac_cv_func_eventfd+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_SYS_EVENTFD_H +#include <sys/eventfd.h> +#endif + +int +main (void) +{ +void *x=eventfd + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_eventfd=yes +else case e in #( + e) ac_cv_func_eventfd=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_eventfd" >&5 +printf "%s\n" "$ac_cv_func_eventfd" >&6; } + if test "x$ac_cv_func_eventfd" = xyes +then : + +printf "%s\n" "#define HAVE_EVENTFD 1" >>confdefs.h + +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for timerfd_create" >&5 +printf %s "checking for timerfd_create... " >&6; } +if test ${ac_cv_func_timerfd_create+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_SYS_TIMERFD_H +#include <sys/timerfd.h> +#endif + +int +main (void) +{ +void *x=timerfd_create + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_timerfd_create=yes +else case e in #( + e) ac_cv_func_timerfd_create=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_timerfd_create" >&5 +printf "%s\n" "$ac_cv_func_timerfd_create" >&6; } + if test "x$ac_cv_func_timerfd_create" = xyes +then : + +printf "%s\n" "#define HAVE_TIMERFD_CREATE 1" >>confdefs.h + +fi + + + + +# On some systems (eg. FreeBSD 5), we would find a definition of the +# functions ctermid_r, setgroups in the library, but no prototype +# (e.g. because we use _XOPEN_SOURCE). See whether we can take their +# address to avoid compiler warnings and potential miscompilations +# because of the missing prototypes. + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ctermid_r" >&5 +printf %s "checking for ctermid_r... " >&6; } +if test ${ac_cv_func_ctermid_r+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main (void) +{ +void *x=ctermid_r + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ctermid_r=yes +else case e in #( + e) ac_cv_func_ctermid_r=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ctermid_r" >&5 +printf "%s\n" "$ac_cv_func_ctermid_r" >&6; } + if test "x$ac_cv_func_ctermid_r" = xyes +then : + +printf "%s\n" "#define HAVE_CTERMID_R 1" >>confdefs.h + +fi + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for flock declaration" >&5 +printf %s "checking for flock declaration... " >&6; } +if test ${ac_cv_flock_decl+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/file.h> +int +main (void) +{ +void* p = flock + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_flock_decl=yes +else case e in #( + e) ac_cv_flock_decl=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flock_decl" >&5 +printf "%s\n" "$ac_cv_flock_decl" >&6; } +if test "x$ac_cv_flock_decl" = xyes +then : + + for ac_func in flock +do : + ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock" +if test "x$ac_cv_func_flock" = xyes +then : + printf "%s\n" "#define HAVE_FLOCK 1" >>confdefs.h + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5 +printf %s "checking for flock in -lbsd... " >&6; } +if test ${ac_cv_lib_bsd_flock+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char flock (void); +int +main (void) +{ +return flock (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bsd_flock=yes +else case e in #( + e) ac_cv_lib_bsd_flock=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5 +printf "%s\n" "$ac_cv_lib_bsd_flock" >&6; } +if test "x$ac_cv_lib_bsd_flock" = xyes +then : + FCNTL_LIBS="-lbsd" +fi + ;; +esac +fi + +done +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5 +printf %s "checking for getpagesize... " >&6; } +if test ${ac_cv_func_getpagesize+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +void *x=getpagesize + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getpagesize=yes +else case e in #( + e) ac_cv_func_getpagesize=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpagesize" >&5 +printf "%s\n" "$ac_cv_func_getpagesize" >&6; } + if test "x$ac_cv_func_getpagesize" = xyes +then : + +printf "%s\n" "#define HAVE_GETPAGESIZE 1" >>confdefs.h + +fi + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken unsetenv" >&5 +printf %s "checking for broken unsetenv... " >&6; } +if test ${ac_cv_broken_unsetenv+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +int +main (void) +{ +int res = unsetenv("DUMMY") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_broken_unsetenv=no +else case e in #( + e) ac_cv_broken_unsetenv=yes + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_unsetenv" >&5 +printf "%s\n" "$ac_cv_broken_unsetenv" >&6; } +if test "x$ac_cv_broken_unsetenv" = xyes +then : + + +printf "%s\n" "#define HAVE_BROKEN_UNSETENV 1" >>confdefs.h + + +fi + +for ac_prog in true +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_TRUE+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$TRUE"; then + ac_cv_prog_TRUE="$TRUE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_TRUE="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +TRUE=$ac_cv_prog_TRUE +if test -n "$TRUE"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TRUE" >&5 +printf "%s\n" "$TRUE" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$TRUE" && break +done +test -n "$TRUE" || TRUE="/bin/true" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lc" >&5 +printf %s "checking for inet_aton in -lc... " >&6; } +if test ${ac_cv_lib_c_inet_aton+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char inet_aton (void); +int +main (void) +{ +return inet_aton (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_c_inet_aton=yes +else case e in #( + e) ac_cv_lib_c_inet_aton=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_inet_aton" >&5 +printf "%s\n" "$ac_cv_lib_c_inet_aton" >&6; } +if test "x$ac_cv_lib_c_inet_aton" = xyes +then : + $ac_cv_prog_TRUE +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lresolv" >&5 +printf %s "checking for inet_aton in -lresolv... " >&6; } +if test ${ac_cv_lib_resolv_inet_aton+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char inet_aton (void); +int +main (void) +{ +return inet_aton (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_resolv_inet_aton=yes +else case e in #( + e) ac_cv_lib_resolv_inet_aton=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_inet_aton" >&5 +printf "%s\n" "$ac_cv_lib_resolv_inet_aton" >&6; } +if test "x$ac_cv_lib_resolv_inet_aton" = xyes +then : + SOCKET_LIBS="-lresolv" +fi + + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hstrerror in -lc" >&5 +printf %s "checking for hstrerror in -lc... " >&6; } +if test ${ac_cv_lib_c_hstrerror+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char hstrerror (void); +int +main (void) +{ +return hstrerror (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_c_hstrerror=yes +else case e in #( + e) ac_cv_lib_c_hstrerror=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_hstrerror" >&5 +printf "%s\n" "$ac_cv_lib_c_hstrerror" >&6; } +if test "x$ac_cv_lib_c_hstrerror" = xyes +then : + $ac_cv_prog_TRUE +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hstrerror in -lresolv" >&5 +printf %s "checking for hstrerror in -lresolv... " >&6; } +if test ${ac_cv_lib_resolv_hstrerror+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char hstrerror (void); +int +main (void) +{ +return hstrerror (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_resolv_hstrerror=yes +else case e in #( + e) ac_cv_lib_resolv_hstrerror=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_hstrerror" >&5 +printf "%s\n" "$ac_cv_lib_resolv_hstrerror" >&6; } +if test "x$ac_cv_lib_resolv_hstrerror" = xyes +then : + SOCKET_LIBS="-lresolv" +fi + + ;; +esac +fi + + +# On Tru64, chflags seems to be present, but calling it will +# exit Python +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for chflags" >&5 +printf %s "checking for chflags... " >&6; } +if test ${ac_cv_have_chflags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_have_chflags=cross +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/stat.h> +#include <unistd.h> +int main(int argc, char *argv[]) +{ + if(chflags(argv[0], 0) != 0) + return 1; + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_have_chflags=yes +else case e in #( + e) ac_cv_have_chflags=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_chflags" >&5 +printf "%s\n" "$ac_cv_have_chflags" >&6; } +if test "$ac_cv_have_chflags" = cross ; then + ac_fn_c_check_func "$LINENO" "chflags" "ac_cv_func_chflags" +if test "x$ac_cv_func_chflags" = xyes +then : + ac_cv_have_chflags="yes" +else case e in #( + e) ac_cv_have_chflags="no" ;; +esac +fi + +fi +if test "$ac_cv_have_chflags" = yes ; then + +printf "%s\n" "#define HAVE_CHFLAGS 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lchflags" >&5 +printf %s "checking for lchflags... " >&6; } +if test ${ac_cv_have_lchflags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_have_lchflags=cross +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/stat.h> +#include <unistd.h> +int main(int argc, char *argv[]) +{ + if(lchflags(argv[0], 0) != 0) + return 1; + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_have_lchflags=yes +else case e in #( + e) ac_cv_have_lchflags=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_lchflags" >&5 +printf "%s\n" "$ac_cv_have_lchflags" >&6; } +if test "$ac_cv_have_lchflags" = cross ; then + ac_fn_c_check_func "$LINENO" "lchflags" "ac_cv_func_lchflags" +if test "x$ac_cv_func_lchflags" = xyes +then : + ac_cv_have_lchflags="yes" +else case e in #( + e) ac_cv_have_lchflags="no" ;; +esac +fi + +fi +if test "$ac_cv_have_lchflags" = yes ; then + +printf "%s\n" "#define HAVE_LCHFLAGS 1" >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-zlib" >&5 +printf %s "checking for --with-zlib... " >&6; } + +# Check whether --with-zlib was given. +if test ${with_zlib+y} +then : + withval=$with_zlib; case $with_zlib in #( + yes|auto) : + with_zlib=auto ;; #( + zlib|zlib-ng|zlib-rs|no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-zlib[=zlib|zlib-ng|zlib-rs|no]" "$LINENO" 5 ;; +esac +else case e in #( + e) with_zlib=auto ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_zlib" >&5 +printf "%s\n" "$with_zlib" >&6; } + +case $with_zlib in #( + auto|zlib) : + + + + if test "$ac_sys_system" = "Emscripten" -a -z "$ZLIB_CFLAGS" -a -z "$ZLIB_LIBS" +then : + + ZLIB_CFLAGS="-sUSE_ZLIB" + ZLIB_LIBS="-sUSE_ZLIB" + +fi + + + ;; #( + *) : + ;; +esac + +if test "x$with_zlib" = xzlib-rs +then : + + zlib_name="libz_rs" + zlib_version="0.6.0" + zlib_libname="z_rs" + +else case e in #( + e) + zlib_name="zlib" + zlib_version="1.2.2.1" + zlib_libname="z" + ;; +esac +fi + +if test "x$with_zlib" = xno +then : + have_zlib=no +else case e in #( + e) + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $zlib_name >= $zlib_version" >&5 +printf %s "checking for $zlib_name >= $zlib_version... " >&6; } + +if test -n "$ZLIB_CFLAGS"; then + pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$zlib_name >= \$zlib_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$zlib_name >= $zlib_version") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "$zlib_name >= $zlib_version" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$ZLIB_LIBS"; then + pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$zlib_name >= \$zlib_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$zlib_name >= $zlib_version") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "$zlib_name >= $zlib_version" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$zlib_name >= $zlib_version" 2>&1` + else + ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$zlib_name >= $zlib_version" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$ZLIB_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LIBS="$LIBS $ZLIB_LIBS" + for ac_header in zlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes +then : + printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h + + py_check_lib_save_LIBS=$LIBS +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_gzread" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -l$zlib_libname" >&5 +printf %s "checking for gzread in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-l$zlib_libname $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char gzread (void); +int +main (void) +{ +return gzread (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$as_ac_Lib=yes" +else case e in #( + e) eval "$as_ac_Lib=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" +then : + have_zlib=yes +else case e in #( + e) have_zlib=no ;; +esac +fi + +LIBS=$py_check_lib_save_LIBS + + +else case e in #( + e) have_zlib=no ;; +esac +fi + +done + if test "x$have_zlib" = xyes +then : + + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} + py_check_lib_save_LIBS=$LIBS +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_inflateCopy" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -l$zlib_libname" >&5 +printf %s "checking for inflateCopy in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-l$zlib_libname $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char inflateCopy (void); +int +main (void) +{ +return inflateCopy (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$as_ac_Lib=yes" +else case e in #( + e) eval "$as_ac_Lib=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" +then : + printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h + +fi + +LIBS=$py_check_lib_save_LIBS + + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LIBS="$LIBS $ZLIB_LIBS" + for ac_header in zlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes +then : + printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h + + py_check_lib_save_LIBS=$LIBS +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_gzread" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -l$zlib_libname" >&5 +printf %s "checking for gzread in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-l$zlib_libname $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char gzread (void); +int +main (void) +{ +return gzread (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$as_ac_Lib=yes" +else case e in #( + e) eval "$as_ac_Lib=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" +then : + have_zlib=yes +else case e in #( + e) have_zlib=no ;; +esac +fi + +LIBS=$py_check_lib_save_LIBS + + +else case e in #( + e) have_zlib=no ;; +esac +fi + +done + if test "x$have_zlib" = xyes +then : + + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} + py_check_lib_save_LIBS=$LIBS +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_inflateCopy" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -l$zlib_libname" >&5 +printf %s "checking for inflateCopy in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-l$zlib_libname $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char inflateCopy (void); +int +main (void) +{ +return inflateCopy (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$as_ac_Lib=yes" +else case e in #( + e) eval "$as_ac_Lib=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" +then : + printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h + +fi + +LIBS=$py_check_lib_save_LIBS + + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS + ZLIB_LIBS=$pkg_cv_ZLIB_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + have_zlib=yes + printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h + + +fi + ;; +esac +fi + +if test "x$with_zlib" = xzlib-ng +then : + if test "x$have_zlib" = xyes +then : + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + ac_fn_check_decl "$LINENO" "ZLIBNG_VERSION" "ac_cv_have_decl_ZLIBNG_VERSION" "#include <zlib.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_ZLIBNG_VERSION" = xyes +then : + +else case e in #( + e) as_fn_error $? "--with-zlib=zlib-ng: the detected zlib library is not zlib-ng" "$LINENO" 5 ;; +esac +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi +fi + +case $with_zlib in #( + auto|no) : + ;; #( + *) : + if test "x$have_zlib" = xno +then : + as_fn_error $? "--with-zlib=$with_zlib requested but $zlib_name was not found" "$LINENO" 5 +fi ;; +esac + +if test "x$have_zlib" = xyes +then : + + BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" + BINASCII_LIBS="$ZLIB_LIBS" + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-bzip2" >&5 +printf %s "checking for --with-bzip2... " >&6; } + +# Check whether --with-bzip2 was given. +if test ${with_bzip2+y} +then : + withval=$with_bzip2; case $with_bzip2 in #( + yes|auto) : + with_bzip2=auto ;; #( + bzip2|bzip2-rs|no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-bzip2[=bzip2|bzip2-rs|no]" "$LINENO" 5 ;; +esac +else case e in #( + e) with_bzip2=auto ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_bzip2" >&5 +printf "%s\n" "$with_bzip2" >&6; } + +case $with_bzip2 in #( + auto|bzip2) : + + + + if test "$ac_sys_system" = "Emscripten" -a -z "$BZIP2_CFLAGS" -a -z "$BZIP2_LIBS" +then : + + BZIP2_CFLAGS="-sUSE_BZIP2" + BZIP2_LIBS="-sUSE_BZIP2" + +fi + + + ;; #( + *) : + ;; +esac + +if test "x$with_bzip2" = xbzip2-rs +then : + + bzip2_name="libbz2_rs" + bzip2_libname="bz2_rs" + +else case e in #( + e) + bzip2_name="bzip2" + bzip2_libname="bz2" + ;; +esac +fi + +if test "x$with_bzip2" = xno +then : + have_bzip2=no +else case e in #( + e) + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $bzip2_name" >&5 +printf %s "checking for $bzip2_name... " >&6; } + +if test -n "$BZIP2_CFLAGS"; then + pkg_cv_BZIP2_CFLAGS="$BZIP2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$bzip2_name\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$bzip2_name") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "$bzip2_name" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$BZIP2_LIBS"; then + pkg_cv_BZIP2_LIBS="$BZIP2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$bzip2_name\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$bzip2_name") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "$bzip2_name" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$bzip2_name" 2>&1` + else + BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$bzip2_name" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$BZIP2_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LIBS="$LIBS $BZIP2_LIBS" + for ac_header in bzlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" +if test "x$ac_cv_header_bzlib_h" = xyes +then : + printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h + + as_ac_Lib=`printf "%s\n" "ac_cv_lib_$bzip2_libname""_BZ2_bzCompress" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -l$bzip2_libname" >&5 +printf %s "checking for BZ2_bzCompress in -l$bzip2_libname... " >&6; } +if eval test \${$as_ac_Lib+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-l$bzip2_libname $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char BZ2_bzCompress (void); +int +main (void) +{ +return BZ2_bzCompress (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$as_ac_Lib=yes" +else case e in #( + e) eval "$as_ac_Lib=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" +then : + have_bzip2=yes +else case e in #( + e) have_bzip2=no ;; +esac +fi + + +else case e in #( + e) have_bzip2=no ;; +esac +fi + +done + if test "x$have_bzip2" = xyes +then : + + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LIBS="$LIBS $BZIP2_LIBS" + for ac_header in bzlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" +if test "x$ac_cv_header_bzlib_h" = xyes +then : + printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h + + as_ac_Lib=`printf "%s\n" "ac_cv_lib_$bzip2_libname""_BZ2_bzCompress" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -l$bzip2_libname" >&5 +printf %s "checking for BZ2_bzCompress in -l$bzip2_libname... " >&6; } +if eval test \${$as_ac_Lib+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-l$bzip2_libname $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char BZ2_bzCompress (void); +int +main (void) +{ +return BZ2_bzCompress (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$as_ac_Lib=yes" +else case e in #( + e) eval "$as_ac_Lib=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" +then : + have_bzip2=yes +else case e in #( + e) have_bzip2=no ;; +esac +fi + + +else case e in #( + e) have_bzip2=no ;; +esac +fi + +done + if test "x$have_bzip2" = xyes +then : + + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + BZIP2_CFLAGS=$pkg_cv_BZIP2_CFLAGS + BZIP2_LIBS=$pkg_cv_BZIP2_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_bzip2=yes +fi + ;; +esac +fi + +case $with_bzip2 in #( + auto|no) : + ;; #( + *) : + if test "x$have_bzip2" = xno +then : + as_fn_error $? "--with-bzip2=$with_bzip2 requested but $bzip2_name was not found" "$LINENO" 5 +fi ;; +esac + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for liblzma" >&5 +printf %s "checking for liblzma... " >&6; } + +if test -n "$LIBLZMA_CFLAGS"; then + pkg_cv_LIBLZMA_CFLAGS="$LIBLZMA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBLZMA_CFLAGS=`$PKG_CONFIG --cflags "liblzma" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBLZMA_LIBS"; then + pkg_cv_LIBLZMA_LIBS="$LIBLZMA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBLZMA_LIBS=`$PKG_CONFIG --libs "liblzma" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblzma" 2>&1` + else + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblzma" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBLZMA_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LIBS="$LIBS $LIBLZMA_LIBS" + for ac_header in lzma.h +do : + ac_fn_c_check_header_compile "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" +if test "x$ac_cv_header_lzma_h" = xyes +then : + printf "%s\n" "#define HAVE_LZMA_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 +printf %s "checking for lzma_easy_encoder in -llzma... " >&6; } +if test ${ac_cv_lib_lzma_lzma_easy_encoder+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-llzma $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char lzma_easy_encoder (void); +int +main (void) +{ +return lzma_easy_encoder (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_lzma_lzma_easy_encoder=yes +else case e in #( + e) ac_cv_lib_lzma_lzma_easy_encoder=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 +printf "%s\n" "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } +if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes +then : + have_liblzma=yes +else case e in #( + e) have_liblzma=no ;; +esac +fi + + +else case e in #( + e) have_liblzma=no ;; +esac +fi + +done + if test "x$have_liblzma" = xyes +then : + + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LIBS="$LIBS $LIBLZMA_LIBS" + for ac_header in lzma.h +do : + ac_fn_c_check_header_compile "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" +if test "x$ac_cv_header_lzma_h" = xyes +then : + printf "%s\n" "#define HAVE_LZMA_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 +printf %s "checking for lzma_easy_encoder in -llzma... " >&6; } +if test ${ac_cv_lib_lzma_lzma_easy_encoder+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-llzma $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char lzma_easy_encoder (void); +int +main (void) +{ +return lzma_easy_encoder (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_lzma_lzma_easy_encoder=yes +else case e in #( + e) ac_cv_lib_lzma_lzma_easy_encoder=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 +printf "%s\n" "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } +if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes +then : + have_liblzma=yes +else case e in #( + e) have_liblzma=no ;; +esac +fi + + +else case e in #( + e) have_liblzma=no ;; +esac +fi + +done + if test "x$have_liblzma" = xyes +then : + + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBLZMA_CFLAGS=$pkg_cv_LIBLZMA_CFLAGS + LIBLZMA_LIBS=$pkg_cv_LIBLZMA_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_liblzma=yes +fi + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libzstd >= 1.4.5" >&5 +printf %s "checking for libzstd >= 1.4.5... " >&6; } + +if test -n "$LIBZSTD_CFLAGS"; then + pkg_cv_LIBZSTD_CFLAGS="$LIBZSTD_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd >= 1.4.5\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libzstd >= 1.4.5") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBZSTD_CFLAGS=`$PKG_CONFIG --cflags "libzstd >= 1.4.5" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBZSTD_LIBS"; then + pkg_cv_LIBZSTD_LIBS="$LIBZSTD_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd >= 1.4.5\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libzstd >= 1.4.5") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBZSTD_LIBS=`$PKG_CONFIG --libs "libzstd >= 1.4.5" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBZSTD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzstd >= 1.4.5" 2>&1` + else + LIBZSTD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzstd >= 1.4.5" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBZSTD_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBZSTD_CFLAGS" + CFLAGS="$CFLAGS $LIBZSTD_CFLAGS" + LIBS="$LIBS $LIBZSTD_LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing ZDICT_finalizeDictionary" >&5 +printf %s "checking for library containing ZDICT_finalizeDictionary... " >&6; } +if test ${ac_cv_search_ZDICT_finalizeDictionary+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char ZDICT_finalizeDictionary (void); +int +main (void) +{ +return ZDICT_finalizeDictionary (); + ; + return 0; +} +_ACEOF +for ac_lib in '' zstd +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_ZDICT_finalizeDictionary=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_ZDICT_finalizeDictionary+y} +then : + break +fi +done +if test ${ac_cv_search_ZDICT_finalizeDictionary+y} +then : + +else case e in #( + e) ac_cv_search_ZDICT_finalizeDictionary=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ZDICT_finalizeDictionary" >&5 +printf "%s\n" "$ac_cv_search_ZDICT_finalizeDictionary" >&6; } +ac_res=$ac_cv_search_ZDICT_finalizeDictionary +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ZSTD_VERSION_NUMBER >= 1.4.5" >&5 +printf %s "checking ZSTD_VERSION_NUMBER >= 1.4.5... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include "zstd.h" +int +main (void) +{ + + #if ZSTD_VERSION_NUMBER < 10405 + # error "zstd version is too old" + #endif + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + for ac_header in zstd.h zdict.h +do : + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | sed "$as_sed_sh"` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_header" | sed "$as_sed_cpp"` 1 +_ACEOF + have_libzstd=yes +else case e in #( + e) have_libzstd=no ;; +esac +fi + +done + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_libzstd=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +else case e in #( + e) have_libzstd=no ;; +esac +fi + + if test "x$have_libzstd" = xyes +then : + + LIBZSTD_CFLAGS=${LIBZSTD_CFLAGS-""} + LIBZSTD_LIBS=${LIBZSTD_LIBS-"-lzstd"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBZSTD_CFLAGS" + CFLAGS="$CFLAGS $LIBZSTD_CFLAGS" + LIBS="$LIBS $LIBZSTD_LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing ZDICT_finalizeDictionary" >&5 +printf %s "checking for library containing ZDICT_finalizeDictionary... " >&6; } +if test ${ac_cv_search_ZDICT_finalizeDictionary+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char ZDICT_finalizeDictionary (void); +int +main (void) +{ +return ZDICT_finalizeDictionary (); + ; + return 0; +} +_ACEOF +for ac_lib in '' zstd +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_ZDICT_finalizeDictionary=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_ZDICT_finalizeDictionary+y} +then : + break +fi +done +if test ${ac_cv_search_ZDICT_finalizeDictionary+y} +then : + +else case e in #( + e) ac_cv_search_ZDICT_finalizeDictionary=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ZDICT_finalizeDictionary" >&5 +printf "%s\n" "$ac_cv_search_ZDICT_finalizeDictionary" >&6; } +ac_res=$ac_cv_search_ZDICT_finalizeDictionary +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ZSTD_VERSION_NUMBER >= 1.4.5" >&5 +printf %s "checking ZSTD_VERSION_NUMBER >= 1.4.5... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include "zstd.h" +int +main (void) +{ + + #if ZSTD_VERSION_NUMBER < 10405 + # error "zstd version is too old" + #endif + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + for ac_header in zstd.h zdict.h +do : + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | sed "$as_sed_sh"` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_header" | sed "$as_sed_cpp"` 1 +_ACEOF + have_libzstd=yes +else case e in #( + e) have_libzstd=no ;; +esac +fi + +done + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_libzstd=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +else case e in #( + e) have_libzstd=no ;; +esac +fi + + if test "x$have_libzstd" = xyes +then : + + LIBZSTD_CFLAGS=${LIBZSTD_CFLAGS-""} + LIBZSTD_LIBS=${LIBZSTD_LIBS-"-lzstd"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBZSTD_CFLAGS=$pkg_cv_LIBZSTD_CFLAGS + LIBZSTD_LIBS=$pkg_cv_LIBZSTD_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_libzstd=yes +fi + +if test "x$have_libzstd" = xyes +then : + + REMOTE_DEBUGGING_CFLAGS="-DHAVE_ZSTD $LIBZSTD_CFLAGS" + REMOTE_DEBUGGING_LIBS="$LIBZSTD_LIBS" + +else case e in #( + e) + REMOTE_DEBUGGING_CFLAGS="" + REMOTE_DEBUGGING_LIBS="" + ;; +esac +fi + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hstrerror" >&5 +printf %s "checking for hstrerror... " >&6; } +if test ${ac_cv_func_hstrerror+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netdb.h> +int +main (void) +{ +void *x=hstrerror + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_hstrerror=yes +else case e in #( + e) ac_cv_func_hstrerror=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_hstrerror" >&5 +printf "%s\n" "$ac_cv_func_hstrerror" >&6; } + if test "x$ac_cv_func_hstrerror" = xyes +then : + +printf "%s\n" "#define HAVE_HSTRERROR 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getservbyname" >&5 +printf %s "checking for getservbyname... " >&6; } +if test ${ac_cv_func_getservbyname+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netdb.h> +int +main (void) +{ +void *x=getservbyname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getservbyname=yes +else case e in #( + e) ac_cv_func_getservbyname=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyname" >&5 +printf "%s\n" "$ac_cv_func_getservbyname" >&6; } + if test "x$ac_cv_func_getservbyname" = xyes +then : + +printf "%s\n" "#define HAVE_GETSERVBYNAME 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getservbyport" >&5 +printf %s "checking for getservbyport... " >&6; } +if test ${ac_cv_func_getservbyport+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netdb.h> +int +main (void) +{ +void *x=getservbyport + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getservbyport=yes +else case e in #( + e) ac_cv_func_getservbyport=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyport" >&5 +printf "%s\n" "$ac_cv_func_getservbyport" >&6; } + if test "x$ac_cv_func_getservbyport" = xyes +then : + +printf "%s\n" "#define HAVE_GETSERVBYPORT 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname" >&5 +printf %s "checking for gethostbyname... " >&6; } +if test ${ac_cv_func_gethostbyname+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netdb.h> +int +main (void) +{ +void *x=gethostbyname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_gethostbyname=yes +else case e in #( + e) ac_cv_func_gethostbyname=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyname" >&5 +printf "%s\n" "$ac_cv_func_gethostbyname" >&6; } + if test "x$ac_cv_func_gethostbyname" = xyes +then : + +printf "%s\n" "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr" >&5 +printf %s "checking for gethostbyaddr... " >&6; } +if test ${ac_cv_func_gethostbyaddr+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netdb.h> +int +main (void) +{ +void *x=gethostbyaddr + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_gethostbyaddr=yes +else case e in #( + e) ac_cv_func_gethostbyaddr=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyaddr" >&5 +printf "%s\n" "$ac_cv_func_gethostbyaddr" >&6; } + if test "x$ac_cv_func_gethostbyaddr" = xyes +then : + +printf "%s\n" "#define HAVE_GETHOSTBYADDR 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getprotobyname" >&5 +printf %s "checking for getprotobyname... " >&6; } +if test ${ac_cv_func_getprotobyname+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netdb.h> +int +main (void) +{ +void *x=getprotobyname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getprotobyname=yes +else case e in #( + e) ac_cv_func_getprotobyname=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getprotobyname" >&5 +printf "%s\n" "$ac_cv_func_getprotobyname" >&6; } + if test "x$ac_cv_func_getprotobyname" = xyes +then : + +printf "%s\n" "#define HAVE_GETPROTOBYNAME 1" >>confdefs.h + +fi + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_aton" >&5 +printf %s "checking for inet_aton... " >&6; } +if test ${ac_cv_func_inet_aton+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=inet_aton + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_inet_aton=yes +else case e in #( + e) ac_cv_func_inet_aton=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_aton" >&5 +printf "%s\n" "$ac_cv_func_inet_aton" >&6; } + if test "x$ac_cv_func_inet_aton" = xyes +then : + +printf "%s\n" "#define HAVE_INET_ATON 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa" >&5 +printf %s "checking for inet_ntoa... " >&6; } +if test ${ac_cv_func_inet_ntoa+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=inet_ntoa + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_inet_ntoa=yes +else case e in #( + e) ac_cv_func_inet_ntoa=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_ntoa" >&5 +printf "%s\n" "$ac_cv_func_inet_ntoa" >&6; } + if test "x$ac_cv_func_inet_ntoa" = xyes +then : + +printf "%s\n" "#define HAVE_INET_NTOA 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_pton" >&5 +printf %s "checking for inet_pton... " >&6; } +if test ${ac_cv_func_inet_pton+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=inet_pton + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_inet_pton=yes +else case e in #( + e) ac_cv_func_inet_pton=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_pton" >&5 +printf "%s\n" "$ac_cv_func_inet_pton" >&6; } + if test "x$ac_cv_func_inet_pton" = xyes +then : + +printf "%s\n" "#define HAVE_INET_PTON 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getpeername" >&5 +printf %s "checking for getpeername... " >&6; } +if test ${ac_cv_func_getpeername+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=getpeername + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getpeername=yes +else case e in #( + e) ac_cv_func_getpeername=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpeername" >&5 +printf "%s\n" "$ac_cv_func_getpeername" >&6; } + if test "x$ac_cv_func_getpeername" = xyes +then : + +printf "%s\n" "#define HAVE_GETPEERNAME 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getsockname" >&5 +printf %s "checking for getsockname... " >&6; } +if test ${ac_cv_func_getsockname+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=getsockname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getsockname=yes +else case e in #( + e) ac_cv_func_getsockname=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getsockname" >&5 +printf "%s\n" "$ac_cv_func_getsockname" >&6; } + if test "x$ac_cv_func_getsockname" = xyes +then : + +printf "%s\n" "#define HAVE_GETSOCKNAME 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for accept" >&5 +printf %s "checking for accept... " >&6; } +if test ${ac_cv_func_accept+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=accept + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_accept=yes +else case e in #( + e) ac_cv_func_accept=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_accept" >&5 +printf "%s\n" "$ac_cv_func_accept" >&6; } + if test "x$ac_cv_func_accept" = xyes +then : + +printf "%s\n" "#define HAVE_ACCEPT 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for bind" >&5 +printf %s "checking for bind... " >&6; } +if test ${ac_cv_func_bind+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=bind + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_bind=yes +else case e in #( + e) ac_cv_func_bind=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_bind" >&5 +printf "%s\n" "$ac_cv_func_bind" >&6; } + if test "x$ac_cv_func_bind" = xyes +then : + +printf "%s\n" "#define HAVE_BIND 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for connect" >&5 +printf %s "checking for connect... " >&6; } +if test ${ac_cv_func_connect+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=connect + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_connect=yes +else case e in #( + e) ac_cv_func_connect=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_connect" >&5 +printf "%s\n" "$ac_cv_func_connect" >&6; } + if test "x$ac_cv_func_connect" = xyes +then : + +printf "%s\n" "#define HAVE_CONNECT 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for listen" >&5 +printf %s "checking for listen... " >&6; } +if test ${ac_cv_func_listen+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=listen + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_listen=yes +else case e in #( + e) ac_cv_func_listen=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_listen" >&5 +printf "%s\n" "$ac_cv_func_listen" >&6; } + if test "x$ac_cv_func_listen" = xyes +then : + +printf "%s\n" "#define HAVE_LISTEN 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for recvfrom" >&5 +printf %s "checking for recvfrom... " >&6; } +if test ${ac_cv_func_recvfrom+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=recvfrom + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_recvfrom=yes +else case e in #( + e) ac_cv_func_recvfrom=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_recvfrom" >&5 +printf "%s\n" "$ac_cv_func_recvfrom" >&6; } + if test "x$ac_cv_func_recvfrom" = xyes +then : + +printf "%s\n" "#define HAVE_RECVFROM 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sendto" >&5 +printf %s "checking for sendto... " >&6; } +if test ${ac_cv_func_sendto+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=sendto + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_sendto=yes +else case e in #( + e) ac_cv_func_sendto=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_sendto" >&5 +printf "%s\n" "$ac_cv_func_sendto" >&6; } + if test "x$ac_cv_func_sendto" = xyes +then : + +printf "%s\n" "#define HAVE_SENDTO 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for setsockopt" >&5 +printf %s "checking for setsockopt... " >&6; } +if test ${ac_cv_func_setsockopt+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=setsockopt + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_setsockopt=yes +else case e in #( + e) ac_cv_func_setsockopt=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setsockopt" >&5 +printf "%s\n" "$ac_cv_func_setsockopt" >&6; } + if test "x$ac_cv_func_setsockopt" = xyes +then : + +printf "%s\n" "#define HAVE_SETSOCKOPT 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socket" >&5 +printf %s "checking for socket... " >&6; } +if test ${ac_cv_func_socket+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +int +main (void) +{ +void *x=socket + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_socket=yes +else case e in #( + e) ac_cv_func_socket=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_socket" >&5 +printf "%s\n" "$ac_cv_func_socket" >&6; } + if test "x$ac_cv_func_socket" = xyes +then : + +printf "%s\n" "#define HAVE_SOCKET 1" >>confdefs.h + +fi + + + + +# On some systems, setgroups is in unistd.h, on others, in grp.h + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for setgroups" >&5 +printf %s "checking for setgroups... " >&6; } +if test ${ac_cv_func_setgroups+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <unistd.h> +#ifdef HAVE_GRP_H +#include <grp.h> +#endif + +int +main (void) +{ +void *x=setgroups + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_setgroups=yes +else case e in #( + e) ac_cv_func_setgroups=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setgroups" >&5 +printf "%s\n" "$ac_cv_func_setgroups" >&6; } + if test "x$ac_cv_func_setgroups" = xyes +then : + +printf "%s\n" "#define HAVE_SETGROUPS 1" >>confdefs.h + +fi + + + + +ac_fn_check_decl "$LINENO" "MAXLOGNAME" "ac_cv_have_decl_MAXLOGNAME" "#include <sys/param.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_MAXLOGNAME" = xyes +then : + +printf "%s\n" "#define HAVE_MAXLOGNAME 1" >>confdefs.h + +fi + +ac_fn_check_decl "$LINENO" "UT_NAMESIZE" "ac_cv_have_decl_UT_NAMESIZE" "#include <utmp.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_UT_NAMESIZE" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_UT_NAMESIZE $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +printf "%s\n" "#define HAVE_UT_NAMESIZE 1" >>confdefs.h + +fi + +# musl libc redefines struct prctl_mm_map and conflicts with linux/prctl.h +if test "$ac_cv_libc" != musl +then : + +ac_fn_check_decl "$LINENO" "PR_SET_VMA_ANON_NAME" "ac_cv_have_decl_PR_SET_VMA_ANON_NAME" "#include <linux/prctl.h> + #include <sys/prctl.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_PR_SET_VMA_ANON_NAME" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_PR_SET_VMA_ANON_NAME $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +printf "%s\n" "#define _Py_HAVE_PR_SET_VMA_ANON_NAME 1" >>confdefs.h + +fi + + +fi +# check for openpty, login_tty, and forkpty + + + for ac_func in openpty +do : + ac_fn_c_check_func "$LINENO" "openpty" "ac_cv_func_openpty" +if test "x$ac_cv_func_openpty" = xyes +then : + printf "%s\n" "#define HAVE_OPENPTY 1" >>confdefs.h + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5 +printf %s "checking for openpty in -lutil... " >&6; } +if test ${ac_cv_lib_util_openpty+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lutil $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char openpty (void); +int +main (void) +{ +return openpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_util_openpty=yes +else case e in #( + e) ac_cv_lib_util_openpty=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5 +printf "%s\n" "$ac_cv_lib_util_openpty" >&6; } +if test "x$ac_cv_lib_util_openpty" = xyes +then : + printf "%s\n" "#define HAVE_OPENPTY 1" >>confdefs.h + LIBS="$LIBS -lutil" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openpty in -lbsd" >&5 +printf %s "checking for openpty in -lbsd... " >&6; } +if test ${ac_cv_lib_bsd_openpty+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char openpty (void); +int +main (void) +{ +return openpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bsd_openpty=yes +else case e in #( + e) ac_cv_lib_bsd_openpty=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_openpty" >&5 +printf "%s\n" "$ac_cv_lib_bsd_openpty" >&6; } +if test "x$ac_cv_lib_bsd_openpty" = xyes +then : + printf "%s\n" "#define HAVE_OPENPTY 1" >>confdefs.h + LIBS="$LIBS -lbsd" +fi + ;; +esac +fi + ;; +esac +fi + +done +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing login_tty" >&5 +printf %s "checking for library containing login_tty... " >&6; } +if test ${ac_cv_search_login_tty+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char login_tty (void); +int +main (void) +{ +return login_tty (); + ; + return 0; +} +_ACEOF +for ac_lib in '' util +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_login_tty=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_login_tty+y} +then : + break +fi +done +if test ${ac_cv_search_login_tty+y} +then : + +else case e in #( + e) ac_cv_search_login_tty=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_login_tty" >&5 +printf "%s\n" "$ac_cv_search_login_tty" >&6; } +ac_res=$ac_cv_search_login_tty +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +printf "%s\n" "#define HAVE_LOGIN_TTY 1" >>confdefs.h + + +fi + + + for ac_func in forkpty +do : + ac_fn_c_check_func "$LINENO" "forkpty" "ac_cv_func_forkpty" +if test "x$ac_cv_func_forkpty" = xyes +then : + printf "%s\n" "#define HAVE_FORKPTY 1" >>confdefs.h + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lutil" >&5 +printf %s "checking for forkpty in -lutil... " >&6; } +if test ${ac_cv_lib_util_forkpty+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lutil $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char forkpty (void); +int +main (void) +{ +return forkpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_util_forkpty=yes +else case e in #( + e) ac_cv_lib_util_forkpty=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_forkpty" >&5 +printf "%s\n" "$ac_cv_lib_util_forkpty" >&6; } +if test "x$ac_cv_lib_util_forkpty" = xyes +then : + printf "%s\n" "#define HAVE_FORKPTY 1" >>confdefs.h + LIBS="$LIBS -lutil" +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lbsd" >&5 +printf %s "checking for forkpty in -lbsd... " >&6; } +if test ${ac_cv_lib_bsd_forkpty+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char forkpty (void); +int +main (void) +{ +return forkpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bsd_forkpty=yes +else case e in #( + e) ac_cv_lib_bsd_forkpty=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_forkpty" >&5 +printf "%s\n" "$ac_cv_lib_bsd_forkpty" >&6; } +if test "x$ac_cv_lib_bsd_forkpty" = xyes +then : + printf "%s\n" "#define HAVE_FORKPTY 1" >>confdefs.h + LIBS="$LIBS -lbsd" +fi + ;; +esac +fi + ;; +esac +fi + +done + +# check for long file support functions +ac_fn_c_check_func "$LINENO" "fseek64" "ac_cv_func_fseek64" +if test "x$ac_cv_func_fseek64" = xyes +then : + printf "%s\n" "#define HAVE_FSEEK64 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" +if test "x$ac_cv_func_fseeko" = xyes +then : + printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fstatvfs" "ac_cv_func_fstatvfs" +if test "x$ac_cv_func_fstatvfs" = xyes +then : + printf "%s\n" "#define HAVE_FSTATVFS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ftell64" "ac_cv_func_ftell64" +if test "x$ac_cv_func_ftell64" = xyes +then : + printf "%s\n" "#define HAVE_FTELL64 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ftello" "ac_cv_func_ftello" +if test "x$ac_cv_func_ftello" = xyes +then : + printf "%s\n" "#define HAVE_FTELLO 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "statvfs" "ac_cv_func_statvfs" +if test "x$ac_cv_func_statvfs" = xyes +then : + printf "%s\n" "#define HAVE_STATVFS 1" >>confdefs.h + +fi + + +ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2" +if test "x$ac_cv_func_dup2" = xyes +then : + printf "%s\n" "#define HAVE_DUP2 1" >>confdefs.h + +else case e in #( + e) case " $LIBOBJS " in + *" dup2.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS dup2.$ac_objext" + ;; +esac + ;; +esac +fi + + + for ac_func in getpgrp +do : + ac_fn_c_check_func "$LINENO" "getpgrp" "ac_cv_func_getpgrp" +if test "x$ac_cv_func_getpgrp" = xyes +then : + printf "%s\n" "#define HAVE_GETPGRP 1" >>confdefs.h + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +getpgrp(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +printf "%s\n" "#define GETPGRP_HAVE_ARG 1" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +done + + for ac_func in setpgrp +do : + ac_fn_c_check_func "$LINENO" "setpgrp" "ac_cv_func_setpgrp" +if test "x$ac_cv_func_setpgrp" = xyes +then : + printf "%s\n" "#define HAVE_SETPGRP 1" >>confdefs.h + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <unistd.h> +int +main (void) +{ +setpgrp(0,0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +printf "%s\n" "#define SETPGRP_HAVE_ARG 1" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +done + +# check for namespace functions +ac_fn_c_check_func "$LINENO" "setns" "ac_cv_func_setns" +if test "x$ac_cv_func_setns" = xyes +then : + printf "%s\n" "#define HAVE_SETNS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "unshare" "ac_cv_func_unshare" +if test "x$ac_cv_func_unshare" = xyes +then : + printf "%s\n" "#define HAVE_UNSHARE 1" >>confdefs.h + +fi + + + + for ac_func in clock_gettime +do : + ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" +if test "x$ac_cv_func_clock_gettime" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 +printf %s "checking for clock_gettime in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_gettime+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (void); +int +main (void) +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_gettime=yes +else case e in #( + e) ac_cv_lib_rt_clock_gettime=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_gettime" >&6; } +if test "x$ac_cv_lib_rt_clock_gettime" = xyes +then : + + LIBS="$LIBS -lrt" + printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h + + +printf "%s\n" "#define TIMEMODULE_LIB rt" >>confdefs.h + + +fi + + ;; +esac +fi + +done + + + for ac_func in clock_getres +do : + ac_fn_c_check_func "$LINENO" "clock_getres" "ac_cv_func_clock_getres" +if test "x$ac_cv_func_clock_getres" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_GETRES 1" >>confdefs.h + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_getres in -lrt" >&5 +printf %s "checking for clock_getres in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_getres+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char clock_getres (void); +int +main (void) +{ +return clock_getres (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_getres=yes +else case e in #( + e) ac_cv_lib_rt_clock_getres=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_getres" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_getres" >&6; } +if test "x$ac_cv_lib_rt_clock_getres" = xyes +then : + + printf "%s\n" "#define HAVE_CLOCK_GETRES 1" >>confdefs.h + + +fi + + ;; +esac +fi + +done + +# On Android and iOS, clock_settime can be linked (so it is found by +# configure), but when used in an unprivileged process, it crashes rather than +# returning an error. Force the symbol off. +if test "$ac_sys_system" != "Linux-android" && test "$ac_sys_system" != "iOS" +then + + for ac_func in clock_settime +do : + ac_fn_c_check_func "$LINENO" "clock_settime" "ac_cv_func_clock_settime" +if test "x$ac_cv_func_clock_settime" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_settime in -lrt" >&5 +printf %s "checking for clock_settime in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_settime+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char clock_settime (void); +int +main (void) +{ +return clock_settime (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_settime=yes +else case e in #( + e) ac_cv_lib_rt_clock_settime=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_settime" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_settime" >&6; } +if test "x$ac_cv_lib_rt_clock_settime" = xyes +then : + + printf "%s\n" "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h + + +fi + + ;; +esac +fi + +done +fi + +# On Android before API level 23, clock_nanosleep returns the wrong value when +# interrupted by a signal (https://issuetracker.google.com/issues/216495770). +if ! { test "$ac_sys_system" = "Linux-android" && + test "$ANDROID_API_LEVEL" -lt 23; }; then + + for ac_func in clock_nanosleep +do : + ac_fn_c_check_func "$LINENO" "clock_nanosleep" "ac_cv_func_clock_nanosleep" +if test "x$ac_cv_func_clock_nanosleep" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_NANOSLEEP 1" >>confdefs.h + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_nanosleep in -lrt" >&5 +printf %s "checking for clock_nanosleep in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_nanosleep+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char clock_nanosleep (void); +int +main (void) +{ +return clock_nanosleep (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_nanosleep=yes +else case e in #( + e) ac_cv_lib_rt_clock_nanosleep=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_nanosleep" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_nanosleep" >&6; } +if test "x$ac_cv_lib_rt_clock_nanosleep" = xyes +then : + + printf "%s\n" "#define HAVE_CLOCK_NANOSLEEP 1" >>confdefs.h + + +fi + + ;; +esac +fi + +done +fi + + + for ac_func in nanosleep +do : + ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" +if test "x$ac_cv_func_nanosleep" = xyes +then : + printf "%s\n" "#define HAVE_NANOSLEEP 1" >>confdefs.h + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5 +printf %s "checking for nanosleep in -lrt... " >&6; } +if test ${ac_cv_lib_rt_nanosleep+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char nanosleep (void); +int +main (void) +{ +return nanosleep (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_nanosleep=yes +else case e in #( + e) ac_cv_lib_rt_nanosleep=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5 +printf "%s\n" "$ac_cv_lib_rt_nanosleep" >&6; } +if test "x$ac_cv_lib_rt_nanosleep" = xyes +then : + + printf "%s\n" "#define HAVE_NANOSLEEP 1" >>confdefs.h + + +fi + + ;; +esac +fi + +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for major, minor, and makedev" >&5 +printf %s "checking for major, minor, and makedev... " >&6; } +if test ${ac_cv_device_macros+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if defined(MAJOR_IN_MKDEV) +#include <sys/mkdev.h> +#elif defined(MAJOR_IN_SYSMACROS) +#include <sys/types.h> +#include <sys/sysmacros.h> +#else +#include <sys/types.h> +#endif + +int +main (void) +{ + + makedev(major(0),minor(0)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_device_macros=yes +else case e in #( + e) ac_cv_device_macros=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_device_macros" >&5 +printf "%s\n" "$ac_cv_device_macros" >&6; } +if test "x$ac_cv_device_macros" = xyes +then : + + +printf "%s\n" "#define HAVE_DEVICE_MACROS 1" >>confdefs.h + + +fi + + +printf "%s\n" "#define SYS_SELECT_WITH_SYS_TIME 1" >>confdefs.h + + +# On OSF/1 V5.1, getaddrinfo is available, but a define +# for [no]getaddrinfo in netdb.h. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 +printf %s "checking for getaddrinfo... " >&6; } +if test ${ac_cv_func_getaddrinfo+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> + +int +main (void) +{ +getaddrinfo(NULL, NULL, NULL, NULL); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_func_getaddrinfo=yes +else case e in #( + e) ac_cv_func_getaddrinfo=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getaddrinfo" >&5 +printf "%s\n" "$ac_cv_func_getaddrinfo" >&6; } + +if test "x$ac_cv_func_getaddrinfo" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking getaddrinfo bug" >&5 +printf %s "checking getaddrinfo bug... " >&6; } +if test ${ac_cv_buggy_getaddrinfo+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + +if test "$ac_sys_system" = "Linux-android" || test "$ac_sys_system" = "iOS"; then + ac_cv_buggy_getaddrinfo="no" +elif test "${enable_ipv6+set}" = set; then + ac_cv_buggy_getaddrinfo="no -- configured with --(en|dis)able-ipv6" +else + ac_cv_buggy_getaddrinfo=yes +fi +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <sys/types.h> +#include <netdb.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> + +int main(void) +{ + int passive, gaierr, inet4 = 0, inet6 = 0; + struct addrinfo hints, *ai, *aitop; + char straddr[INET6_ADDRSTRLEN], strport[16]; + + for (passive = 0; passive <= 1; passive++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = passive ? AI_PASSIVE : 0; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { + (void)gai_strerror(gaierr); + goto bad; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_addr == NULL || + ai->ai_addrlen == 0 || + getnameinfo(ai->ai_addr, ai->ai_addrlen, + straddr, sizeof(straddr), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + goto bad; + } + switch (ai->ai_family) { + case AF_INET: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "0.0.0.0") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "127.0.0.1") != 0) { + goto bad; + } + } + inet4++; + break; + case AF_INET6: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "::") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "::1") != 0) { + goto bad; + } + } + inet6++; + break; + case AF_UNSPEC: + goto bad; + break; + default: + /* another family support? */ + break; + } + } + freeaddrinfo(aitop); + aitop = NULL; + } + + if (!(inet4 == 0 || inet4 == 2)) + goto bad; + if (!(inet6 == 0 || inet6 == 2)) + goto bad; + + if (aitop) + freeaddrinfo(aitop); + return 0; + + bad: + if (aitop) + freeaddrinfo(aitop); + return 1; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_buggy_getaddrinfo=no +else case e in #( + e) ac_cv_buggy_getaddrinfo=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_buggy_getaddrinfo" >&5 +printf "%s\n" "$ac_cv_buggy_getaddrinfo" >&6; } + + +fi + +if test "$ac_cv_func_getaddrinfo" = no -o "$ac_cv_buggy_getaddrinfo" = yes +then + if test "x$ipv6" = xyes +then : + + as_fn_error $? "You must get working getaddrinfo() function or pass the \"--disable-ipv6\" option to configure." "$LINENO" 5 + +fi +else + +printf "%s\n" "#define HAVE_GETADDRINFO 1" >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo" +if test "x$ac_cv_func_getnameinfo" = xyes +then : + printf "%s\n" "#define HAVE_GETNAMEINFO 1" >>confdefs.h + +fi + + +# checks for structures +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +printf %s "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if test ${ac_cv_struct_tm+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <time.h> + +int +main (void) +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_tm=time.h +else case e in #( + e) ac_cv_struct_tm=sys/time.h ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +printf "%s\n" "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +printf "%s\n" "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include <sys/types.h> +#include <$ac_cv_struct_tm> + +" +if test "x$ac_cv_member_struct_tm_tm_zone" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_TM_TM_ZONE 1" >>confdefs.h + + +fi + +if test "$ac_cv_member_struct_tm_tm_zone" = yes; then + +printf "%s\n" "#define HAVE_TM_ZONE 1" >>confdefs.h + +else + ac_fn_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include <time.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_tzname" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_TZNAME $ac_have_decl" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5 +printf %s "checking for tzname... " >&6; } +if test ${ac_cv_var_tzname+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <time.h> +#if !HAVE_DECL_TZNAME +extern char *tzname[]; +#endif + +int +main (void) +{ +return tzname[0][0]; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_var_tzname=yes +else case e in #( + e) ac_cv_var_tzname=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5 +printf "%s\n" "$ac_cv_var_tzname" >&6; } + if test $ac_cv_var_tzname = yes; then + +printf "%s\n" "#define HAVE_TZNAME 1" >>confdefs.h + + fi +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_rdev" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_RDEV 1" >>confdefs.h + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blksize" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BLKSIZE 1" >>confdefs.h + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_flags" "ac_cv_member_struct_stat_st_flags" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_flags" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_FLAGS 1" >>confdefs.h + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_gen" "ac_cv_member_struct_stat_st_gen" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_gen" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_GEN 1" >>confdefs.h + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_birthtime" "ac_cv_member_struct_stat_st_birthtime" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_birthtime" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1" >>confdefs.h + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blocks" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BLOCKS 1" >>confdefs.h + + +fi + +ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" " + #include <sys/types.h> + #include <pwd.h> + +" +if test "x$ac_cv_member_struct_passwd_pw_gecos" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_PASSWD_PW_GECOS 1" >>confdefs.h + + +fi +ac_fn_c_check_member "$LINENO" "struct passwd" "pw_passwd" "ac_cv_member_struct_passwd_pw_passwd" " + #include <sys/types.h> + #include <pwd.h> + +" +if test "x$ac_cv_member_struct_passwd_pw_passwd" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_PASSWD_PW_PASSWD 1" >>confdefs.h + + +fi + +# Issue #21085: In Cygwin, siginfo_t does not have si_band field. +ac_fn_c_check_member "$LINENO" "siginfo_t" "si_band" "ac_cv_member_siginfo_t_si_band" "#include <signal.h> +" +if test "x$ac_cv_member_siginfo_t_si_band" = xyes +then : + +printf "%s\n" "#define HAVE_SIGINFO_T_SI_BAND 1" >>confdefs.h + + +fi + + +if test "$ac_cv_func_statx" = yes; then + # Some systems have the definitions of the mask bits without having the + # corresponding members in struct statx. Check for members added after Linux + # 4.11 (when statx itself was added). + ac_fn_c_check_member "$LINENO" "struct statx" "stx_mnt_id" "ac_cv_member_struct_statx_stx_mnt_id" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_mnt_id" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_MNT_ID 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_mem_align" "ac_cv_member_struct_statx_stx_dio_mem_align" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_dio_mem_align" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN 1" >>confdefs.h + + +fi + + # stx_dio_offset_align was added together with stx_dio_mem_align + ac_fn_c_check_member "$LINENO" "struct statx" "stx_subvol" "ac_cv_member_struct_statx_stx_subvol" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_subvol" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_SUBVOL 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct statx" "stx_atomic_write_unit_min" "ac_cv_member_struct_statx_stx_atomic_write_unit_min" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_atomic_write_unit_min" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN 1" >>confdefs.h + + +fi + + # stx_atomic_write_unit_max and stx_atomic_write_segments_max were added + # together with stx_atomic_write_unit_min + ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_read_offset_align" "ac_cv_member_struct_statx_stx_dio_read_offset_align" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_dio_read_offset_align" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN 1" >>confdefs.h + + +fi + + # stx_atomic_write_unit_max_opt was added in Linux 6.16, but is controlled by + # the STATX_WRITE_ATOMIC mask bit added in Linux 6.11, so having the mask bit + # doesn't imply having the member. + ac_fn_c_check_member "$LINENO" "struct statx" "stx_atomic_write_unit_max_opt" "ac_cv_member_struct_statx_stx_atomic_write_unit_max_opt" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_atomic_write_unit_max_opt" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT 1" >>confdefs.h + + +fi + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for time.h that defines altzone" >&5 +printf %s "checking for time.h that defines altzone... " >&6; } +if test ${ac_cv_header_time_altzone+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <time.h> +int +main (void) +{ +return altzone; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_header_time_altzone=yes +else case e in #( + e) ac_cv_header_time_altzone=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time_altzone" >&5 +printf "%s\n" "$ac_cv_header_time_altzone" >&6; } +if test $ac_cv_header_time_altzone = yes; then + +printf "%s\n" "#define HAVE_ALTZONE 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for addrinfo" >&5 +printf %s "checking for addrinfo... " >&6; } +if test ${ac_cv_struct_addrinfo+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <netdb.h> +int +main (void) +{ +struct addrinfo a + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_addrinfo=yes +else case e in #( + e) ac_cv_struct_addrinfo=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_addrinfo" >&5 +printf "%s\n" "$ac_cv_struct_addrinfo" >&6; } +if test $ac_cv_struct_addrinfo = yes; then + +printf "%s\n" "#define HAVE_ADDRINFO 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sockaddr_storage" >&5 +printf %s "checking for sockaddr_storage... " >&6; } +if test ${ac_cv_struct_sockaddr_storage+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# include <sys/types.h> +# include <sys/socket.h> +int +main (void) +{ +struct sockaddr_storage s + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_sockaddr_storage=yes +else case e in #( + e) ac_cv_struct_sockaddr_storage=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_storage" >&5 +printf "%s\n" "$ac_cv_struct_sockaddr_storage" >&6; } +if test $ac_cv_struct_sockaddr_storage = yes; then + +printf "%s\n" "#define HAVE_SOCKADDR_STORAGE 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sockaddr_alg" >&5 +printf %s "checking for sockaddr_alg... " >&6; } +if test ${ac_cv_struct_sockaddr_alg+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# include <sys/types.h> +# include <sys/socket.h> +# include <linux/if_alg.h> +int +main (void) +{ +struct sockaddr_alg s + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_sockaddr_alg=yes +else case e in #( + e) ac_cv_struct_sockaddr_alg=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_alg" >&5 +printf "%s\n" "$ac_cv_struct_sockaddr_alg" >&6; } +if test $ac_cv_struct_sockaddr_alg = yes; then + +printf "%s\n" "#define HAVE_SOCKADDR_ALG 1" >>confdefs.h + +fi + +# checks for compiler characteristics + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +printf %s "checking for an ANSI C-conforming const... " >&6; } +if test ${ac_cv_c_const+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* IBM XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* IBM XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_const=yes +else case e in #( + e) ac_cv_c_const=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +printf "%s\n" "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +printf "%s\n" "#define const /**/" >>confdefs.h + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working signed char" >&5 +printf %s "checking for working signed char... " >&6; } +if test ${ac_cv_working_signed_char_c+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +signed char c; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_working_signed_char_c=yes +else case e in #( + e) ac_cv_working_signed_char_c=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_signed_char_c" >&5 +printf "%s\n" "$ac_cv_working_signed_char_c" >&6; } +if test "x$ac_cv_working_signed_char_c" = xno +then : + + +printf "%s\n" "#define signed /**/" >>confdefs.h + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for prototypes" >&5 +printf %s "checking for prototypes... " >&6; } +if test ${ac_cv_function_prototypes+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo(int x) { return 0; } +int +main (void) +{ +return foo(10); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_function_prototypes=yes +else case e in #( + e) ac_cv_function_prototypes=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_function_prototypes" >&5 +printf "%s\n" "$ac_cv_function_prototypes" >&6; } +if test "x$ac_cv_function_prototypes" = xyes +then : + + +printf "%s\n" "#define HAVE_PROTOTYPES 1" >>confdefs.h + + +fi + + +# check for socketpair + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socketpair" >&5 +printf %s "checking for socketpair... " >&6; } +if test ${ac_cv_func_socketpair+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> + +int +main (void) +{ +void *x=socketpair + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_socketpair=yes +else case e in #( + e) ac_cv_func_socketpair=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_socketpair" >&5 +printf "%s\n" "$ac_cv_func_socketpair" >&6; } + if test "x$ac_cv_func_socketpair" = xyes +then : + +printf "%s\n" "#define HAVE_SOCKETPAIR 1" >>confdefs.h + +fi + + + + +# check if sockaddr has sa_len member +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if sockaddr has sa_len member" >&5 +printf %s "checking if sockaddr has sa_len member... " >&6; } +if test ${ac_cv_struct_sockaddr_sa_len+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/socket.h> +int +main (void) +{ +struct sockaddr x; +x.sa_len = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_sockaddr_sa_len=yes +else case e in #( + e) ac_cv_struct_sockaddr_sa_len=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_sa_len" >&5 +printf "%s\n" "$ac_cv_struct_sockaddr_sa_len" >&6; } +if test "x$ac_cv_struct_sockaddr_sa_len" = xyes +then : + + +printf "%s\n" "#define HAVE_SOCKADDR_SA_LEN 1" >>confdefs.h + + +fi + +# sigh -- gethostbyname_r is a mess; it can have 3, 5 or 6 arguments :-( + + +ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" +if test "x$ac_cv_func_gethostbyname_r" = xyes +then : + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 6 args" >&5 +printf %s "checking gethostbyname_r with 6 args... " >&6; } + OLD_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS $MY_CPPFLAGS $MY_THREAD_CPPFLAGS $MY_CFLAGS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# include <netdb.h> + +int +main (void) +{ + + char *name; + struct hostent *he, *res; + char buffer[2048]; + int buflen = 2048; + int h_errnop; + + (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop) + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h + + +printf "%s\n" "#define HAVE_GETHOSTBYNAME_R_6_ARG 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 5 args" >&5 +printf %s "checking gethostbyname_r with 5 args... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# include <netdb.h> + +int +main (void) +{ + + char *name; + struct hostent *he; + char buffer[2048]; + int buflen = 2048; + int h_errnop; + + (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop) + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h + + +printf "%s\n" "#define HAVE_GETHOSTBYNAME_R_5_ARG 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 3 args" >&5 +printf %s "checking gethostbyname_r with 3 args... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# include <netdb.h> + +int +main (void) +{ + + char *name; + struct hostent *he; + struct hostent_data data; + + (void) gethostbyname_r(name, he, &data); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h + + +printf "%s\n" "#define HAVE_GETHOSTBYNAME_R_3_ARG 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$OLD_CFLAGS + +else case e in #( + e) + ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes +then : + printf "%s\n" "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h + +fi + + ;; +esac +fi + + + + + + + +# checks for system services +# (none yet) + +# Linux requires this for correct f.p. operations +ac_fn_c_check_func "$LINENO" "__fpu_control" "ac_cv_func___fpu_control" +if test "x$ac_cv_func___fpu_control" = xyes +then : + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __fpu_control in -lieee" >&5 +printf %s "checking for __fpu_control in -lieee... " >&6; } +if test ${ac_cv_lib_ieee___fpu_control+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lieee $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char __fpu_control (void); +int +main (void) +{ +return __fpu_control (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ieee___fpu_control=yes +else case e in #( + e) ac_cv_lib_ieee___fpu_control=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee___fpu_control" >&5 +printf "%s\n" "$ac_cv_lib_ieee___fpu_control" >&6; } +if test "x$ac_cv_lib_ieee___fpu_control" = xyes +then : + printf "%s\n" "#define HAVE_LIBIEEE 1" >>confdefs.h + + LIBS="-lieee $LIBS" + +fi + + ;; +esac +fi + + +# check for --with-libm=... + +case $ac_sys_system in +Darwin) ;; +*) LIBM=-lm +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-libm=STRING" >&5 +printf %s "checking for --with-libm=STRING... " >&6; } + +# Check whether --with-libm was given. +if test ${with_libm+y} +then : + withval=$with_libm; +if test "$withval" = no +then LIBM= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: force LIBM empty" >&5 +printf "%s\n" "force LIBM empty" >&6; } +elif test "$withval" != yes +then LIBM=$withval + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5 +printf "%s\n" "set LIBM=\"$withval\"" >&6; } +else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5 +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5 +printf "%s\n" "default LIBM=\"$LIBM\"" >&6; } ;; +esac +fi + + +# check for --with-libc=... + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-libc=STRING" >&5 +printf %s "checking for --with-libc=STRING... " >&6; } + +# Check whether --with-libc was given. +if test ${with_libc+y} +then : + withval=$with_libc; +if test "$withval" = no +then LIBC= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: force LIBC empty" >&5 +printf "%s\n" "force LIBC empty" >&6; } +elif test "$withval" != yes +then LIBC=$withval + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5 +printf "%s\n" "set LIBC=\"$withval\"" >&6; } +else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5 +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5 +printf "%s\n" "default LIBC=\"$LIBC\"" >&6; } ;; +esac +fi + + +# ************************************** +# * Check for gcc x64 inline assembler * +# ************************************** + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x64 gcc inline assembler" >&5 +printf %s "checking for x64 gcc inline assembler... " >&6; } +if test ${ac_cv_gcc_asm_for_x64+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + __asm__ __volatile__ ("movq %rcx, %rax"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_gcc_asm_for_x64=yes +else case e in #( + e) ac_cv_gcc_asm_for_x64=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_x64" >&5 +printf "%s\n" "$ac_cv_gcc_asm_for_x64" >&6; } + +if test "x$ac_cv_gcc_asm_for_x64" = xyes +then : + + +printf "%s\n" "#define HAVE_GCC_ASM_FOR_X64 1" >>confdefs.h + + +fi + +# ************************************************** +# * Check for various properties of floating point * +# ************************************************** + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether float word ordering is bigendian" >&5 +printf %s "checking whether float word ordering is bigendian... " >&6; } +if test ${ax_cv_c_float_words_bigendian+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + +ax_cv_c_float_words_bigendian=unknown +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#include <stdlib.h> + +static double m[] = {9.090423496703681e+223, 0.0}; + +int main (int argc, char *argv[]) +{ + m[atoi (argv[1])] += atof (argv[2]); + return m[atoi (argv[3])] > 0.0; +} + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + +if grep noonsees conftest* > /dev/null ; then + ax_cv_c_float_words_bigendian=yes +fi +if grep seesnoon conftest* >/dev/null ; then + if test "$ax_cv_c_float_words_bigendian" = unknown; then + ax_cv_c_float_words_bigendian=no + else + ax_cv_c_float_words_bigendian=unknown + fi +fi + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_float_words_bigendian" >&5 +printf "%s\n" "$ax_cv_c_float_words_bigendian" >&6; } + +case $ax_cv_c_float_words_bigendian in + yes) + +printf "%s\n" "#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1" >>confdefs.h + ;; + no) + +printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h + ;; + *) + as_fn_error $? "Unknown float word ordering. You need to manually preset ax_cv_c_float_words_bigendian=no (or yes) according to your system." "$LINENO" 5 ;; +esac + + + +# The short float repr introduced in Python 3.1 requires the +# correctly-rounded string <-> double conversion functions from +# Python/dtoa.c, which in turn require that the FPU uses 53-bit +# rounding; this is a problem on x86, where the x87 FPU has a default +# rounding precision of 64 bits. For gcc/x86, we can fix this by +# using inline assembler to get and set the x87 FPU control word. + +# This inline assembler syntax works for icx and may also work for +# suncc and icc, so we try it on all platforms. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 +printf %s "checking whether we can use gcc inline assembler to get and set x87 control word... " >&6; } +if test ${ac_cv_gcc_asm_for_x87+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_gcc_asm_for_x87=yes +else case e in #( + e) ac_cv_gcc_asm_for_x87=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_x87" >&5 +printf "%s\n" "$ac_cv_gcc_asm_for_x87" >&6; } +if test "x$ac_cv_gcc_asm_for_x87" = xyes +then : + + +printf "%s\n" "#define HAVE_GCC_ASM_FOR_X87 1" >>confdefs.h + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set mc68881 fpcr" >&5 +printf %s "checking whether we can use gcc inline assembler to get and set mc68881 fpcr... " >&6; } +if test ${ac_cv_gcc_asm_for_mc68881+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + unsigned int fpcr; + __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm" (fpcr)); + __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm" (fpcr)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_gcc_asm_for_mc68881=yes +else case e in #( + e) ac_cv_gcc_asm_for_mc68881=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_mc68881" >&5 +printf "%s\n" "$ac_cv_gcc_asm_for_mc68881" >&6; } +if test "x$ac_cv_gcc_asm_for_mc68881" = xyes +then : + + +printf "%s\n" "#define HAVE_GCC_ASM_FOR_MC68881 1" >>confdefs.h + + +fi + +# Detect whether system arithmetic is subject to x87-style double +# rounding issues. The result of this test has little meaning on non +# IEEE 754 platforms. On IEEE 754, test should return 1 if rounding +# mode is round-to-nearest and double rounding issues are present, and +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5 +printf %s "checking for x87-style double rounding... " >&6; } +if test ${ac_cv_x87_double_rounding+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +# $BASECFLAGS may affect the result +ac_save_cc="$CC" +CC="$CC $BASECFLAGS" +if test "$cross_compiling" = yes +then : + ac_cv_x87_double_rounding=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdlib.h> +#include <math.h> +int main(void) { + volatile double x, y, z; + /* 1./(1-2**-53) -> 1+2**-52 (correct), 1.0 (double rounding) */ + x = 0.99999999999999989; /* 1-2**-53 */ + y = 1./x; + if (y != 1.) + exit(0); + /* 1e16+2.99999 -> 1e16+2. (correct), 1e16+4. (double rounding) */ + x = 1e16; + y = 2.99999; + z = x + y; + if (z != 1e16+4.) + exit(0); + /* both tests show evidence of double rounding */ + exit(1); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_x87_double_rounding=no +else case e in #( + e) ac_cv_x87_double_rounding=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CC="$ac_save_cc" + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_x87_double_rounding" >&5 +printf "%s\n" "$ac_cv_x87_double_rounding" >&6; } + +if test "x$ac_cv_x87_double_rounding" = xyes +then : + + +printf "%s\n" "#define X87_DOUBLE_ROUNDING 1" >>confdefs.h + + +fi + +# ************************************ +# * Check for mathematical functions * +# ************************************ + +LIBS_SAVE=$LIBS +LIBS="$LIBS $LIBM" + + + for ac_func in acosh asinh atanh erf erfc expm1 log1p log2 +do : + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | sed "$as_sed_sh"` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_func" | sed "$as_sed_cpp"` 1 +_ACEOF + +else case e in #( + e) as_fn_error $? "Python requires C99 compatible libm" "$LINENO" 5 + ;; +esac +fi + +done + +ac_func= +for ac_item in $ac_func_c_list +do + if test $ac_func; then + ac_fn_c_check_func "$LINENO" $ac_func ac_cv_func_$ac_func + if eval test \"x\$ac_cv_func_$ac_func\" = xyes; then + echo "#define $ac_item 1" >> confdefs.h + fi + ac_func= + else + ac_func=$ac_item + fi +done + + + + + + + +LIBS=$LIBS_SAVE + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX semaphores are enabled" >&5 +printf %s "checking whether POSIX semaphores are enabled... " >&6; } +if test ${ac_cv_posix_semaphores_enabled+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_posix_semaphores_enabled=yes +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <unistd.h> + #include <fcntl.h> + #include <stdio.h> + #include <semaphore.h> + #include <sys/stat.h> + + int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + sem_unlink("/autoconf"); + return 0; + } + + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_posix_semaphores_enabled=yes +else case e in #( + e) ac_cv_posix_semaphores_enabled=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_posix_semaphores_enabled" >&5 +printf "%s\n" "$ac_cv_posix_semaphores_enabled" >&6; } +if test "x$ac_cv_posix_semaphores_enabled" = xno +then : + + +printf "%s\n" "#define POSIX_SEMAPHORES_NOT_ENABLED 1" >>confdefs.h + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken sem_getvalue" >&5 +printf %s "checking for broken sem_getvalue... " >&6; } +if test ${ac_cv_broken_sem_getvalue+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_broken_sem_getvalue=yes +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <unistd.h> + #include <fcntl.h> + #include <stdio.h> + #include <semaphore.h> + #include <sys/stat.h> + + int main(void){ + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + sem_unlink("/autocftw"); + return res==-1 ? 1 : 0; + } + + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_broken_sem_getvalue=no +else case e in #( + e) ac_cv_broken_sem_getvalue=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_sem_getvalue" >&5 +printf "%s\n" "$ac_cv_broken_sem_getvalue" >&6; } +if test "x$ac_cv_broken_sem_getvalue" = xyes +then : + + +printf "%s\n" "#define HAVE_BROKEN_SEM_GETVALUE 1" >>confdefs.h + + +fi + +ac_fn_check_decl "$LINENO" "RTLD_LAZY" "ac_cv_have_decl_RTLD_LAZY" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_LAZY" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_LAZY $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_NOW" "ac_cv_have_decl_RTLD_NOW" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_NOW" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_NOW $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_GLOBAL" "ac_cv_have_decl_RTLD_GLOBAL" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_GLOBAL" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_GLOBAL $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_LOCAL" "ac_cv_have_decl_RTLD_LOCAL" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_LOCAL" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_LOCAL $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_NODELETE" "ac_cv_have_decl_RTLD_NODELETE" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_NODELETE" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_NODELETE $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_NOLOAD" "ac_cv_have_decl_RTLD_NOLOAD" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_NOLOAD" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_NOLOAD $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_DEEPBIND" "ac_cv_have_decl_RTLD_DEEPBIND" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_DEEPBIND" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_DEEPBIND $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_MEMBER" "ac_cv_have_decl_RTLD_MEMBER" "#include <dlfcn.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_MEMBER" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_RTLD_MEMBER $ac_have_decl" >>confdefs.h + + +# determine what size digit to use for Python's longs +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking digit size for Python's longs" >&5 +printf %s "checking digit size for Python's longs... " >&6; } +# Check whether --enable-big-digits was given. +if test ${enable_big_digits+y} +then : + enableval=$enable_big_digits; case $enable_big_digits in +yes) + enable_big_digits=30 ;; +no) + enable_big_digits=15 ;; +15|30) + ;; +*) + as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5 +printf "%s\n" "$enable_big_digits" >&6; } + +printf "%s\n" "#define PYLONG_BITS_IN_DIGIT $enable_big_digits" >>confdefs.h + + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 +printf "%s\n" "no value specified" >&6; } ;; +esac +fi + + +# check for wchar.h +ac_fn_c_check_header_compile "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" +if test "x$ac_cv_header_wchar_h" = xyes +then : + + +printf "%s\n" "#define HAVE_WCHAR_H 1" >>confdefs.h + + wchar_h="yes" + +else case e in #( + e) wchar_h="no" + ;; +esac +fi + + +# determine wchar_t size +if test "$wchar_h" = yes +then + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of wchar_t" >&5 +printf %s "checking size of wchar_t... " >&6; } +if test ${ac_cv_sizeof_wchar_t+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (wchar_t))" "ac_cv_sizeof_wchar_t" "#include <wchar.h> +" +then : + +else case e in #( + e) if test "$ac_cv_type_wchar_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (wchar_t) +See 'config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_wchar_t=0 + fi ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_wchar_t" >&5 +printf "%s\n" "$ac_cv_sizeof_wchar_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t" >>confdefs.h + + +fi + +# check whether wchar_t is signed or not +if test "$wchar_h" = yes +then + # check whether wchar_t is signed or not + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether wchar_t is signed" >&5 +printf %s "checking whether wchar_t is signed... " >&6; } +if test ${ac_cv_wchar_t_signed+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + if test "$cross_compiling" = yes +then : + ac_cv_wchar_t_signed=yes +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <wchar.h> + int main() + { + /* Success: exit code 0 */ + return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1); + } + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_wchar_t_signed=yes +else case e in #( + e) ac_cv_wchar_t_signed=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_wchar_t_signed" >&5 +printf "%s\n" "$ac_cv_wchar_t_signed" >&6; } +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether wchar_t is usable" >&5 +printf %s "checking whether wchar_t is usable... " >&6; } +# wchar_t is only usable if it maps to an unsigned type +if test "$ac_cv_sizeof_wchar_t" -ge 2 \ + -a "$ac_cv_wchar_t_signed" = "no" +then + +printf "%s\n" "#define HAVE_USABLE_WCHAR_T 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + +case $ac_sys_system/$ac_sys_release in +SunOS/*) + if test -f /etc/os-release; then + OS_NAME=$(awk -F= '/^NAME=/ {print substr($2,2,length($2)-2)}' /etc/os-release) + if test "x$OS_NAME" = "xOracle Solaris"; then + # bpo-43667: In Oracle Solaris, the internal form of wchar_t in + # non-Unicode locales is not Unicode and hence cannot be used directly. + # https://docs.oracle.com/cd/E37838_01/html/E61053/gmwke.html + +printf "%s\n" "#define HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION 1" >>confdefs.h + + fi + fi + ;; +esac + +# check for endianness + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +printf %s "checking whether byte ordering is bigendian... " >&6; } +if test ${ac_cv_c_bigendian+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main (void) +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \\ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \\ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main (void) +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_bigendian=yes +else case e in #( + e) ac_cv_c_bigendian=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main (void) +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main (void) +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_bigendian=yes +else case e in #( + e) ac_cv_c_bigendian=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes +then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +unsigned short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + unsigned short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + unsigned short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + unsigned short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + int + main (int argc, char **argv) + { + /* Intimidate the compiler so that it does not + optimize the arrays away. */ + char *p = argv[0]; + ascii_mm[1] = *p++; ebcdic_mm[1] = *p++; + ascii_ii[1] = *p++; ebcdic_ii[1] = *p++; + return use_ascii (argc) == use_ebcdic (*p); + } +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + if grep BIGenDianSyS conftest$ac_exeext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest$ac_exeext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main (void) +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_c_bigendian=no +else case e in #( + e) ac_cv_c_bigendian=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +printf "%s\n" "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +# ABI version string for Python extension modules. This appears between the +# periods in shared library file names, e.g. foo.<SOABI>.so. It is calculated +# from the following attributes which affect the ABI of this Python build (in +# this order): +# +# * The Python implementation (always 'cpython-' for us) +# * The major and minor version numbers +# * --disable-gil (adds a 't') +# * --with-pydebug (adds a 'd') +# +# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, +# would get a shared library ABI version tag of 'cpython-32dmu' and shared +# libraries would be named 'foo.cpython-32dmu.so'. +# +# In Python 3.2 and older, --with-wide-unicode added a 'u' flag. +# In Python 3.7 and older, --with-pymalloc added a 'm' flag. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ABIFLAGS" >&5 +printf %s "checking ABIFLAGS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ABIFLAGS" >&5 +printf "%s\n" "$ABIFLAGS" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5 +printf %s "checking SOABI... " >&6; } +SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${SOABI_PLATFORM:+-$SOABI_PLATFORM} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5 +printf "%s\n" "$SOABI" >&6; } + +# Release build, debug build (Py_DEBUG), and trace refs build (Py_TRACE_REFS) +# are ABI compatible +if test "$Py_DEBUG" = 'true'; then + # Similar to SOABI but remove "d" flag from ABIFLAGS + + ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${SOABI_PLATFORM:+-$SOABI_PLATFORM} + +printf "%s\n" "#define ALT_SOABI \"${ALT_SOABI}\"" >>confdefs.h + +fi + + +EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDVERSION" >&5 +printf %s "checking LDVERSION... " >&6; } +LDVERSION='$(VERSION)$(ABIFLAGS)' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5 +printf "%s\n" "$LDVERSION" >&6; } + +# Configure the flags and dependencies used when compiling shared modules. + + +MODULE_DEPS_SHARED='$(MODULE_DEPS_STATIC) $(EXPORTSYMS)' + +# On most platforms, extension modules aren't linked against libpython, so +# LIBPYTHON must be empty. +LIBPYTHON='' + +# On Android and Cygwin the shared libraries must be linked with libpython. +# LIBPYTHON is used by python-config, python3.pc, the commands for building the +# stdlib's own extension modules, and external package build systems via +# sysconfig, so its value must be suitable for all those contexts. +if test "$PY_ENABLE_SHARED" = "1" && ( test -n "$ANDROID_API_LEVEL" || test "$MACHDEP" = "cygwin"); then + MODULE_DEPS_SHARED="$MODULE_DEPS_SHARED \$(LDLIBRARY)" + LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" +fi + +# On iOS the shared libraries must be linked with the Python framework +if test "$ac_sys_system" = "iOS"; then + MODULE_DEPS_SHARED="$MODULE_DEPS_SHARED \$(PYTHONFRAMEWORKDIR)/\$(PYTHONFRAMEWORK)" +fi + +# Check for --with-platlibdir +# /usr/$PLATLIBDIR/python$(VERSION)$(ABI_THREAD) + +PLATLIBDIR="lib" # XXX: We should probably calculate the defauly from libdir, if defined. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-platlibdir" >&5 +printf %s "checking for --with-platlibdir... " >&6; } + +# Check whether --with-platlibdir was given. +if test ${with_platlibdir+y} +then : + withval=$with_platlibdir; +# ignore 3 options: +# --with-platlibdir +# --with-platlibdir= +# --without-platlibdir +if test -n "$withval" -a "$withval" != yes -a "$withval" != no +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + PLATLIBDIR="$withval" +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + + + +LIBDEST='${prefix}/${PLATLIBDIR}/python$(VERSION)$(ABI_THREAD)' +BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)$(ABI_THREAD)' + + +if test x$PLATFORM_TRIPLET = x; then + LIBPL='$(LIBDEST)'"/config-${LDVERSION}" +else + LIBPL='$(LIBDEST)'"/config-${LDVERSION}-${PLATFORM_TRIPLET}" +fi + + +# Check for --with-wheel-pkg-dir=PATH + +WHEEL_PKG_DIR="" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-wheel-pkg-dir" >&5 +printf %s "checking for --with-wheel-pkg-dir... " >&6; } + +# Check whether --with-wheel-pkg-dir was given. +if test ${with_wheel_pkg_dir+y} +then : + withval=$with_wheel_pkg_dir; +if test -n "$withval"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + WHEEL_PKG_DIR="$withval" +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi + + +# Check whether right shifting a negative integer extends the sign bit +# or fills with zeros (like the Cray J90, according to Tim Peters). +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether right shift extends the sign bit" >&5 +printf %s "checking whether right shift extends the sign bit... " >&6; } +if test ${ac_cv_rshift_extends_sign+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +if test "$cross_compiling" = yes +then : + ac_cv_rshift_extends_sign=yes +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int main(void) +{ + return (((-1)>>3 == -1) ? 0 : 1); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_rshift_extends_sign=yes +else case e in #( + e) ac_cv_rshift_extends_sign=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_rshift_extends_sign" >&5 +printf "%s\n" "$ac_cv_rshift_extends_sign" >&6; } +if test "$ac_cv_rshift_extends_sign" = no +then + +printf "%s\n" "#define SIGNED_RIGHT_SHIFT_ZERO_FILLS 1" >>confdefs.h + +fi + +# check for getc_unlocked and related locking functions +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getc_unlocked() and friends" >&5 +printf %s "checking for getc_unlocked() and friends... " >&6; } +if test ${ac_cv_have_getc_unlocked+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main (void) +{ + + FILE *f = fopen("/dev/null", "r"); + flockfile(f); + getc_unlocked(f); + funlockfile(f); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_have_getc_unlocked=yes +else case e in #( + e) ac_cv_have_getc_unlocked=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_getc_unlocked" >&5 +printf "%s\n" "$ac_cv_have_getc_unlocked" >&6; } +if test "$ac_cv_have_getc_unlocked" = yes +then + +printf "%s\n" "#define HAVE_GETC_UNLOCKED 1" >>confdefs.h + +fi + + + + + +# Check whether --with-readline was given. +if test ${with_readline+y} +then : + withval=$with_readline; + case $with_readline in #( + editline|edit) : + with_readline=edit ;; #( + yes|readline) : + with_readline=readline ;; #( + no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-readline[=editline|readline|no]" "$LINENO" 5 + ;; +esac + +else case e in #( + e) with_readline=readline + ;; +esac +fi + + +if test "x$with_readline" = xreadline +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline" >&5 +printf %s "checking for readline... " >&6; } + +if test -n "$LIBREADLINE_CFLAGS"; then + pkg_cv_LIBREADLINE_CFLAGS="$LIBREADLINE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"readline\""; } >&5 + ($PKG_CONFIG --exists --print-errors "readline") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBREADLINE_CFLAGS=`$PKG_CONFIG --cflags "readline" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBREADLINE_LIBS"; then + pkg_cv_LIBREADLINE_LIBS="$LIBREADLINE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"readline\""; } >&5 + ($PKG_CONFIG --exists --print-errors "readline") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBREADLINE_LIBS=`$PKG_CONFIG --libs "readline" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "readline" 2>&1` + else + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "readline" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBREADLINE_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LIBS="$LIBS $LIBREADLINE_LIBS" + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_READLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +printf %s "checking for readline in -lreadline... " >&6; } +if test ${ac_cv_lib_readline_readline+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char readline (void); +int +main (void) +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_readline_readline=yes +else case e in #( + e) ac_cv_lib_readline_readline=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +printf "%s\n" "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes +then : + + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + +else case e in #( + e) with_readline=no ;; +esac +fi + + +else case e in #( + e) with_readline=no ;; +esac +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LIBS="$LIBS $LIBREADLINE_LIBS" + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_READLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +printf %s "checking for readline in -lreadline... " >&6; } +if test ${ac_cv_lib_readline_readline+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char readline (void); +int +main (void) +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_readline_readline=yes +else case e in #( + e) ac_cv_lib_readline_readline=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +printf "%s\n" "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes +then : + + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + +else case e in #( + e) with_readline=no ;; +esac +fi + + +else case e in #( + e) with_readline=no ;; +esac +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBREADLINE_CFLAGS=$pkg_cv_LIBREADLINE_CFLAGS + LIBREADLINE_LIBS=$pkg_cv_LIBREADLINE_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + LIBREADLINE=readline + READLINE_CFLAGS=$LIBREADLINE_CFLAGS + READLINE_LIBS=$LIBREADLINE_LIBS + +fi + +fi + +if test "x$with_readline" = xedit +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libedit" >&5 +printf %s "checking for libedit... " >&6; } + +if test -n "$LIBEDIT_CFLAGS"; then + pkg_cv_LIBEDIT_CFLAGS="$LIBEDIT_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libedit") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBEDIT_CFLAGS=`$PKG_CONFIG --cflags "libedit" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBEDIT_LIBS"; then + pkg_cv_LIBEDIT_LIBS="$LIBEDIT_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libedit") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBEDIT_LIBS=`$PKG_CONFIG --libs "libedit" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libedit" 2>&1` + else + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libedit" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBEDIT_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LIBS="$LIBS $LIBEDIT_LIBS" + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_EDITLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +printf %s "checking for readline in -ledit... " >&6; } +if test ${ac_cv_lib_edit_readline+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char readline (void); +int +main (void) +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_edit_readline=yes +else case e in #( + e) ac_cv_lib_edit_readline=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +printf "%s\n" "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes +then : + + LIBREADLINE=edit + printf "%s\n" "#define WITH_EDITLINE 1" >>confdefs.h + + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + +else case e in #( + e) with_readline=no ;; +esac +fi + + +else case e in #( + e) with_readline=no ;; +esac +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LIBS="$LIBS $LIBEDIT_LIBS" + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_EDITLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +printf %s "checking for readline in -ledit... " >&6; } +if test ${ac_cv_lib_edit_readline+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char readline (void); +int +main (void) +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_edit_readline=yes +else case e in #( + e) ac_cv_lib_edit_readline=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +printf "%s\n" "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes +then : + + LIBREADLINE=edit + printf "%s\n" "#define WITH_EDITLINE 1" >>confdefs.h + + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + +else case e in #( + e) with_readline=no ;; +esac +fi + + +else case e in #( + e) with_readline=no ;; +esac +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBEDIT_CFLAGS=$pkg_cv_LIBEDIT_CFLAGS + LIBEDIT_LIBS=$pkg_cv_LIBEDIT_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + printf "%s\n" "#define WITH_EDITLINE 1" >>confdefs.h + + LIBREADLINE=edit + READLINE_CFLAGS=$LIBEDIT_CFLAGS + READLINE_LIBS=$LIBEDIT_LIBS + +fi + +fi + +READLINE_CFLAGS=$(echo $READLINE_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link readline" >&5 +printf %s "checking how to link readline... " >&6; } +if test "x$with_readline" = xno +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)" >&5 +printf "%s\n" "$with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS" + LIBS="$LIBS $READLINE_LIBS" + LIBS_SAVE=$LIBS + + + + # check for readline 2.2 + ac_fn_check_decl "$LINENO" "rl_completion_append_character" "ac_cv_have_decl_rl_completion_append_character" " + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_rl_completion_append_character" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1" >>confdefs.h + + +fi + + ac_fn_check_decl "$LINENO" "rl_completion_suppress_append" "ac_cv_have_decl_rl_completion_suppress_append" " + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_rl_completion_suppress_append" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1" >>confdefs.h + + +fi + + # check for readline 4.0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_pre_input_hook in -l$LIBREADLINE" >&5 +printf %s "checking for rl_pre_input_hook in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_pre_input_hook+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +int +main (void) +{ +void *x = rl_pre_input_hook + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_pre_input_hook=yes +else case e in #( + e) ac_cv_readline_rl_pre_input_hook=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_pre_input_hook" >&5 +printf "%s\n" "$ac_cv_readline_rl_pre_input_hook" >&6; } + if test "x$ac_cv_readline_rl_pre_input_hook" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_PRE_INPUT_HOOK 1" >>confdefs.h + + +fi + + # also in 4.0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_completion_display_matches_hook in -l$LIBREADLINE" >&5 +printf %s "checking for rl_completion_display_matches_hook in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_completion_display_matches_hook+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +int +main (void) +{ +void *x = rl_completion_display_matches_hook + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_completion_display_matches_hook=yes +else case e in #( + e) ac_cv_readline_rl_completion_display_matches_hook=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_completion_display_matches_hook" >&5 +printf "%s\n" "$ac_cv_readline_rl_completion_display_matches_hook" >&6; } + if test "x$ac_cv_readline_rl_completion_display_matches_hook" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1" >>confdefs.h + + +fi + + # also in 4.0, but not in editline + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_resize_terminal in -l$LIBREADLINE" >&5 +printf %s "checking for rl_resize_terminal in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_resize_terminal+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +int +main (void) +{ +void *x = rl_resize_terminal + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_resize_terminal=yes +else case e in #( + e) ac_cv_readline_rl_resize_terminal=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_resize_terminal" >&5 +printf "%s\n" "$ac_cv_readline_rl_resize_terminal" >&6; } + if test "x$ac_cv_readline_rl_resize_terminal" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_RESIZE_TERMINAL 1" >>confdefs.h + + +fi + + # rl_change_environment is in readline 6.3, but not in editline + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_change_environment in -l$LIBREADLINE" >&5 +printf %s "checking for rl_change_environment in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_change_environment+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +int +main (void) +{ +int x = rl_change_environment + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_change_environment=yes +else case e in #( + e) ac_cv_readline_rl_change_environment=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_change_environment" >&5 +printf "%s\n" "$ac_cv_readline_rl_change_environment" >&6; } + if test "x$ac_cv_readline_rl_change_environment" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_CHANGE_ENVIRONMENT 1" >>confdefs.h + + +fi + + # check for readline 4.2 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -l$LIBREADLINE" >&5 +printf %s "checking for rl_completion_matches in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_completion_matches+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +int +main (void) +{ +void *x = rl_completion_matches + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_completion_matches=yes +else case e in #( + e) ac_cv_readline_rl_completion_matches=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_completion_matches" >&5 +printf "%s\n" "$ac_cv_readline_rl_completion_matches" >&6; } + if test "x$ac_cv_readline_rl_completion_matches" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_MATCHES 1" >>confdefs.h + + +fi + + # also in readline 4.2 + ac_fn_check_decl "$LINENO" "rl_catch_signals" "ac_cv_have_decl_rl_catch_signals" " + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_rl_catch_signals" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_CATCH_SIGNAL 1" >>confdefs.h + + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for append_history in -l$LIBREADLINE" >&5 +printf %s "checking for append_history in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_append_history+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +int +main (void) +{ +void *x = append_history + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_append_history=yes +else case e in #( + e) ac_cv_readline_append_history=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_append_history" >&5 +printf "%s\n" "$ac_cv_readline_append_history" >&6; } + if test "x$ac_cv_readline_append_history" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_APPEND_HISTORY 1" >>confdefs.h + + +fi + + # in readline as well as newer editline (April 2023) + ac_fn_c_check_type "$LINENO" "rl_compdisp_func_t" "ac_cv_type_rl_compdisp_func_t" " + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + +" +if test "x$ac_cv_type_rl_compdisp_func_t" = xyes +then : + +printf "%s\n" "#define HAVE_RL_COMPDISP_FUNC_T 1" >>confdefs.h + + +fi + + + # Some editline versions declare rl_startup_hook as taking no args, others + # declare it as taking 2. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if rl_startup_hook takes arguments" >&5 +printf %s "checking if rl_startup_hook takes arguments... " >&6; } +if test ${ac_cv_readline_rl_startup_hook_takes_args+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + + extern int test_hook_func(const char *text, int state); +int +main (void) +{ +rl_startup_hook=test_hook_func; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_readline_rl_startup_hook_takes_args=yes +else case e in #( + e) ac_cv_readline_rl_startup_hook_takes_args=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_startup_hook_takes_args" >&5 +printf "%s\n" "$ac_cv_readline_rl_startup_hook_takes_args" >&6; } + if test "x$ac_cv_readline_rl_startup_hook_takes_args" = xyes +then : + + +printf "%s\n" "#define Py_RL_STARTUP_HOOK_TAKES_ARGS 1" >>confdefs.h + + +fi + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken nice()" >&5 +printf %s "checking for broken nice()... " >&6; } +if test ${ac_cv_broken_nice+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +if test "$cross_compiling" = yes +then : + ac_cv_broken_nice=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdlib.h> +#include <unistd.h> +int main(void) +{ + int val1 = nice(1); + if (val1 != -1 && val1 == nice(2)) + exit(0); + exit(1); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_broken_nice=yes +else case e in #( + e) ac_cv_broken_nice=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_nice" >&5 +printf "%s\n" "$ac_cv_broken_nice" >&6; } +if test "$ac_cv_broken_nice" = yes +then + +printf "%s\n" "#define HAVE_BROKEN_NICE 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken poll()" >&5 +printf %s "checking for broken poll()... " >&6; } +if test ${ac_cv_broken_poll+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_broken_poll=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <poll.h> +#include <unistd.h> + +int main(void) +{ + struct pollfd poll_struct = { 42, POLLIN|POLLPRI|POLLOUT, 0 }; + int poll_test; + + close (42); + + poll_test = poll(&poll_struct, 1, 0); + if (poll_test < 0) + return 0; + else if (poll_test == 0 && poll_struct.revents != POLLNVAL) + return 0; + else + return 1; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_broken_poll=yes +else case e in #( + e) ac_cv_broken_poll=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_poll" >&5 +printf "%s\n" "$ac_cv_broken_poll" >&6; } +if test "$ac_cv_broken_poll" = yes +then + +printf "%s\n" "#define HAVE_BROKEN_POLL 1" >>confdefs.h + +fi + +# check tzset(3) exists and works like we expect it to +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working tzset()" >&5 +printf %s "checking for working tzset()... " >&6; } +if test ${ac_cv_working_tzset+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +if test "$cross_compiling" = yes +then : + ac_cv_working_tzset=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdlib.h> +#include <time.h> +#include <string.h> + +#if HAVE_TZNAME +extern char *tzname[]; +#endif + +int main(void) +{ + /* Note that we need to ensure that not only does tzset(3) + do 'something' with localtime, but it works as documented + in the library reference and as expected by the test suite. + This includes making sure that tzname is set properly if + tm->tm_zone does not exist since it is the alternative way + of getting timezone info. + + Red Hat 6.2 doesn't understand the southern hemisphere + after New Year's Day. + */ + + time_t groundhogday = 1044144000; /* GMT-based */ + time_t midyear = groundhogday + (365 * 24 * 3600 / 2); + + putenv("TZ=UTC+0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 0) + exit(1); +#if HAVE_TZNAME + /* For UTC, tzname[1] is sometimes "", sometimes " " */ + if (strcmp(tzname[0], "UTC") || + (tzname[1][0] != 0 && tzname[1][0] != ' ')) + exit(1); +#endif + + putenv("TZ=EST+5EDT,M4.1.0,M10.5.0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 19) + exit(1); +#if HAVE_TZNAME + if (strcmp(tzname[0], "EST") || strcmp(tzname[1], "EDT")) + exit(1); +#endif + + putenv("TZ=AEST-10AEDT-11,M10.5.0,M3.5.0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 11) + exit(1); +#if HAVE_TZNAME + if (strcmp(tzname[0], "AEST") || strcmp(tzname[1], "AEDT")) + exit(1); +#endif + +#if HAVE_STRUCT_TM_TM_ZONE + if (strcmp(localtime(&groundhogday)->tm_zone, "AEDT")) + exit(1); + if (strcmp(localtime(&midyear)->tm_zone, "AEST")) + exit(1); +#endif + + exit(0); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_working_tzset=yes +else case e in #( + e) ac_cv_working_tzset=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_tzset" >&5 +printf "%s\n" "$ac_cv_working_tzset" >&6; } +if test "$ac_cv_working_tzset" = yes +then + +printf "%s\n" "#define HAVE_WORKING_TZSET 1" >>confdefs.h + +fi + +# Look for subsecond timestamps in struct stat +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tv_nsec in struct stat" >&5 +printf %s "checking for tv_nsec in struct stat... " >&6; } +if test ${ac_cv_stat_tv_nsec+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/stat.h> +int +main (void) +{ + +struct stat st; +st.st_mtim.tv_nsec = 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_stat_tv_nsec=yes +else case e in #( + e) ac_cv_stat_tv_nsec=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stat_tv_nsec" >&5 +printf "%s\n" "$ac_cv_stat_tv_nsec" >&6; } +if test "$ac_cv_stat_tv_nsec" = yes +then + +printf "%s\n" "#define HAVE_STAT_TV_NSEC 1" >>confdefs.h + +fi + +# Look for BSD style subsecond timestamps in struct stat +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tv_nsec2 in struct stat" >&5 +printf %s "checking for tv_nsec2 in struct stat... " >&6; } +if test ${ac_cv_stat_tv_nsec2+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/stat.h> +int +main (void) +{ + +struct stat st; +st.st_mtimespec.tv_nsec = 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_stat_tv_nsec2=yes +else case e in #( + e) ac_cv_stat_tv_nsec2=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stat_tv_nsec2" >&5 +printf "%s\n" "$ac_cv_stat_tv_nsec2" >&6; } +if test "$ac_cv_stat_tv_nsec2" = yes +then + +printf "%s\n" "#define HAVE_STAT_TV_NSEC2 1" >>confdefs.h + +fi + +have_curses=no +have_panel=no + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-curses" >&5 +printf %s "checking for --with-curses... " >&6; } + +# Check whether --with-curses was given. +if test ${with_curses+y} +then : + withval=$with_curses; case $with_curses in #( + yes|auto) : + with_curses=auto ;; #( + ncursesw|ncurses|curses|no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-curses[=ncursesw|ncurses|curses|no]" "$LINENO" 5 ;; +esac +else case e in #( + e) with_curses=auto ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_curses" >&5 +printf "%s\n" "$with_curses" >&6; } + + + +# Detect the selected backend. ncursesw/ncurses are found via pkg-config; +# native curses has no .pc file and is left to the header/link probes below. +# curses_libs/panel_libs drive the AC_SEARCH_LIBS fallback; for "no" they are +# empty so nothing links and have_curses stays "no". +case $with_curses in #( + ncursesw) : + + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncursesw" >&5 +printf %s "checking for ncursesw... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 + + have_curses=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_curses=no +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h + + have_curses=yes + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panelw" >&5 +printf %s "checking for panelw... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PANELW 1" >>confdefs.h + + have_panel=yes +fi +fi + + + curses_libs="ncursesw"; panel_libs="panelw gnupanel" ;; #( + ncurses) : + + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses" >&5 +printf %s "checking for ncurses... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 + + have_curses=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_curses=no +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_NCURSES 1" >>confdefs.h + + have_curses=yes + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panel" >&5 +printf %s "checking for panel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PANEL 1" >>confdefs.h + + have_panel=yes +fi +fi + + + curses_libs="ncurses"; panel_libs="panel gnupanel" ;; #( + curses) : + curses_libs="curses"; panel_libs="panel" ;; #( + no) : + curses_libs=""; panel_libs="" ;; #( + *) : + + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncursesw" >&5 +printf %s "checking for ncursesw... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 + + have_curses=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_curses=no +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h + + have_curses=yes + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panelw" >&5 +printf %s "checking for panelw... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PANELW 1" >>confdefs.h + + have_panel=yes +fi +fi + + + if test "x$have_curses" = xno +then : + + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses" >&5 +printf %s "checking for ncurses... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 + + have_curses=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_curses=no +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_NCURSES 1" >>confdefs.h + + have_curses=yes + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panel" >&5 +printf %s "checking for panel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnupanel" >&5 +printf %s "checking for gnupanel... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnupanel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnupanel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "gnupanel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnupanel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnupanel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + have_panel=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_panel=no +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_panel=yes +fi +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PANEL 1" >>confdefs.h + + have_panel=yes +fi +fi + + +fi + curses_libs="ncursesw ncurses"; panel_libs="panelw panel gnupanel" ;; +esac + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + # Make sure we've got the header defines. For the native "curses" backend, + # probe only the plain headers: a system may also have ncurses headers (e.g. + # ncurses/curses.h), and picking those while linking the native library mixes + # incompatible declarations (e.g. tparm()) with the native <term.h>. + as_fn_append CPPFLAGS " $CURSES_CFLAGS $PANEL_CFLAGS" + if test "x$with_curses" = xcurses +then : + ac_fn_c_check_header_compile "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default" +if test "x$ac_cv_header_curses_h" = xyes +then : + printf "%s\n" "#define HAVE_CURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "panel.h" "ac_cv_header_panel_h" "$ac_includes_default" +if test "x$ac_cv_header_panel_h" = xyes +then : + printf "%s\n" "#define HAVE_PANEL_H 1" >>confdefs.h + +fi + +else case e in #( + e) ac_fn_c_check_header_compile "$LINENO" "ncursesw/curses.h" "ac_cv_header_ncursesw_curses_h" "$ac_includes_default" +if test "x$ac_cv_header_ncursesw_curses_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSESW_CURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ncursesw/ncurses.h" "ac_cv_header_ncursesw_ncurses_h" "$ac_includes_default" +if test "x$ac_cv_header_ncursesw_ncurses_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSESW_NCURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ncursesw/panel.h" "ac_cv_header_ncursesw_panel_h" "$ac_includes_default" +if test "x$ac_cv_header_ncursesw_panel_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSESW_PANEL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ncurses/curses.h" "ac_cv_header_ncurses_curses_h" "$ac_includes_default" +if test "x$ac_cv_header_ncurses_curses_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSES_CURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ncurses/ncurses.h" "ac_cv_header_ncurses_ncurses_h" "$ac_includes_default" +if test "x$ac_cv_header_ncurses_ncurses_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSES_NCURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ncurses/panel.h" "ac_cv_header_ncurses_panel_h" "$ac_includes_default" +if test "x$ac_cv_header_ncurses_panel_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSES_PANEL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default" +if test "x$ac_cv_header_curses_h" = xyes +then : + printf "%s\n" "#define HAVE_CURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" "$ac_includes_default" +if test "x$ac_cv_header_ncurses_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "panel.h" "ac_cv_header_panel_h" "$ac_includes_default" +if test "x$ac_cv_header_panel_h" = xyes +then : + printf "%s\n" "#define HAVE_PANEL_H 1" >>confdefs.h + +fi + ;; +esac +fi + + # Check that we're able to link with crucial curses/panel functions. This + # also serves as a fallback in case pkg-config failed. Extension modules are + # not linked with LIBS, so exclude it to get the required libraries. + LIBS="$CURSES_LIBS $PANEL_LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing initscr" >&5 +printf %s "checking for library containing initscr... " >&6; } +if test ${ac_cv_search_initscr+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (void); +int +main (void) +{ +return initscr (); + ; + return 0; +} +_ACEOF +for ac_lib in '' $curses_libs +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_initscr=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_initscr+y} +then : + break +fi +done +if test ${ac_cv_search_initscr+y} +then : + +else case e in #( + e) ac_cv_search_initscr=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_initscr" >&5 +printf "%s\n" "$ac_cv_search_initscr" >&6; } +ac_res=$ac_cv_search_initscr +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + if test "x$have_curses" = xno +then : + have_curses=yes + CURSES_LIBS=${CURSES_LIBS-"$ac_cv_search_initscr"} +fi +else case e in #( + e) have_curses=no ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing update_panels" >&5 +printf %s "checking for library containing update_panels... " >&6; } +if test ${ac_cv_search_update_panels+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char update_panels (void); +int +main (void) +{ +return update_panels (); + ; + return 0; +} +_ACEOF +for ac_lib in '' $panel_libs +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_update_panels=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_update_panels+y} +then : + break +fi +done +if test ${ac_cv_search_update_panels+y} +then : + +else case e in #( + e) ac_cv_search_update_panels=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_update_panels" >&5 +printf "%s\n" "$ac_cv_search_update_panels" >&6; } +ac_res=$ac_cv_search_update_panels +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + if test "x$have_panel" = xno +then : + have_panel=yes + PANEL_LIBS=${PANEL_LIBS-"$ac_cv_search_update_panels"} +fi +else case e in #( + e) have_panel=no ;; +esac +fi + + + + +if test "$have_curses" != "no" +then : + +CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +if test "x$ac_sys_system" = xDarwin +then : + + + as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1" + +fi + +PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +case $with_curses in #( + ncursesw|no) : + ;; #( + *) : + + save_curses_cppflags=$CPPFLAGS + as_fn_append CPPFLAGS " $CURSES_CFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether curses supports wide characters" >&5 +printf %s "checking whether curses supports wide characters... " >&6; } +if test ${ac_cv_curses_wide+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + cchar_t wcval; + setcchar(&wcval, L"x", A_NORMAL, 0, NULL); + add_wch(&wcval); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_curses_wide=yes +else case e in #( + e) ac_cv_curses_wide=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_curses_wide" >&5 +printf "%s\n" "$ac_cv_curses_wide" >&6; } + CPPFLAGS=$save_curses_cppflags + if test "x$ac_cv_curses_wide" = xyes +then : + printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h + +fi + ;; +esac + +# On Solaris, term.h requires curses.h +ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" " +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +" +if test "x$ac_cv_header_term_h" = xyes +then : + printf "%s\n" "#define HAVE_TERM_H 1" >>confdefs.h + +fi + + +# On HP/UX 11.0, mvwdelch is a block with a return statement +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether mvwdelch is an expression" >&5 +printf %s "checking whether mvwdelch is an expression... " >&6; } +if test ${ac_cv_mvwdelch_is_expression+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + int rtn; + rtn = mvwdelch(0,0,0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_mvwdelch_is_expression=yes +else case e in #( + e) ac_cv_mvwdelch_is_expression=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mvwdelch_is_expression" >&5 +printf "%s\n" "$ac_cv_mvwdelch_is_expression" >&6; } + +if test "$ac_cv_mvwdelch_is_expression" = yes +then + +printf "%s\n" "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5 +printf %s "checking whether WINDOW has _flags... " >&6; } +if test ${ac_cv_window_has_flags+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + WINDOW *w; + w->_flags = 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_window_has_flags=yes +else case e in #( + e) ac_cv_window_has_flags=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_window_has_flags" >&5 +printf "%s\n" "$ac_cv_window_has_flags" >&6; } + + +if test "$ac_cv_window_has_flags" = yes +then + +printf "%s\n" "#define WINDOW_HAS_FLAGS 1" >>confdefs.h + +fi + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function is_pad" >&5 +printf %s "checking for curses function is_pad... " >&6; } +if test ${ac_cv_lib_curses_is_pad+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef is_pad + void *x=is_pad + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_is_pad=yes +else case e in #( + e) ac_cv_lib_curses_is_pad=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_pad" >&5 +printf "%s\n" "$ac_cv_lib_curses_is_pad" >&6; } + if test "x$ac_cv_lib_curses_is_pad" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_IS_PAD 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function is_term_resized" >&5 +printf %s "checking for curses function is_term_resized... " >&6; } +if test ${ac_cv_lib_curses_is_term_resized+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef is_term_resized + void *x=is_term_resized + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_is_term_resized=yes +else case e in #( + e) ac_cv_lib_curses_is_term_resized=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_term_resized" >&5 +printf "%s\n" "$ac_cv_lib_curses_is_term_resized" >&6; } + if test "x$ac_cv_lib_curses_is_term_resized" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_IS_TERM_RESIZED 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function resize_term" >&5 +printf %s "checking for curses function resize_term... " >&6; } +if test ${ac_cv_lib_curses_resize_term+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef resize_term + void *x=resize_term + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_resize_term=yes +else case e in #( + e) ac_cv_lib_curses_resize_term=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_resize_term" >&5 +printf "%s\n" "$ac_cv_lib_curses_resize_term" >&6; } + if test "x$ac_cv_lib_curses_resize_term" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_RESIZE_TERM 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function resizeterm" >&5 +printf %s "checking for curses function resizeterm... " >&6; } +if test ${ac_cv_lib_curses_resizeterm+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef resizeterm + void *x=resizeterm + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_resizeterm=yes +else case e in #( + e) ac_cv_lib_curses_resizeterm=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_resizeterm" >&5 +printf "%s\n" "$ac_cv_lib_curses_resizeterm" >&6; } + if test "x$ac_cv_lib_curses_resizeterm" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_RESIZETERM 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function immedok" >&5 +printf %s "checking for curses function immedok... " >&6; } +if test ${ac_cv_lib_curses_immedok+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef immedok + void *x=immedok + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_immedok=yes +else case e in #( + e) ac_cv_lib_curses_immedok=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_immedok" >&5 +printf "%s\n" "$ac_cv_lib_curses_immedok" >&6; } + if test "x$ac_cv_lib_curses_immedok" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_IMMEDOK 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function syncok" >&5 +printf %s "checking for curses function syncok... " >&6; } +if test ${ac_cv_lib_curses_syncok+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef syncok + void *x=syncok + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_syncok=yes +else case e in #( + e) ac_cv_lib_curses_syncok=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_syncok" >&5 +printf "%s\n" "$ac_cv_lib_curses_syncok" >&6; } + if test "x$ac_cv_lib_curses_syncok" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SYNCOK 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wchgat" >&5 +printf %s "checking for curses function wchgat... " >&6; } +if test ${ac_cv_lib_curses_wchgat+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef wchgat + void *x=wchgat + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_wchgat=yes +else case e in #( + e) ac_cv_lib_curses_wchgat=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wchgat" >&5 +printf "%s\n" "$ac_cv_lib_curses_wchgat" >&6; } + if test "x$ac_cv_lib_curses_wchgat" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_WCHGAT 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function filter" >&5 +printf %s "checking for curses function filter... " >&6; } +if test ${ac_cv_lib_curses_filter+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef filter + void *x=filter + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_filter=yes +else case e in #( + e) ac_cv_lib_curses_filter=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_filter" >&5 +printf "%s\n" "$ac_cv_lib_curses_filter" >&6; } + if test "x$ac_cv_lib_curses_filter" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_FILTER 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function nofilter" >&5 +printf %s "checking for curses function nofilter... " >&6; } +if test ${ac_cv_lib_curses_nofilter+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef nofilter + void *x=nofilter + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_nofilter=yes +else case e in #( + e) ac_cv_lib_curses_nofilter=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_nofilter" >&5 +printf "%s\n" "$ac_cv_lib_curses_nofilter" >&6; } + if test "x$ac_cv_lib_curses_nofilter" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_NOFILTER 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function has_key" >&5 +printf %s "checking for curses function has_key... " >&6; } +if test ${ac_cv_lib_curses_has_key+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef has_key + void *x=has_key + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_has_key=yes +else case e in #( + e) ac_cv_lib_curses_has_key=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_has_key" >&5 +printf "%s\n" "$ac_cv_lib_curses_has_key" >&6; } + if test "x$ac_cv_lib_curses_has_key" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_HAS_KEY 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function has_mouse" >&5 +printf %s "checking for curses function has_mouse... " >&6; } +if test ${ac_cv_lib_curses_has_mouse+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef has_mouse + void *x=has_mouse + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_has_mouse=yes +else case e in #( + e) ac_cv_lib_curses_has_mouse=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_has_mouse" >&5 +printf "%s\n" "$ac_cv_lib_curses_has_mouse" >&6; } + if test "x$ac_cv_lib_curses_has_mouse" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_HAS_MOUSE 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function is_keypad" >&5 +printf %s "checking for curses function is_keypad... " >&6; } +if test ${ac_cv_lib_curses_is_keypad+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef is_keypad + void *x=is_keypad + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_is_keypad=yes +else case e in #( + e) ac_cv_lib_curses_is_keypad=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_keypad" >&5 +printf "%s\n" "$ac_cv_lib_curses_is_keypad" >&6; } + if test "x$ac_cv_lib_curses_is_keypad" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_IS_KEYPAD 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function is_leaveok" >&5 +printf %s "checking for curses function is_leaveok... " >&6; } +if test ${ac_cv_lib_curses_is_leaveok+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef is_leaveok + void *x=is_leaveok + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_is_leaveok=yes +else case e in #( + e) ac_cv_lib_curses_is_leaveok=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_leaveok" >&5 +printf "%s\n" "$ac_cv_lib_curses_is_leaveok" >&6; } + if test "x$ac_cv_lib_curses_is_leaveok" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_IS_LEAVEOK 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function typeahead" >&5 +printf %s "checking for curses function typeahead... " >&6; } +if test ${ac_cv_lib_curses_typeahead+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef typeahead + void *x=typeahead + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_typeahead=yes +else case e in #( + e) ac_cv_lib_curses_typeahead=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_typeahead" >&5 +printf "%s\n" "$ac_cv_lib_curses_typeahead" >&6; } + if test "x$ac_cv_lib_curses_typeahead" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_TYPEAHEAD 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function use_env" >&5 +printf %s "checking for curses function use_env... " >&6; } +if test ${ac_cv_lib_curses_use_env+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef use_env + void *x=use_env + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_use_env=yes +else case e in #( + e) ac_cv_lib_curses_use_env=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_use_env" >&5 +printf "%s\n" "$ac_cv_lib_curses_use_env" >&6; } + if test "x$ac_cv_lib_curses_use_env" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_USE_ENV 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function new_prescr" >&5 +printf %s "checking for curses function new_prescr... " >&6; } +if test ${ac_cv_lib_curses_new_prescr+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef new_prescr + void *x=new_prescr + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_new_prescr=yes +else case e in #( + e) ac_cv_lib_curses_new_prescr=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_new_prescr" >&5 +printf "%s\n" "$ac_cv_lib_curses_new_prescr" >&6; } + if test "x$ac_cv_lib_curses_new_prescr" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_NEW_PRESCR 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function use_screen" >&5 +printf %s "checking for curses function use_screen... " >&6; } +if test ${ac_cv_lib_curses_use_screen+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef use_screen + void *x=use_screen + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_use_screen=yes +else case e in #( + e) ac_cv_lib_curses_use_screen=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_use_screen" >&5 +printf "%s\n" "$ac_cv_lib_curses_use_screen" >&6; } + if test "x$ac_cv_lib_curses_use_screen" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_USE_SCREEN 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function use_window" >&5 +printf %s "checking for curses function use_window... " >&6; } +if test ${ac_cv_lib_curses_use_window+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef use_window + void *x=use_window + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_use_window=yes +else case e in #( + e) ac_cv_lib_curses_use_window=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_use_window" >&5 +printf "%s\n" "$ac_cv_lib_curses_use_window" >&6; } + if test "x$ac_cv_lib_curses_use_window" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_USE_WINDOW 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function key_defined" >&5 +printf %s "checking for curses function key_defined... " >&6; } +if test ${ac_cv_lib_curses_key_defined+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef key_defined + void *x=key_defined + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_key_defined=yes +else case e in #( + e) ac_cv_lib_curses_key_defined=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_key_defined" >&5 +printf "%s\n" "$ac_cv_lib_curses_key_defined" >&6; } + if test "x$ac_cv_lib_curses_key_defined" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_KEY_DEFINED 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function term_attrs" >&5 +printf %s "checking for curses function term_attrs... " >&6; } +if test ${ac_cv_lib_curses_term_attrs+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef term_attrs + void *x=term_attrs + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_term_attrs=yes +else case e in #( + e) ac_cv_lib_curses_term_attrs=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_term_attrs" >&5 +printf "%s\n" "$ac_cv_lib_curses_term_attrs" >&6; } + if test "x$ac_cv_lib_curses_term_attrs" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_TERM_ATTRS 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function define_key" >&5 +printf %s "checking for curses function define_key... " >&6; } +if test ${ac_cv_lib_curses_define_key+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef define_key + void *x=define_key + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_define_key=yes +else case e in #( + e) ac_cv_lib_curses_define_key=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_define_key" >&5 +printf "%s\n" "$ac_cv_lib_curses_define_key" >&6; } + if test "x$ac_cv_lib_curses_define_key" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_DEFINE_KEY 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function keyok" >&5 +printf %s "checking for curses function keyok... " >&6; } +if test ${ac_cv_lib_curses_keyok+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef keyok + void *x=keyok + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_keyok=yes +else case e in #( + e) ac_cv_lib_curses_keyok=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_keyok" >&5 +printf "%s\n" "$ac_cv_lib_curses_keyok" >&6; } + if test "x$ac_cv_lib_curses_keyok" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_KEYOK 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function set_escdelay" >&5 +printf %s "checking for curses function set_escdelay... " >&6; } +if test ${ac_cv_lib_curses_set_escdelay+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef set_escdelay + void *x=set_escdelay + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_set_escdelay=yes +else case e in #( + e) ac_cv_lib_curses_set_escdelay=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_set_escdelay" >&5 +printf "%s\n" "$ac_cv_lib_curses_set_escdelay" >&6; } + if test "x$ac_cv_lib_curses_set_escdelay" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SET_ESCDELAY 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function set_tabsize" >&5 +printf %s "checking for curses function set_tabsize... " >&6; } +if test ${ac_cv_lib_curses_set_tabsize+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef set_tabsize + void *x=set_tabsize + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_set_tabsize=yes +else case e in #( + e) ac_cv_lib_curses_set_tabsize=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_set_tabsize" >&5 +printf "%s\n" "$ac_cv_lib_curses_set_tabsize" >&6; } + if test "x$ac_cv_lib_curses_set_tabsize" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SET_TABSIZE 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_get" >&5 +printf %s "checking for curses function wattr_get... " >&6; } +if test ${ac_cv_lib_curses_wattr_get+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef wattr_get + void *x=wattr_get + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_wattr_get=yes +else case e in #( + e) ac_cv_lib_curses_wattr_get=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_get" >&5 +printf "%s\n" "$ac_cv_lib_curses_wattr_get" >&6; } + if test "x$ac_cv_lib_curses_wattr_get" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_WATTR_GET 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_set" >&5 +printf %s "checking for curses function wattr_set... " >&6; } +if test ${ac_cv_lib_curses_wattr_set+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef wattr_set + void *x=wattr_set + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_wattr_set=yes +else case e in #( + e) ac_cv_lib_curses_wattr_set=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_set" >&5 +printf "%s\n" "$ac_cv_lib_curses_wattr_set" >&6; } + if test "x$ac_cv_lib_curses_wattr_set" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_WATTR_SET 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_on" >&5 +printf %s "checking for curses function wattr_on... " >&6; } +if test ${ac_cv_lib_curses_wattr_on+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef wattr_on + void *x=wattr_on + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_wattr_on=yes +else case e in #( + e) ac_cv_lib_curses_wattr_on=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_on" >&5 +printf "%s\n" "$ac_cv_lib_curses_wattr_on" >&6; } + if test "x$ac_cv_lib_curses_wattr_on" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_WATTR_ON 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wattr_off" >&5 +printf %s "checking for curses function wattr_off... " >&6; } +if test ${ac_cv_lib_curses_wattr_off+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef wattr_off + void *x=wattr_off + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_wattr_off=yes +else case e in #( + e) ac_cv_lib_curses_wattr_off=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wattr_off" >&5 +printf "%s\n" "$ac_cv_lib_curses_wattr_off" >&6; } + if test "x$ac_cv_lib_curses_wattr_off" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_WATTR_OFF 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wcolor_set" >&5 +printf %s "checking for curses function wcolor_set... " >&6; } +if test ${ac_cv_lib_curses_wcolor_set+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef wcolor_set + void *x=wcolor_set + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_wcolor_set=yes +else case e in #( + e) ac_cv_lib_curses_wcolor_set=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wcolor_set" >&5 +printf "%s\n" "$ac_cv_lib_curses_wcolor_set" >&6; } + if test "x$ac_cv_lib_curses_wcolor_set" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_WCOLOR_SET 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_attr_on" >&5 +printf %s "checking for curses function slk_attr_on... " >&6; } +if test ${ac_cv_lib_curses_slk_attr_on+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef slk_attr_on + void *x=slk_attr_on + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_slk_attr_on=yes +else case e in #( + e) ac_cv_lib_curses_slk_attr_on=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_attr_on" >&5 +printf "%s\n" "$ac_cv_lib_curses_slk_attr_on" >&6; } + if test "x$ac_cv_lib_curses_slk_attr_on" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SLK_ATTR_ON 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_attr_off" >&5 +printf %s "checking for curses function slk_attr_off... " >&6; } +if test ${ac_cv_lib_curses_slk_attr_off+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef slk_attr_off + void *x=slk_attr_off + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_slk_attr_off=yes +else case e in #( + e) ac_cv_lib_curses_slk_attr_off=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_attr_off" >&5 +printf "%s\n" "$ac_cv_lib_curses_slk_attr_off" >&6; } + if test "x$ac_cv_lib_curses_slk_attr_off" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SLK_ATTR_OFF 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_attr_set" >&5 +printf %s "checking for curses function slk_attr_set... " >&6; } +if test ${ac_cv_lib_curses_slk_attr_set+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef slk_attr_set + void *x=slk_attr_set + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_slk_attr_set=yes +else case e in #( + e) ac_cv_lib_curses_slk_attr_set=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_attr_set" >&5 +printf "%s\n" "$ac_cv_lib_curses_slk_attr_set" >&6; } + if test "x$ac_cv_lib_curses_slk_attr_set" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SLK_ATTR_SET 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function slk_color" >&5 +printf %s "checking for curses function slk_color... " >&6; } +if test ${ac_cv_lib_curses_slk_color+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef slk_color + void *x=slk_color + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_slk_color=yes +else case e in #( + e) ac_cv_lib_curses_slk_color=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_slk_color" >&5 +printf "%s\n" "$ac_cv_lib_curses_slk_color" >&6; } + if test "x$ac_cv_lib_curses_slk_color" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SLK_COLOR 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses variable ESCDELAY" >&5 +printf %s "checking for curses variable ESCDELAY... " >&6; } +if test ${ac_cv_lib_curses_ESCDELAY+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + int x = ESCDELAY; (void)x; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_ESCDELAY=yes +else case e in #( + e) ac_cv_lib_curses_ESCDELAY=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_ESCDELAY" >&5 +printf "%s\n" "$ac_cv_lib_curses_ESCDELAY" >&6; } + if test "x$ac_cv_lib_curses_ESCDELAY" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_ESCDELAY 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses variable TABSIZE" >&5 +printf %s "checking for curses variable TABSIZE... " >&6; } +if test ${ac_cv_lib_curses_TABSIZE+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + int x = TABSIZE; (void)x; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_TABSIZE=yes +else case e in #( + e) ac_cv_lib_curses_TABSIZE=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_TABSIZE" >&5 +printf "%s\n" "$ac_cv_lib_curses_TABSIZE" >&6; } + if test "x$ac_cv_lib_curses_TABSIZE" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_TABSIZE 1" >>confdefs.h + +fi + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses-style curses function getmouse" >&5 +printf %s "checking for ncurses-style curses function getmouse... " >&6; } +if test ${ac_cv_lib_curses_getmouse+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ +MEVENT event; (void)getmouse(&event); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_getmouse=yes +else case e in #( + e) ac_cv_lib_curses_getmouse=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_getmouse" >&5 +printf "%s\n" "$ac_cv_lib_curses_getmouse" >&6; } +if test "x$ac_cv_lib_curses_getmouse" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_GETMOUSE 1" >>confdefs.h + +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function scr_dump" >&5 +printf %s "checking for curses function scr_dump... " >&6; } +if test ${ac_cv_lib_curses_scr_dump+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef scr_dump + void *x=scr_dump + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_scr_dump=yes +else case e in #( + e) ac_cv_lib_curses_scr_dump=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_scr_dump" >&5 +printf "%s\n" "$ac_cv_lib_curses_scr_dump" >&6; } + if test "x$ac_cv_lib_curses_scr_dump" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SCR_DUMP 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function scr_set" >&5 +printf %s "checking for curses function scr_set... " >&6; } +if test ${ac_cv_lib_curses_scr_set+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif + +int +main (void) +{ + + #ifndef scr_set + void *x=scr_set + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_lib_curses_scr_set=yes +else case e in #( + e) ac_cv_lib_curses_scr_set=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_scr_set" >&5 +printf "%s\n" "$ac_cv_lib_curses_scr_set" >&6; } + if test "x$ac_cv_lib_curses_scr_set" = xyes +then : + +printf "%s\n" "#define HAVE_CURSES_SCR_SET 1" >>confdefs.h + +fi + + + +CPPFLAGS=$ac_save_cppflags + +fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for device files" >&5 +printf "%s\n" "$as_me: checking for device files" >&6;} + +if test "$ac_sys_system" = "Linux-android" || test "$ac_sys_system" = "iOS"; then + ac_cv_file__dev_ptmx=no + ac_cv_file__dev_ptc=no +else + if test "x$cross_compiling" = xyes; then + if test "${ac_cv_file__dev_ptmx+set}" != set; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 +printf %s "checking for /dev/ptmx... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not set" >&5 +printf "%s\n" "not set" >&6; } + as_fn_error $? "set ac_cv_file__dev_ptmx to yes/no in your CONFIG_SITE file when cross compiling" "$LINENO" 5 + fi + if test "${ac_cv_file__dev_ptc+set}" != set; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 +printf %s "checking for /dev/ptc... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not set" >&5 +printf "%s\n" "not set" >&6; } + as_fn_error $? "set ac_cv_file__dev_ptc to yes/no in your CONFIG_SITE file when cross compiling" "$LINENO" 5 + fi + fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 +printf %s "checking for /dev/ptmx... " >&6; } +if test ${ac_cv_file__dev_ptmx+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/dev/ptmx"; then + ac_cv_file__dev_ptmx=yes +else + ac_cv_file__dev_ptmx=no +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__dev_ptmx" >&5 +printf "%s\n" "$ac_cv_file__dev_ptmx" >&6; } +if test "x$ac_cv_file__dev_ptmx" = xyes +then : + +fi + + if test "x$ac_cv_file__dev_ptmx" = xyes; then + +printf "%s\n" "#define HAVE_DEV_PTMX 1" >>confdefs.h + + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 +printf %s "checking for /dev/ptc... " >&6; } +if test ${ac_cv_file__dev_ptc+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/dev/ptc"; then + ac_cv_file__dev_ptc=yes +else + ac_cv_file__dev_ptc=no +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__dev_ptc" >&5 +printf "%s\n" "$ac_cv_file__dev_ptc" >&6; } +if test "x$ac_cv_file__dev_ptc" = xyes +then : + +fi + + if test "x$ac_cv_file__dev_ptc" = xyes; then + +printf "%s\n" "#define HAVE_DEV_PTC 1" >>confdefs.h + + fi +fi + +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + +ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +" +if test "x$ac_cv_type_socklen_t" = xyes +then : + +printf "%s\n" "#define HAVE_SOCKLEN_T 1" >>confdefs.h + + +else case e in #( + e) +printf "%s\n" "#define socklen_t int" >>confdefs.h + ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken mbstowcs" >&5 +printf %s "checking for broken mbstowcs... " >&6; } +if test ${ac_cv_broken_mbstowcs+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + ac_cv_broken_mbstowcs=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +int main(void) { + size_t len = -1; + const char *str = "text"; + len = mbstowcs(NULL, str, 0); + return (len != 4); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_broken_mbstowcs=no +else case e in #( + e) ac_cv_broken_mbstowcs=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_mbstowcs" >&5 +printf "%s\n" "$ac_cv_broken_mbstowcs" >&6; } +if test "$ac_cv_broken_mbstowcs" = yes +then + +printf "%s\n" "#define HAVE_BROKEN_MBSTOWCS 1" >>confdefs.h + +fi + +# Check for --with-computed-gotos +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-computed-gotos" >&5 +printf %s "checking for --with-computed-gotos... " >&6; } + +# Check whether --with-computed-gotos was given. +if test ${with_computed_gotos+y} +then : + withval=$with_computed_gotos; +if test "$withval" = yes +then + +printf "%s\n" "#define USE_COMPUTED_GOTOS 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +if test "$withval" = no +then + +printf "%s\n" "#define USE_COMPUTED_GOTOS 0" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 +printf "%s\n" "no value specified" >&6; } ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports computed gotos" >&5 +printf %s "checking whether $CC supports computed gotos... " >&6; } +if test ${ac_cv_computed_gotos+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "$cross_compiling" = yes +then : + if test "${with_computed_gotos+set}" = set; then + ac_cv_computed_gotos="$with_computed_gotos -- configured --with(out)-computed-gotos" + else + ac_cv_computed_gotos=no + fi +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int main(int argc, char **argv) +{ + static void *targets[1] = { &&LABEL1 }; + goto LABEL2; +LABEL1: + return 0; +LABEL2: + goto *targets[0]; + return 1; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_computed_gotos=yes +else case e in #( + e) ac_cv_computed_gotos=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_computed_gotos" >&5 +printf "%s\n" "$ac_cv_computed_gotos" >&6; } +case "$ac_cv_computed_gotos" in yes*) + +printf "%s\n" "#define HAVE_COMPUTED_GOTOS 1" >>confdefs.h + +esac + +# Check for --with-tail-call-interp +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-tail-call-interp" >&5 +printf %s "checking for --with-tail-call-interp... " >&6; } + +# Check whether --with-tail-call-interp was given. +if test ${with_tail_call_interp+y} +then : + withval=$with_tail_call_interp; +if test "$withval" = yes +then + +printf "%s\n" "#define _Py_TAIL_CALL_INTERP 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +if test "$withval" = no +then + +printf "%s\n" "#define _Py_TAIL_CALL_INTERP 0" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 +printf "%s\n" "no value specified" >&6; } ;; +esac +fi + + +# Check for --with-remote-debug +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-remote-debug" >&5 +printf %s "checking for --with-remote-debug... " >&6; } + +# Check whether --with-remote-debug was given. +if test ${with_remote_debug+y} +then : + withval=$with_remote_debug; +else case e in #( + e) with_remote_debug=yes ;; +esac +fi + + +if test "$with_remote_debug" = yes; then + +printf "%s\n" "#define Py_REMOTE_DEBUG 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +case $ac_sys_system in +AIX*) + +printf "%s\n" "#define HAVE_BROKEN_PIPE_BUF 1" >>confdefs.h + ;; +esac + + + + +for h in `(cd $srcdir;echo Python/thread_*.h)` +do + THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" +done + + +SRCDIRS="\ + Modules \ + Modules/_ctypes \ + Modules/_decimal \ + Modules/_hacl \ + Modules/_io \ + Modules/_multiprocessing \ + Modules/_remote_debugging \ + Modules/_sqlite \ + Modules/_sre \ + Modules/_testcapi \ + Modules/_testinternalcapi \ + Modules/_testlimitedcapi \ + Modules/_xxtestfuzz \ + Modules/_zstd \ + Modules/cjkcodecs \ + Modules/expat \ + Objects \ + Objects/mimalloc \ + Objects/mimalloc/prim \ + Parser \ + Parser/tokenizer \ + Parser/lexer \ + Programs \ + Python \ + Python/frozen_modules" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5 +printf %s "checking for build directories... " >&6; } +for dir in $SRCDIRS; do + if test ! -d $dir; then + mkdir $dir + fi +done +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 +printf "%s\n" "done" >&6; } + +# Availability of -O2: +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -O2" >&5 +printf %s "checking for -O2... " >&6; } +if test ${ac_cv_compile_o2+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +saved_cflags="$CFLAGS" +CFLAGS="-O2" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_compile_o2=yes +else case e in #( + e) ac_cv_compile_o2=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +CFLAGS="$saved_cflags" + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_compile_o2" >&5 +printf "%s\n" "$ac_cv_compile_o2" >&6; } + +# _FORTIFY_SOURCE wrappers for memmove and bcopy are incorrect: +# http://sourceware.org/ml/libc-alpha/2010-12/msg00009.html +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for glibc _FORTIFY_SOURCE/memmove bug" >&5 +printf %s "checking for glibc _FORTIFY_SOURCE/memmove bug... " >&6; } +saved_cflags="$CFLAGS" +CFLAGS="-O2 -D_FORTIFY_SOURCE=2" +if test "$ac_cv_compile_o2" = no; then + CFLAGS="" +fi +if test "$cross_compiling" = yes +then : + have_glibc_memmove_bug=undefined +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +void foo(void *p, void *q) { memmove(p, q, 19); } +int main(void) { + char a[32] = "123456789000000000"; + foo(&a[9], a); + if (strcmp(a, "123456789123456789000000000") != 0) + return 1; + foo(a, &a[9]); + if (strcmp(a, "123456789000000000") != 0) + return 1; + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + have_glibc_memmove_bug=no +else case e in #( + e) have_glibc_memmove_bug=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +CFLAGS="$saved_cflags" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_glibc_memmove_bug" >&5 +printf "%s\n" "$have_glibc_memmove_bug" >&6; } +if test "$have_glibc_memmove_bug" = yes; then + +printf "%s\n" "#define HAVE_GLIBC_MEMMOVE_BUG 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we need to manually block large inlining in ceval.c" >&5 +printf %s "checking if we need to manually block large inlining in ceval.c... " >&6; } +if test "$cross_compiling" = yes +then : + block_huge_inlining_in_ceval=undefined +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int main(void) { +// See gh-148284: Clang 22 seems to have interactions with inlining +// and the stackref buffer which cause 40 kB of stack usage on x86-64 +// in buggy versions of _PyEval_EvalFrameDefault() in computed goto +// interpreter. The normal usage seen is normally 1-2 kB. +#if defined(__clang__) && (__clang_major__ == 22) + return 1; +#else + return 0; +#endif +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + block_huge_inlining_in_ceval=no +else case e in #( + e) block_huge_inlining_in_ceval=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $block_huge_inlining_in_ceval" >&5 +printf "%s\n" "$block_huge_inlining_in_ceval" >&6; } + +if test "$block_huge_inlining_in_ceval" = yes && test "$ac_cv_computed_gotos" = yes; then + # gh-148284: Suppress inlining of functions whose stack size exceeds + # 512 bytes. This number should be tuned to follow the C stack + # consumption in _PyEval_EvalFrameDefault() on computed goto + # interpreter. + CFLAGS_CEVAL="$CFLAGS_CEVAL -finline-max-stacksize=512" +fi + + +if test "$ac_cv_gcc_asm_for_x87" = yes; then + # Some versions of gcc miscompile inline asm: + # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46491 + # http://gcc.gnu.org/ml/gcc/2010-11/msg00366.html + case $ac_cv_cc_name in + gcc) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc ipa-pure-const bug" >&5 +printf %s "checking for gcc ipa-pure-const bug... " >&6; } + saved_cflags="$CFLAGS" + CFLAGS="-O2" + if test "$cross_compiling" = yes +then : + have_ipa_pure_const_bug=undefined +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + __attribute__((noinline)) int + foo(int *p) { + int r; + asm ( "movl \$6, (%1)\n\t" + "xorl %0, %0\n\t" + : "=r" (r) : "r" (p) : "memory" + ); + return r; + } + int main(void) { + int p = 8; + if ((foo(&p) ? : p) != 6) + return 1; + return 0; + } + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + have_ipa_pure_const_bug=no +else case e in #( + e) have_ipa_pure_const_bug=yes ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + CFLAGS="$saved_cflags" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_ipa_pure_const_bug" >&5 +printf "%s\n" "$have_ipa_pure_const_bug" >&6; } + if test "$have_ipa_pure_const_bug" = yes; then + +printf "%s\n" "#define HAVE_IPA_PURE_CONST_BUG 1" >>confdefs.h + + fi + ;; + esac +fi + +# ensurepip option +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ensurepip" >&5 +printf %s "checking for ensurepip... " >&6; } + +# Check whether --with-ensurepip was given. +if test ${with_ensurepip+y} +then : + withval=$with_ensurepip; +else case e in #( + e) + case $ac_sys_system in #( + Emscripten) : + with_ensurepip=no ;; #( + WASI) : + with_ensurepip=no ;; #( + iOS) : + with_ensurepip=no ;; #( + *) : + with_ensurepip=upgrade + ;; +esac + ;; +esac +fi + +case $with_ensurepip in #( + yes|upgrade) : + ENSUREPIP=upgrade ;; #( + install) : + ENSUREPIP=install ;; #( + no) : + ENSUREPIP=no ;; #( + *) : + as_fn_error $? "--with-ensurepip=upgrade|install|no" "$LINENO" 5 ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ENSUREPIP" >&5 +printf "%s\n" "$ENSUREPIP" >&6; } + + +# check if the dirent structure of a d_type field and DT_UNKNOWN is defined +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the dirent structure of a d_type field" >&5 +printf %s "checking if the dirent structure of a d_type field... " >&6; } +if test ${ac_cv_dirent_d_type+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <dirent.h> + + int main(void) { + struct dirent entry; + return entry.d_type == DT_UNKNOWN; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_dirent_d_type=yes +else case e in #( + e) ac_cv_dirent_d_type=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dirent_d_type" >&5 +printf "%s\n" "$ac_cv_dirent_d_type" >&6; } + +if test "x$ac_cv_dirent_d_type" = xyes +then : + + +printf "%s\n" "#define HAVE_DIRENT_D_TYPE 1" >>confdefs.h + + +fi + +# check if the Linux getrandom() syscall is available +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the Linux getrandom() syscall" >&5 +printf %s "checking for the Linux getrandom() syscall... " >&6; } +if test ${ac_cv_getrandom_syscall+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <stddef.h> + #include <unistd.h> + #include <sys/syscall.h> + #include <linux/random.h> + + int main(void) { + char buffer[1]; + const size_t buflen = sizeof(buffer); + const int flags = GRND_NONBLOCK; + /* ignore the result, Python checks for ENOSYS and EAGAIN at runtime */ + (void)syscall(SYS_getrandom, buffer, buflen, flags); + return 0; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_getrandom_syscall=yes +else case e in #( + e) ac_cv_getrandom_syscall=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_getrandom_syscall" >&5 +printf "%s\n" "$ac_cv_getrandom_syscall" >&6; } + +if test "x$ac_cv_getrandom_syscall" = xyes +then : + + +printf "%s\n" "#define HAVE_GETRANDOM_SYSCALL 1" >>confdefs.h + + +fi + +# check if the getrandom() function is available +# the test was written for the Solaris function of <sys/random.h> +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the getrandom() function" >&5 +printf %s "checking for the getrandom() function... " >&6; } +if test ${ac_cv_func_getrandom+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <stddef.h> + #include <sys/random.h> + + int main(void) { + char buffer[1]; + const size_t buflen = sizeof(buffer); + const int flags = 0; + /* ignore the result, Python checks for ENOSYS at runtime */ + (void)getrandom(buffer, buflen, flags); + return 0; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_func_getrandom=yes +else case e in #( + e) ac_cv_func_getrandom=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getrandom" >&5 +printf "%s\n" "$ac_cv_func_getrandom" >&6; } + +if test "x$ac_cv_func_getrandom" = xyes +then : + + +printf "%s\n" "#define HAVE_GETRANDOM 1" >>confdefs.h + + +fi + +# checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c +# shm_* may only be available if linking against librt +POSIXSHMEM_CFLAGS='-I$(srcdir)/Modules/_multiprocessing' +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 +printf %s "checking for library containing shm_open... " >&6; } +if test ${ac_cv_search_shm_open+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char shm_open (void); +int +main (void) +{ +return shm_open (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_shm_open=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_shm_open+y} +then : + break +fi +done +if test ${ac_cv_search_shm_open+y} +then : + +else case e in #( + e) ac_cv_search_shm_open=no ;; +esac +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shm_open" >&5 +printf "%s\n" "$ac_cv_search_shm_open" >&6; } +ac_res=$ac_cv_search_shm_open +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + if test "x$ac_cv_search_shm_open" = x-lrt +then : + POSIXSHMEM_LIBS="-lrt" +fi + + save_ac_includes_default=$ac_includes_default + ac_includes_default="\ + ${ac_includes_default} + #ifndef __cplusplus + # ifdef HAVE_SYS_MMAN_H + # include <sys/mman.h> + # endif + #endif + " + + for ac_func in shm_open shm_unlink +do : + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | sed "$as_sed_sh"` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_func" | sed "$as_sed_cpp"` 1 +_ACEOF + have_posix_shmem=yes +else case e in #( + e) have_posix_shmem=no ;; +esac +fi + +done + ac_includes_default=$save_ac_includes_default + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +# Check for usable OpenSSL + + found=false + +# Check whether --with-openssl was given. +if test ${with_openssl+y} +then : + withval=$with_openssl; + case "$withval" in + "" | y | ye | yes | n | no) + as_fn_error $? "Invalid --with-openssl value" "$LINENO" 5 + ;; + *) ssldirs="$withval" + ;; + esac + +else case e in #( + e) + # if pkg-config is installed and openssl has installed a .pc file, + # then use that information and don't search ssldirs + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$PKG_CONFIG"; then + ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +PKG_CONFIG=$ac_cv_prog_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_PKG_CONFIG"; then + ac_ct_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_PKG_CONFIG"; then + ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG +if test -n "$ac_ct_PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 +printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_ct_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" +fi + + if test x"$PKG_CONFIG" != x""; then + OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null` + if test $? = 0; then + OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null` + OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null` + found=true + fi + fi + + # no such luck; use some default ssldirs + if ! $found; then + ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" + fi + + ;; +esac +fi + + + + # note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in + # an 'openssl' subdirectory + + if ! $found; then + OPENSSL_INCLUDES= + for ssldir in $ssldirs; do + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for include/openssl/ssl.h in $ssldir" >&5 +printf %s "checking for include/openssl/ssl.h in $ssldir... " >&6; } + if test -f "$ssldir/include/openssl/ssl.h"; then + OPENSSL_INCLUDES="-I$ssldir/include" + OPENSSL_LDFLAGS="-L$ssldir/lib" + OPENSSL_LIBS="-lssl -lcrypto" + found=true + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + break + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + done + + # if the file wasn't found, well, go ahead and try the link anyway -- maybe + # it will just work! + fi + + # try the preprocessor and linker with our new flags, + # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiling and linking against OpenSSL works" >&5 +printf %s "checking whether compiling and linking against OpenSSL works... " >&6; } + echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \ + "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&5 + + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + save_CPPFLAGS="$CPPFLAGS" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" + LIBS="$OPENSSL_LIBS $LIBS" + CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <openssl/ssl.h> +int +main (void) +{ +SSL_new(NULL) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_openssl=yes + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_openssl=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + + + + + + +# rpath to libssl and libcrypto +if test "x$GNULD" = xyes +then : + + rpath_arg="-Wl,--enable-new-dtags,-rpath=" + +else case e in #( + e) + if test "$ac_sys_system" = "Darwin" + then + rpath_arg="-Wl,-rpath," + else + rpath_arg="-Wl,-rpath=" + fi + ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-openssl-rpath" >&5 +printf %s "checking for --with-openssl-rpath... " >&6; } + +# Check whether --with-openssl-rpath was given. +if test ${with_openssl_rpath+y} +then : + withval=$with_openssl_rpath; +else case e in #( + e) with_openssl_rpath=no + ;; +esac +fi + +case $with_openssl_rpath in #( + auto|yes) : + + OPENSSL_RPATH=auto + for arg in "$OPENSSL_LDFLAGS"; do + case $arg in #( + -L*) : + OPENSSL_LDFLAGS_RPATH="$OPENSSL_LDFLAGS_RPATH ${rpath_arg}$(echo $arg | cut -c3-)" + ;; #( + *) : + ;; +esac + done + ;; #( + no) : + OPENSSL_RPATH= ;; #( + *) : + if test -d "$with_openssl_rpath" +then : + + OPENSSL_RPATH="$with_openssl_rpath" + OPENSSL_LDFLAGS_RPATH="${rpath_arg}$with_openssl_rpath" + +else case e in #( + e) as_fn_error $? "--with-openssl-rpath \"$with_openssl_rpath\" is not a directory" "$LINENO" 5 ;; +esac +fi + + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_RPATH" >&5 +printf "%s\n" "$OPENSSL_RPATH" >&6; } + +# This static linking is NOT OFFICIALLY SUPPORTED and not advertised. +# Requires static OpenSSL build with position-independent code. Some features +# like DSO engines or external OSSL providers don't work. Only tested with GCC +# and clang on X86_64. +if test "x$PY_UNSUPPORTED_OPENSSL_BUILD" = xstatic +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unsupported static openssl build" >&5 +printf %s "checking for unsupported static openssl build... " >&6; } + new_OPENSSL_LIBS= + for arg in $OPENSSL_LIBS; do + case $arg in #( + -l*) : + + libname=$(echo $arg | cut -c3-) + new_OPENSSL_LIBS="$new_OPENSSL_LIBS -l:lib${libname}.a -Wl,--exclude-libs,lib${libname}.a" + ;; #( + *) : + new_OPENSSL_LIBS="$new_OPENSSL_LIBS $arg" + ;; +esac + done + OPENSSL_LIBS="$new_OPENSSL_LIBS $ZLIB_LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_LIBS" >&5 +printf "%s\n" "$OPENSSL_LIBS" >&6; } + +fi + +LIBCRYPTO_LIBS= +for arg in $OPENSSL_LIBS; do + case $arg in #( + -l*ssl*|-Wl*ssl*) : + ;; #( + *) : + LIBCRYPTO_LIBS="$LIBCRYPTO_LIBS $arg" + ;; +esac +done + +# check if OpenSSL libraries work as expected +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + LIBS="$LIBS $OPENSSL_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required ssl module APIs" >&5 +printf %s "checking whether OpenSSL provides required ssl module APIs... " >&6; } +if test ${ac_cv_working_openssl_ssl+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <openssl/opensslv.h> + #include <openssl/ssl.h> + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + static void keylog_cb(const SSL *ssl, const char *line) {} + +int +main (void) +{ + + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + SSL_CTX_set_keylog_callback(ctx, keylog_cb); + SSL *ssl = SSL_new(ctx); + X509_VERIFY_PARAM *param = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set1_host(param, "python.org", 0); + SSL_free(ssl); + SSL_CTX_free(ctx); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_working_openssl_ssl=yes +else case e in #( + e) ac_cv_working_openssl_ssl=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_ssl" >&5 +printf "%s\n" "$ac_cv_working_openssl_ssl" >&6; } + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + LIBS="$LIBS $LIBCRYPTO_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required hashlib module APIs" >&5 +printf %s "checking whether OpenSSL provides required hashlib module APIs... " >&6; } +if test ${ac_cv_working_openssl_hashlib+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <openssl/opensslv.h> + #include <openssl/evp.h> + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + +int +main (void) +{ + + OBJ_nid2sn(NID_md5); + OBJ_nid2sn(NID_sha1); + OBJ_nid2sn(NID_sha512); + OBJ_nid2sn(NID_sha3_512); + EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_working_openssl_hashlib=yes +else case e in #( + e) ac_cv_working_openssl_hashlib=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_hashlib" >&5 +printf "%s\n" "$ac_cv_working_openssl_hashlib" >&6; } + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +# ssl module default cipher suite string + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-ssl-default-suites" >&5 +printf %s "checking for --with-ssl-default-suites... " >&6; } + +# Check whether --with-ssl-default-suites was given. +if test ${with_ssl_default_suites+y} +then : + withval=$with_ssl_default_suites; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +case "$withval" in + python) + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 1" >>confdefs.h + + ;; + openssl) + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 2" >>confdefs.h + + ;; + *) + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 0" >>confdefs.h + + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHER_STRING \"$withval\"" >>confdefs.h + + ;; +esac + +else case e in #( + e) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: python" >&5 +printf "%s\n" "python" >&6; } +printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 1" >>confdefs.h + + ;; +esac +fi + + +# builtin hash modules +default_hashlib_hashes="md5,sha1,sha2,sha3,blake2" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-builtin-hashlib-hashes" >&5 +printf %s "checking for --with-builtin-hashlib-hashes... " >&6; } + +# Check whether --with-builtin-hashlib-hashes was given. +if test ${with_builtin_hashlib_hashes+y} +then : + withval=$with_builtin_hashlib_hashes; + case $with_builtin_hashlib_hashes in #( + yes) : + with_builtin_hashlib_hashes=$default_hashlib_hashes ;; #( + no) : + with_builtin_hashlib_hashes="" + ;; #( + *) : + ;; +esac + +else case e in #( + e) with_builtin_hashlib_hashes=$default_hashlib_hashes ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_builtin_hashlib_hashes" >&5 +printf "%s\n" "$with_builtin_hashlib_hashes" >&6; } + +printf "%s\n" "#define PY_BUILTIN_HASHLIB_HASHES \"$with_builtin_hashlib_hashes\"" >>confdefs.h + + +as_save_IFS=$IFS +IFS=, +for builtin_hash in $with_builtin_hashlib_hashes; do + case $builtin_hash in #( + md5) : + with_builtin_md5=yes ;; #( + sha1) : + with_builtin_sha1=yes ;; #( + sha2) : + with_builtin_sha2=yes ;; #( + sha3) : + with_builtin_sha3=yes ;; #( + blake2) : + with_builtin_blake2=yes + ;; #( + *) : + ;; +esac +done +IFS=$as_save_IFS + +# Check whether to disable test modules. Once set, setup.py will not build +# test extension modules and "make install" will not install test suites. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --disable-test-modules" >&5 +printf %s "checking for --disable-test-modules... " >&6; } +# Check whether --enable-test-modules was given. +if test ${enable_test_modules+y} +then : + enableval=$enable_test_modules; + if test "x$enable_test_modules" = xyes +then : + TEST_MODULES=yes +else case e in #( + e) TEST_MODULES=no ;; +esac +fi + +else case e in #( + e) TEST_MODULES=yes ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TEST_MODULES" >&5 +printf "%s\n" "$TEST_MODULES" >&6; } + + +# Check for --with-build-details-suffix +BUILD_DETAILS=build-details.json + +# Check whether --with-build-details-suffix was given. +if test ${with_build_details_suffix+y} +then : + withval=$with_build_details_suffix; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-build-details-suffix" >&5 +printf %s "checking for --with-build-details-suffix... " >&6; } + if test "x$with_build_details_suffix" = xno +then : + as_fn_error $? "invalid --with-build-details-suffix option: expected custom suffix or \"yes\", not \"no\"" "$LINENO" 5 + +fi + if test "x$with_build_details_suffix" = xyes +then : + + colocated_install=yes + threading_suffix="" + if [ "$ABI_THREAD" = "t" ]; then + threading_suffix=-free-threading + fi + debug_suffix="" + if [ "$Py_DEBUG" = "true" ]; then + debug_suffix=-debug + fi + BUILD_DETAILS=build-details.$MULTIARCH$threading_suffix$debug_suffix.json + +else case e in #( + e) + BUILD_DETAILS=build-details.$with_build_details_suffix.json + + ;; +esac +fi + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_build_details_suffix" >&5 +printf "%s\n" "$with_build_details_suffix" >&6; } +BUILD_DETAILS=$BUILD_DETAILS + + +# gh-109054: Check if -latomic is needed to get <pyatomic.h> atomic functions. +# On Linux aarch64, GCC may require programs and libraries to be linked +# explicitly to libatomic. Call _Py_atomic_or_uint64() which may require +# libatomic __atomic_fetch_or_8(), or not, depending on the C compiler and the +# compiler flags. +# +# gh-112779: On RISC-V, GCC 12 and earlier require libatomic support for 1-byte +# and 2-byte operations, but not for 8-byte operations. +# +# Avoid #include <Python.h> or #include <pyport.h>. The <Python.h> header +# requires <pyconfig.h> header which is only written below by AC_OUTPUT below. +# If the check is done after AC_OUTPUT, modifying LIBS has no effect +# anymore. <pyport.h> cannot be included alone, it's designed to be included +# by <Python.h>: it expects other includes and macros to be defined. +save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether libatomic is needed by <pyatomic.h>" >&5 +printf %s "checking whether libatomic is needed by <pyatomic.h>... " >&6; } +if test ${ac_cv_libatomic_needed+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +// pyatomic.h needs uint64_t and Py_ssize_t types +#include <stdint.h> // int64_t, intptr_t +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> // ssize_t +#endif +// Code adapted from Include/pyport.h +#if HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef intptr_t Py_ssize_t; +#else +# error "unable to define Py_ssize_t" +#endif + +#include "pyatomic.h" + +int main() +{ + uint64_t value; + _Py_atomic_store_uint64(&value, 2); + if (_Py_atomic_or_uint64(&value, 8) != 2) { + return 1; // error + } + if (_Py_atomic_load_uint64(&value) != 10) { + return 1; // error + } + uint8_t byte = 0xb8; + if (_Py_atomic_or_uint8(&byte, 0x2d) != 0xb8) { + return 1; // error + } + if (_Py_atomic_load_uint8(&byte) != 0xbd) { + return 1; // error + } + return 0; // all good +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_libatomic_needed=no +else case e in #( + e) ac_cv_libatomic_needed=yes ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libatomic_needed" >&5 +printf "%s\n" "$ac_cv_libatomic_needed" >&6; } + +if test "x$ac_cv_libatomic_needed" = xyes +then : + LIBS="${LIBS} -latomic" + LIBATOMIC=${LIBATOMIC-"-latomic"} +fi +CPPFLAGS=$save_CPPFLAGS + + +# gh-59705: Maximum length in bytes of a thread name +case "$ac_sys_system" in + Linux*) _PYTHREAD_NAME_MAXLEN=15;; # Linux and Android + SunOS*) _PYTHREAD_NAME_MAXLEN=31;; + NetBSD*) _PYTHREAD_NAME_MAXLEN=15;; # gh-131268 + Darwin) _PYTHREAD_NAME_MAXLEN=63;; + iOS) _PYTHREAD_NAME_MAXLEN=63;; + FreeBSD*) _PYTHREAD_NAME_MAXLEN=19;; # gh-131268 + OpenBSD*) _PYTHREAD_NAME_MAXLEN=23;; # gh-131268 + CYGWIN*) _PYTHREAD_NAME_MAXLEN=16;; + *) _PYTHREAD_NAME_MAXLEN=;; +esac +if test -n "$_PYTHREAD_NAME_MAXLEN"; then + +printf "%s\n" "#define _PYTHREAD_NAME_MAXLEN $_PYTHREAD_NAME_MAXLEN" >>confdefs.h + +fi + + + +# stdlib + + +# stdlib not available +case $ac_sys_system in #( + AIX) : + + + py_cv_module__scproxy=n/a + ;; #( + VxWorks*) : + + + py_cv_module__scproxy=n/a + py_cv_module_termios=n/a + py_cv_module_grp=n/a + ;; #( + Darwin) : + ;; #( + iOS) : + + + + py_cv_module__curses=n/a + py_cv_module__curses_panel=n/a + py_cv_module__gdbm=n/a + py_cv_module__multiprocessing=n/a + py_cv_module__posixshmem=n/a + py_cv_module__posixsubprocess=n/a + py_cv_module__scproxy=n/a + py_cv_module__tkinter=n/a + py_cv_module_grp=n/a + py_cv_module_nis=n/a + py_cv_module_readline=n/a + py_cv_module_pwd=n/a + py_cv_module_spwd=n/a + py_cv_module_syslog=n/a + py_cv_module_=n/a + + ;; #( + CYGWIN*) : + + + py_cv_module__scproxy=n/a + ;; #( + QNX*) : + + + py_cv_module__scproxy=n/a + ;; #( + FreeBSD*) : + + + py_cv_module__scproxy=n/a + ;; #( + Emscripten) : + + + + py_cv_module__curses=n/a + py_cv_module__curses_panel=n/a + py_cv_module__dbm=n/a + py_cv_module__gdbm=n/a + py_cv_module__multiprocessing=n/a + py_cv_module__posixshmem=n/a + py_cv_module__posixsubprocess=n/a + py_cv_module__scproxy=n/a + py_cv_module__tkinter=n/a + py_cv_module__interpreters=n/a + py_cv_module__interpchannels=n/a + py_cv_module__interpqueues=n/a + py_cv_module_grp=n/a + py_cv_module_pwd=n/a + py_cv_module_resource=n/a + py_cv_module_syslog=n/a + py_cv_module_=n/a + + + + py_cv_module_readline=n/a + py_cv_module_=n/a + + ;; #( + WASI) : + + + + py_cv_module__curses=n/a + py_cv_module__curses_panel=n/a + py_cv_module__dbm=n/a + py_cv_module__gdbm=n/a + py_cv_module__multiprocessing=n/a + py_cv_module__posixshmem=n/a + py_cv_module__posixsubprocess=n/a + py_cv_module__scproxy=n/a + py_cv_module__tkinter=n/a + py_cv_module__interpreters=n/a + py_cv_module__interpchannels=n/a + py_cv_module__interpqueues=n/a + py_cv_module_grp=n/a + py_cv_module_pwd=n/a + py_cv_module_resource=n/a + py_cv_module_syslog=n/a + py_cv_module_=n/a + + + + py_cv_module__ctypes_test=n/a + py_cv_module__remote_debugging=n/a + py_cv_module__testimportmultiple=n/a + py_cv_module__testmultiphase=n/a + py_cv_module__testsinglephase=n/a + py_cv_module_fcntl=n/a + py_cv_module_mmap=n/a + py_cv_module_termios=n/a + py_cv_module_xxlimited=n/a + py_cv_module_xxlimited_35=n/a + py_cv_module_xxlimited_3_13=n/a + py_cv_module_=n/a + + ;; #( + *) : + + + py_cv_module__scproxy=n/a + + ;; +esac + + +case $host_cpu in #( + wasm32|wasm64) : + MODULE_BUILDTYPE=static ;; #( + *) : + MODULE_BUILDTYPE=${MODULE_BUILDTYPE:-shared} + ;; +esac + + + +MODULE_BLOCK= + + + + + + + if test "$py_cv_module__io" != "n/a" +then : + py_cv_module__io=yes +fi + if test "$py_cv_module__io" = yes; then + MODULE__IO_TRUE= + MODULE__IO_FALSE='#' +else + MODULE__IO_TRUE='#' + MODULE__IO_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__IO_STATE=$py_cv_module__io$as_nl" + if test "x$py_cv_module__io" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__IO_CFLAGS=-I\$(srcdir)/Modules/_io$as_nl" + + +fi + + + if test "$py_cv_module_time" != "n/a" +then : + py_cv_module_time=yes +fi + if test "$py_cv_module_time" = yes; then + MODULE_TIME_TRUE= + MODULE_TIME_FALSE='#' +else + MODULE_TIME_TRUE='#' + MODULE_TIME_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_TIME_STATE=$py_cv_module_time$as_nl" + if test "x$py_cv_module_time" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE_TIME_LDFLAGS=$TIMEMODULE_LIB$as_nl" + +fi + + + + if test "$py_cv_module_array" != "n/a" +then : + py_cv_module_array=yes +fi + if test "$py_cv_module_array" = yes; then + MODULE_ARRAY_TRUE= + MODULE_ARRAY_FALSE='#' +else + MODULE_ARRAY_TRUE='#' + MODULE_ARRAY_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_ARRAY_STATE=$py_cv_module_array$as_nl" + if test "x$py_cv_module_array" = xyes +then : + + + + +fi + + + if test "$py_cv_module__math_integer" != "n/a" +then : + py_cv_module__math_integer=yes +fi + if test "$py_cv_module__math_integer" = yes; then + MODULE__MATH_INTEGER_TRUE= + MODULE__MATH_INTEGER_FALSE='#' +else + MODULE__MATH_INTEGER_TRUE='#' + MODULE__MATH_INTEGER_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__MATH_INTEGER_STATE=$py_cv_module__math_integer$as_nl" + if test "x$py_cv_module__math_integer" = xyes +then : + + + + +fi + + + if test "$py_cv_module__asyncio" != "n/a" +then : + py_cv_module__asyncio=yes +fi + if test "$py_cv_module__asyncio" = yes; then + MODULE__ASYNCIO_TRUE= + MODULE__ASYNCIO_FALSE='#' +else + MODULE__ASYNCIO_TRUE='#' + MODULE__ASYNCIO_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__ASYNCIO_STATE=$py_cv_module__asyncio$as_nl" + if test "x$py_cv_module__asyncio" = xyes +then : + + + + +fi + + + if test "$py_cv_module__bisect" != "n/a" +then : + py_cv_module__bisect=yes +fi + if test "$py_cv_module__bisect" = yes; then + MODULE__BISECT_TRUE= + MODULE__BISECT_FALSE='#' +else + MODULE__BISECT_TRUE='#' + MODULE__BISECT_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__BISECT_STATE=$py_cv_module__bisect$as_nl" + if test "x$py_cv_module__bisect" = xyes +then : + + + + +fi + + + if test "$py_cv_module__csv" != "n/a" +then : + py_cv_module__csv=yes +fi + if test "$py_cv_module__csv" = yes; then + MODULE__CSV_TRUE= + MODULE__CSV_FALSE='#' +else + MODULE__CSV_TRUE='#' + MODULE__CSV_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CSV_STATE=$py_cv_module__csv$as_nl" + if test "x$py_cv_module__csv" = xyes +then : + + + + +fi + + + if test "$py_cv_module__heapq" != "n/a" +then : + py_cv_module__heapq=yes +fi + if test "$py_cv_module__heapq" = yes; then + MODULE__HEAPQ_TRUE= + MODULE__HEAPQ_FALSE='#' +else + MODULE__HEAPQ_TRUE='#' + MODULE__HEAPQ_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__HEAPQ_STATE=$py_cv_module__heapq$as_nl" + if test "x$py_cv_module__heapq" = xyes +then : + + + + +fi + + + if test "$py_cv_module__json" != "n/a" +then : + py_cv_module__json=yes +fi + if test "$py_cv_module__json" = yes; then + MODULE__JSON_TRUE= + MODULE__JSON_FALSE='#' +else + MODULE__JSON_TRUE='#' + MODULE__JSON_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__JSON_STATE=$py_cv_module__json$as_nl" + if test "x$py_cv_module__json" = xyes +then : + + + + +fi + + + if test "$py_cv_module__lsprof" != "n/a" +then : + py_cv_module__lsprof=yes +fi + if test "$py_cv_module__lsprof" = yes; then + MODULE__LSPROF_TRUE= + MODULE__LSPROF_FALSE='#' +else + MODULE__LSPROF_TRUE='#' + MODULE__LSPROF_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__LSPROF_STATE=$py_cv_module__lsprof$as_nl" + if test "x$py_cv_module__lsprof" = xyes +then : + + + + +fi + + + if test "$py_cv_module__pickle" != "n/a" +then : + py_cv_module__pickle=yes +fi + if test "$py_cv_module__pickle" = yes; then + MODULE__PICKLE_TRUE= + MODULE__PICKLE_FALSE='#' +else + MODULE__PICKLE_TRUE='#' + MODULE__PICKLE_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__PICKLE_STATE=$py_cv_module__pickle$as_nl" + if test "x$py_cv_module__pickle" = xyes +then : + + + + +fi + + + if test "$py_cv_module__posixsubprocess" != "n/a" +then : + py_cv_module__posixsubprocess=yes +fi + if test "$py_cv_module__posixsubprocess" = yes; then + MODULE__POSIXSUBPROCESS_TRUE= + MODULE__POSIXSUBPROCESS_FALSE='#' +else + MODULE__POSIXSUBPROCESS_TRUE='#' + MODULE__POSIXSUBPROCESS_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__POSIXSUBPROCESS_STATE=$py_cv_module__posixsubprocess$as_nl" + if test "x$py_cv_module__posixsubprocess" = xyes +then : + + + + +fi + + + if test "$py_cv_module__queue" != "n/a" +then : + py_cv_module__queue=yes +fi + if test "$py_cv_module__queue" = yes; then + MODULE__QUEUE_TRUE= + MODULE__QUEUE_FALSE='#' +else + MODULE__QUEUE_TRUE='#' + MODULE__QUEUE_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__QUEUE_STATE=$py_cv_module__queue$as_nl" + if test "x$py_cv_module__queue" = xyes +then : + + + + +fi + + + if test "$py_cv_module__random" != "n/a" +then : + py_cv_module__random=yes +fi + if test "$py_cv_module__random" = yes; then + MODULE__RANDOM_TRUE= + MODULE__RANDOM_FALSE='#' +else + MODULE__RANDOM_TRUE='#' + MODULE__RANDOM_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__RANDOM_STATE=$py_cv_module__random$as_nl" + if test "x$py_cv_module__random" = xyes +then : + + + + +fi + + + if test "$py_cv_module__remote_debugging" != "n/a" +then : + py_cv_module__remote_debugging=yes +fi + if test "$py_cv_module__remote_debugging" = yes; then + MODULE__REMOTE_DEBUGGING_TRUE= + MODULE__REMOTE_DEBUGGING_FALSE='#' +else + MODULE__REMOTE_DEBUGGING_TRUE='#' + MODULE__REMOTE_DEBUGGING_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__REMOTE_DEBUGGING_STATE=$py_cv_module__remote_debugging$as_nl" + if test "x$py_cv_module__remote_debugging" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__REMOTE_DEBUGGING_CFLAGS=$REMOTE_DEBUGGING_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__REMOTE_DEBUGGING_LDFLAGS=$REMOTE_DEBUGGING_LIBS$as_nl" + +fi + + + if test "$py_cv_module_select" != "n/a" +then : + py_cv_module_select=yes +fi + if test "$py_cv_module_select" = yes; then + MODULE_SELECT_TRUE= + MODULE_SELECT_FALSE='#' +else + MODULE_SELECT_TRUE='#' + MODULE_SELECT_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_SELECT_STATE=$py_cv_module_select$as_nl" + if test "x$py_cv_module_select" = xyes +then : + + + + +fi + + + if test "$py_cv_module__struct" != "n/a" +then : + py_cv_module__struct=yes +fi + if test "$py_cv_module__struct" = yes; then + MODULE__STRUCT_TRUE= + MODULE__STRUCT_FALSE='#' +else + MODULE__STRUCT_TRUE='#' + MODULE__STRUCT_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__STRUCT_STATE=$py_cv_module__struct$as_nl" + if test "x$py_cv_module__struct" = xyes +then : + + + + +fi + + + if test "$py_cv_module__types" != "n/a" +then : + py_cv_module__types=yes +fi + if test "$py_cv_module__types" = yes; then + MODULE__TYPES_TRUE= + MODULE__TYPES_FALSE='#' +else + MODULE__TYPES_TRUE='#' + MODULE__TYPES_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__TYPES_STATE=$py_cv_module__types$as_nl" + if test "x$py_cv_module__types" = xyes +then : + + + + +fi + + + if test "$py_cv_module__typing" != "n/a" +then : + py_cv_module__typing=yes +fi + if test "$py_cv_module__typing" = yes; then + MODULE__TYPING_TRUE= + MODULE__TYPING_FALSE='#' +else + MODULE__TYPING_TRUE='#' + MODULE__TYPING_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__TYPING_STATE=$py_cv_module__typing$as_nl" + if test "x$py_cv_module__typing" = xyes +then : + + + + +fi + + + if test "$py_cv_module__interpreters" != "n/a" +then : + py_cv_module__interpreters=yes +fi + if test "$py_cv_module__interpreters" = yes; then + MODULE__INTERPRETERS_TRUE= + MODULE__INTERPRETERS_FALSE='#' +else + MODULE__INTERPRETERS_TRUE='#' + MODULE__INTERPRETERS_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__INTERPRETERS_STATE=$py_cv_module__interpreters$as_nl" + if test "x$py_cv_module__interpreters" = xyes +then : + + + + +fi + + + if test "$py_cv_module__interpchannels" != "n/a" +then : + py_cv_module__interpchannels=yes +fi + if test "$py_cv_module__interpchannels" = yes; then + MODULE__INTERPCHANNELS_TRUE= + MODULE__INTERPCHANNELS_FALSE='#' +else + MODULE__INTERPCHANNELS_TRUE='#' + MODULE__INTERPCHANNELS_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__INTERPCHANNELS_STATE=$py_cv_module__interpchannels$as_nl" + if test "x$py_cv_module__interpchannels" = xyes +then : + + + + +fi + + + if test "$py_cv_module__interpqueues" != "n/a" +then : + py_cv_module__interpqueues=yes +fi + if test "$py_cv_module__interpqueues" = yes; then + MODULE__INTERPQUEUES_TRUE= + MODULE__INTERPQUEUES_FALSE='#' +else + MODULE__INTERPQUEUES_TRUE='#' + MODULE__INTERPQUEUES_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__INTERPQUEUES_STATE=$py_cv_module__interpqueues$as_nl" + if test "x$py_cv_module__interpqueues" = xyes +then : + + + + +fi + + + if test "$py_cv_module__zoneinfo" != "n/a" +then : + py_cv_module__zoneinfo=yes +fi + if test "$py_cv_module__zoneinfo" = yes; then + MODULE__ZONEINFO_TRUE= + MODULE__ZONEINFO_FALSE='#' +else + MODULE__ZONEINFO_TRUE='#' + MODULE__ZONEINFO_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__ZONEINFO_STATE=$py_cv_module__zoneinfo$as_nl" + if test "x$py_cv_module__zoneinfo" = xyes +then : + + + + +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _multiprocessing" >&5 +printf %s "checking for stdlib extension module _multiprocessing... " >&6; } + if test "$py_cv_module__multiprocessing" != "n/a" +then : + + if true +then : + if test "$ac_cv_func_sem_unlink" = "yes" +then : + py_cv_module__multiprocessing=yes +else case e in #( + e) py_cv_module__multiprocessing=missing ;; +esac +fi +else case e in #( + e) py_cv_module__multiprocessing=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__MULTIPROCESSING_STATE=$py_cv_module__multiprocessing$as_nl" + if test "x$py_cv_module__multiprocessing" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__MULTIPROCESSING_CFLAGS=-I\$(srcdir)/Modules/_multiprocessing$as_nl" + + +fi + if test "$py_cv_module__multiprocessing" = yes; then + MODULE__MULTIPROCESSING_TRUE= + MODULE__MULTIPROCESSING_FALSE='#' +else + MODULE__MULTIPROCESSING_TRUE='#' + MODULE__MULTIPROCESSING_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__multiprocessing" >&5 +printf "%s\n" "$py_cv_module__multiprocessing" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _posixshmem" >&5 +printf %s "checking for stdlib extension module _posixshmem... " >&6; } + if test "$py_cv_module__posixshmem" != "n/a" +then : + + if true +then : + if test "$have_posix_shmem" = "yes" +then : + py_cv_module__posixshmem=yes +else case e in #( + e) py_cv_module__posixshmem=missing ;; +esac +fi +else case e in #( + e) py_cv_module__posixshmem=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_STATE=$py_cv_module__posixshmem$as_nl" + if test "x$py_cv_module__posixshmem" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_CFLAGS=$POSIXSHMEM_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_LDFLAGS=$POSIXSHMEM_LIBS$as_nl" + +fi + if test "$py_cv_module__posixshmem" = yes; then + MODULE__POSIXSHMEM_TRUE= + MODULE__POSIXSHMEM_FALSE='#' +else + MODULE__POSIXSHMEM_TRUE='#' + MODULE__POSIXSHMEM_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__posixshmem" >&5 +printf "%s\n" "$py_cv_module__posixshmem" >&6; } + + + + if test "$py_cv_module__statistics" != "n/a" +then : + py_cv_module__statistics=yes +fi + if test "$py_cv_module__statistics" = yes; then + MODULE__STATISTICS_TRUE= + MODULE__STATISTICS_FALSE='#' +else + MODULE__STATISTICS_TRUE='#' + MODULE__STATISTICS_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__STATISTICS_STATE=$py_cv_module__statistics$as_nl" + if test "x$py_cv_module__statistics" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE__STATISTICS_LDFLAGS=$LIBM$as_nl" + +fi + + + if test "$py_cv_module_cmath" != "n/a" +then : + py_cv_module_cmath=yes +fi + if test "$py_cv_module_cmath" = yes; then + MODULE_CMATH_TRUE= + MODULE_CMATH_FALSE='#' +else + MODULE_CMATH_TRUE='#' + MODULE_CMATH_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_CMATH_STATE=$py_cv_module_cmath$as_nl" + if test "x$py_cv_module_cmath" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE_CMATH_LDFLAGS=$LIBM$as_nl" + +fi + + + if test "$py_cv_module_math" != "n/a" +then : + py_cv_module_math=yes +fi + if test "$py_cv_module_math" = yes; then + MODULE_MATH_TRUE= + MODULE_MATH_FALSE='#' +else + MODULE_MATH_TRUE='#' + MODULE_MATH_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_MATH_STATE=$py_cv_module_math$as_nl" + if test "x$py_cv_module_math" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE_MATH_LDFLAGS=$LIBM$as_nl" + +fi + + + + if test "$py_cv_module__datetime" != "n/a" +then : + py_cv_module__datetime=yes +fi + if test "$py_cv_module__datetime" = yes; then + MODULE__DATETIME_TRUE= + MODULE__DATETIME_FALSE='#' +else + MODULE__DATETIME_TRUE='#' + MODULE__DATETIME_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__DATETIME_STATE=$py_cv_module__datetime$as_nl" + if test "x$py_cv_module__datetime" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE__DATETIME_LDFLAGS=$TIMEMODULE_LIB $LIBM$as_nl" + +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module fcntl" >&5 +printf %s "checking for stdlib extension module fcntl... " >&6; } + if test "$py_cv_module_fcntl" != "n/a" +then : + + if true +then : + if test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes" +then : + py_cv_module_fcntl=yes +else case e in #( + e) py_cv_module_fcntl=missing ;; +esac +fi +else case e in #( + e) py_cv_module_fcntl=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_FCNTL_STATE=$py_cv_module_fcntl$as_nl" + if test "x$py_cv_module_fcntl" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE_FCNTL_LDFLAGS=$FCNTL_LIBS$as_nl" + +fi + if test "$py_cv_module_fcntl" = yes; then + MODULE_FCNTL_TRUE= + MODULE_FCNTL_FALSE='#' +else + MODULE_FCNTL_TRUE='#' + MODULE_FCNTL_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_fcntl" >&5 +printf "%s\n" "$py_cv_module_fcntl" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module mmap" >&5 +printf %s "checking for stdlib extension module mmap... " >&6; } + if test "$py_cv_module_mmap" != "n/a" +then : + + if true +then : + if test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes" +then : + py_cv_module_mmap=yes +else case e in #( + e) py_cv_module_mmap=missing ;; +esac +fi +else case e in #( + e) py_cv_module_mmap=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_MMAP_STATE=$py_cv_module_mmap$as_nl" + if test "x$py_cv_module_mmap" = xyes +then : + + + + +fi + if test "$py_cv_module_mmap" = yes; then + MODULE_MMAP_TRUE= + MODULE_MMAP_FALSE='#' +else + MODULE_MMAP_TRUE='#' + MODULE_MMAP_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_mmap" >&5 +printf "%s\n" "$py_cv_module_mmap" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _socket" >&5 +printf %s "checking for stdlib extension module _socket... " >&6; } + if test "$py_cv_module__socket" != "n/a" +then : + + if true +then : + if test "$ac_cv_header_sys_socket_h" = "yes" -a "$ac_cv_header_sys_types_h" = "yes" -a "$ac_cv_header_netinet_in_h" = "yes" +then : + py_cv_module__socket=yes +else case e in #( + e) py_cv_module__socket=missing ;; +esac +fi +else case e in #( + e) py_cv_module__socket=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SOCKET_STATE=$py_cv_module__socket$as_nl" + if test "x$py_cv_module__socket" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE__SOCKET_LDFLAGS=$SOCKET_LIBS$as_nl" + +fi + if test "$py_cv_module__socket" = yes; then + MODULE__SOCKET_TRUE= + MODULE__SOCKET_FALSE='#' +else + MODULE__SOCKET_TRUE='#' + MODULE__SOCKET_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__socket" >&5 +printf "%s\n" "$py_cv_module__socket" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module grp" >&5 +printf %s "checking for stdlib extension module grp... " >&6; } + if test "$py_cv_module_grp" != "n/a" +then : + + if true +then : + if test "$ac_cv_func_getgrent" = "yes" && + { test "$ac_cv_func_getgrgid" = "yes" || test "$ac_cv_func_getgrgid_r" = "yes"; } +then : + py_cv_module_grp=yes +else case e in #( + e) py_cv_module_grp=missing ;; +esac +fi +else case e in #( + e) py_cv_module_grp=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_GRP_STATE=$py_cv_module_grp$as_nl" + if test "x$py_cv_module_grp" = xyes +then : + + + + +fi + if test "$py_cv_module_grp" = yes; then + MODULE_GRP_TRUE= + MODULE_GRP_FALSE='#' +else + MODULE_GRP_TRUE='#' + MODULE_GRP_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_grp" >&5 +printf "%s\n" "$py_cv_module_grp" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pwd" >&5 +printf %s "checking for stdlib extension module pwd... " >&6; } + if test "$py_cv_module_pwd" != "n/a" +then : + + if true +then : + if test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes +then : + py_cv_module_pwd=yes +else case e in #( + e) py_cv_module_pwd=missing ;; +esac +fi +else case e in #( + e) py_cv_module_pwd=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_PWD_STATE=$py_cv_module_pwd$as_nl" + if test "x$py_cv_module_pwd" = xyes +then : + + + + +fi + if test "$py_cv_module_pwd" = yes; then + MODULE_PWD_TRUE= + MODULE_PWD_FALSE='#' +else + MODULE_PWD_TRUE='#' + MODULE_PWD_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pwd" >&5 +printf "%s\n" "$py_cv_module_pwd" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module resource" >&5 +printf %s "checking for stdlib extension module resource... " >&6; } + if test "$py_cv_module_resource" != "n/a" +then : + + if true +then : + if test "$ac_cv_header_sys_resource_h" = yes +then : + py_cv_module_resource=yes +else case e in #( + e) py_cv_module_resource=missing ;; +esac +fi +else case e in #( + e) py_cv_module_resource=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_RESOURCE_STATE=$py_cv_module_resource$as_nl" + if test "x$py_cv_module_resource" = xyes +then : + + + + +fi + if test "$py_cv_module_resource" = yes; then + MODULE_RESOURCE_TRUE= + MODULE_RESOURCE_FALSE='#' +else + MODULE_RESOURCE_TRUE='#' + MODULE_RESOURCE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_resource" >&5 +printf "%s\n" "$py_cv_module_resource" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _scproxy" >&5 +printf %s "checking for stdlib extension module _scproxy... " >&6; } + if test "$py_cv_module__scproxy" != "n/a" +then : + + if test "$ac_sys_system" = "Darwin" +then : + if true +then : + py_cv_module__scproxy=yes +else case e in #( + e) py_cv_module__scproxy=missing ;; +esac +fi +else case e in #( + e) py_cv_module__scproxy=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SCPROXY_STATE=$py_cv_module__scproxy$as_nl" + if test "x$py_cv_module__scproxy" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE__SCPROXY_LDFLAGS=-framework SystemConfiguration -framework CoreFoundation$as_nl" + +fi + if test "$py_cv_module__scproxy" = yes; then + MODULE__SCPROXY_TRUE= + MODULE__SCPROXY_FALSE='#' +else + MODULE__SCPROXY_TRUE='#' + MODULE__SCPROXY_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__scproxy" >&5 +printf "%s\n" "$py_cv_module__scproxy" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5 +printf %s "checking for stdlib extension module syslog... " >&6; } + if test "$py_cv_module_syslog" != "n/a" +then : + + if true +then : + if test "$ac_cv_header_syslog_h" = yes +then : + py_cv_module_syslog=yes +else case e in #( + e) py_cv_module_syslog=missing ;; +esac +fi +else case e in #( + e) py_cv_module_syslog=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_SYSLOG_STATE=$py_cv_module_syslog$as_nl" + if test "x$py_cv_module_syslog" = xyes +then : + + + + +fi + if test "$py_cv_module_syslog" = yes; then + MODULE_SYSLOG_TRUE= + MODULE_SYSLOG_FALSE='#' +else + MODULE_SYSLOG_TRUE='#' + MODULE_SYSLOG_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_syslog" >&5 +printf "%s\n" "$py_cv_module_syslog" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module termios" >&5 +printf %s "checking for stdlib extension module termios... " >&6; } + if test "$py_cv_module_termios" != "n/a" +then : + + if true +then : + if test "$ac_cv_header_termios_h" = yes +then : + py_cv_module_termios=yes +else case e in #( + e) py_cv_module_termios=missing ;; +esac +fi +else case e in #( + e) py_cv_module_termios=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_TERMIOS_STATE=$py_cv_module_termios$as_nl" + if test "x$py_cv_module_termios" = xyes +then : + + + + +fi + if test "$py_cv_module_termios" = yes; then + MODULE_TERMIOS_TRUE= + MODULE_TERMIOS_FALSE='#' +else + MODULE_TERMIOS_TRUE='#' + MODULE_TERMIOS_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_termios" >&5 +printf "%s\n" "$py_cv_module_termios" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pyexpat" >&5 +printf %s "checking for stdlib extension module pyexpat... " >&6; } + if test "$py_cv_module_pyexpat" != "n/a" +then : + + if true +then : + if test "$ac_cv_header_sys_time_h" = "yes" +then : + py_cv_module_pyexpat=yes +else case e in #( + e) py_cv_module_pyexpat=missing ;; +esac +fi +else case e in #( + e) py_cv_module_pyexpat=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_STATE=$py_cv_module_pyexpat$as_nl" + if test "x$py_cv_module_pyexpat" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_CFLAGS=$LIBEXPAT_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_LDFLAGS=$LIBEXPAT_LDFLAGS$as_nl" + +fi + if test "$py_cv_module_pyexpat" = yes; then + MODULE_PYEXPAT_TRUE= + MODULE_PYEXPAT_FALSE='#' +else + MODULE_PYEXPAT_TRUE='#' + MODULE_PYEXPAT_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pyexpat" >&5 +printf "%s\n" "$py_cv_module_pyexpat" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _elementtree" >&5 +printf %s "checking for stdlib extension module _elementtree... " >&6; } + if test "$py_cv_module__elementtree" != "n/a" +then : + + if true +then : + if true +then : + py_cv_module__elementtree=yes +else case e in #( + e) py_cv_module__elementtree=missing ;; +esac +fi +else case e in #( + e) py_cv_module__elementtree=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE_STATE=$py_cv_module__elementtree$as_nl" + if test "x$py_cv_module__elementtree" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE_CFLAGS=$LIBEXPAT_CFLAGS$as_nl" + + +fi + if test "$py_cv_module__elementtree" = yes; then + MODULE__ELEMENTTREE_TRUE= + MODULE__ELEMENTTREE_FALSE='#' +else + MODULE__ELEMENTTREE_TRUE='#' + MODULE__ELEMENTTREE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__elementtree" >&5 +printf "%s\n" "$py_cv_module__elementtree" >&6; } + + + if test "$py_cv_module__codecs_cn" != "n/a" +then : + py_cv_module__codecs_cn=yes +fi + if test "$py_cv_module__codecs_cn" = yes; then + MODULE__CODECS_CN_TRUE= + MODULE__CODECS_CN_FALSE='#' +else + MODULE__CODECS_CN_TRUE='#' + MODULE__CODECS_CN_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CODECS_CN_STATE=$py_cv_module__codecs_cn$as_nl" + if test "x$py_cv_module__codecs_cn" = xyes +then : + + + + +fi + + + if test "$py_cv_module__codecs_hk" != "n/a" +then : + py_cv_module__codecs_hk=yes +fi + if test "$py_cv_module__codecs_hk" = yes; then + MODULE__CODECS_HK_TRUE= + MODULE__CODECS_HK_FALSE='#' +else + MODULE__CODECS_HK_TRUE='#' + MODULE__CODECS_HK_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CODECS_HK_STATE=$py_cv_module__codecs_hk$as_nl" + if test "x$py_cv_module__codecs_hk" = xyes +then : + + + + +fi + + + if test "$py_cv_module__codecs_iso2022" != "n/a" +then : + py_cv_module__codecs_iso2022=yes +fi + if test "$py_cv_module__codecs_iso2022" = yes; then + MODULE__CODECS_ISO2022_TRUE= + MODULE__CODECS_ISO2022_FALSE='#' +else + MODULE__CODECS_ISO2022_TRUE='#' + MODULE__CODECS_ISO2022_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CODECS_ISO2022_STATE=$py_cv_module__codecs_iso2022$as_nl" + if test "x$py_cv_module__codecs_iso2022" = xyes +then : + + + + +fi + + + if test "$py_cv_module__codecs_jp" != "n/a" +then : + py_cv_module__codecs_jp=yes +fi + if test "$py_cv_module__codecs_jp" = yes; then + MODULE__CODECS_JP_TRUE= + MODULE__CODECS_JP_FALSE='#' +else + MODULE__CODECS_JP_TRUE='#' + MODULE__CODECS_JP_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CODECS_JP_STATE=$py_cv_module__codecs_jp$as_nl" + if test "x$py_cv_module__codecs_jp" = xyes +then : + + + + +fi + + + if test "$py_cv_module__codecs_kr" != "n/a" +then : + py_cv_module__codecs_kr=yes +fi + if test "$py_cv_module__codecs_kr" = yes; then + MODULE__CODECS_KR_TRUE= + MODULE__CODECS_KR_FALSE='#' +else + MODULE__CODECS_KR_TRUE='#' + MODULE__CODECS_KR_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CODECS_KR_STATE=$py_cv_module__codecs_kr$as_nl" + if test "x$py_cv_module__codecs_kr" = xyes +then : + + + + +fi + + + if test "$py_cv_module__codecs_tw" != "n/a" +then : + py_cv_module__codecs_tw=yes +fi + if test "$py_cv_module__codecs_tw" = yes; then + MODULE__CODECS_TW_TRUE= + MODULE__CODECS_TW_FALSE='#' +else + MODULE__CODECS_TW_TRUE='#' + MODULE__CODECS_TW_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CODECS_TW_STATE=$py_cv_module__codecs_tw$as_nl" + if test "x$py_cv_module__codecs_tw" = xyes +then : + + + + +fi + + + if test "$py_cv_module__multibytecodec" != "n/a" +then : + py_cv_module__multibytecodec=yes +fi + if test "$py_cv_module__multibytecodec" = yes; then + MODULE__MULTIBYTECODEC_TRUE= + MODULE__MULTIBYTECODEC_FALSE='#' +else + MODULE__MULTIBYTECODEC_TRUE='#' + MODULE__MULTIBYTECODEC_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__MULTIBYTECODEC_STATE=$py_cv_module__multibytecodec$as_nl" + if test "x$py_cv_module__multibytecodec" = xyes +then : + + + + +fi + + + if test "$py_cv_module_unicodedata" != "n/a" +then : + py_cv_module_unicodedata=yes +fi + if test "$py_cv_module_unicodedata" = yes; then + MODULE_UNICODEDATA_TRUE= + MODULE_UNICODEDATA_FALSE='#' +else + MODULE_UNICODEDATA_TRUE='#' + MODULE_UNICODEDATA_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_UNICODEDATA_STATE=$py_cv_module_unicodedata$as_nl" + if test "x$py_cv_module_unicodedata" = xyes +then : + + + + +fi + + +############################################################################### +# HACL* compilation and linking configuration (contact: @picnixz) +# +# Used by the HACL*-based implementations of cryptographic primitives. +# +# CPython provides a vendored copy of a subset of the HACL* project used +# to build extension modules of cryptographic primitives. On WASI, HACL* +# sources must be statically linked with the extension modules; on other +# platforms, the extension modules may assume that HACL* has been compiled +# as a shared library. +# +# Example for MD5: +# +# * Compile Modules/_hacl/Hacl_Hash_MD5.c into Modules/_hacl/Hacl_Hash_MD5.o. +# * Decide whether the object files are to be passed to the linker (emulate +# a shared library without having to install it) or if we need to create +# a static library for WASI. The following summarizes the values taken by +# the MODULE_<NAME>_LDFLAGS variable depending on the linkage type: +# - shared: MODULE__MD5_LDFLAGS is set to LIBHACL_MD5_OBJS +# - static: MODULE__MD5_LDFLAGS is set to Modules/_hacl/libHacl_Hash_MD5.a +# * Compile Modules/md5module.c into Modules/md5module.o. +# * Link Modules/md5module.o using $(MODULE__MD5_LDFLAGS) +# and get Modules/_md5$(EXT_SUFFIX). +# +# LIBHACL_FLAG_I: '-I' flags passed to $(CC) for HACL* and HACL*-based modules +# LIBHACL_FLAG_D: '-D' flags passed to $(CC) for HACL* and HACL*-based modules +# LIBHACL_CFLAGS: compiler flags passed for HACL* and HACL*-based modules +# LIBHACL_LDFLAGS: linker flags passed for HACL* and HACL*-based modules +LIBHACL_FLAG_I='-I$(srcdir)/Modules/_hacl -I$(srcdir)/Modules/_hacl/include' +LIBHACL_FLAG_D='-D_BSD_SOURCE -D_DEFAULT_SOURCE' +case "$ac_sys_system" in + Linux*) + if test "$ac_cv_func_explicit_bzero" = "no"; then + LIBHACL_FLAG_D="${LIBHACL_FLAG_D} -DLINUX_NO_EXPLICIT_BZERO" + fi + ;; +esac +LIBHACL_CFLAGS="${LIBHACL_FLAG_I} ${LIBHACL_FLAG_D} \$(PY_STDMODULE_CFLAGS) \$(CCSHARED)" + +LIBHACL_LDFLAGS= # for now, no specific linker flags are needed + + +if test "$UNIVERSAL_ARCHS" = "universal2" -o \ + \( "$build_cpu" = "aarch64" -a "$build_vendor" = "apple" \) +then + use_hacl_universal2_impl=yes +else + use_hacl_universal2_impl=no +fi + +# The SIMD files use aligned_alloc, which is not available on older versions of +# Android. +# The *mmintrin.h headers are x86-family-specific, so can't be used on WASI. +if test "$ac_sys_system" != "Linux-android" -a "$ac_sys_system" != "WASI" || \ + { test -n "$ANDROID_API_LEVEL" && test "$ANDROID_API_LEVEL" -ge 28; } +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -msse -msse2 -msse3 -msse4.1 -msse4.2" >&5 +printf %s "checking whether C compiler accepts -msse -msse2 -msse3 -msse4.1 -msse4.2... " >&6; } +if test ${ax_cv_check_cflags__Werror__msse__msse2__msse3__msse4_1__msse4_2+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -msse -msse2 -msse3 -msse4.1 -msse4.2" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__msse__msse2__msse3__msse4_1__msse4_2=yes +else case e in #( + e) ax_cv_check_cflags__Werror__msse__msse2__msse3__msse4_1__msse4_2=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__msse__msse2__msse3__msse4_1__msse4_2" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__msse__msse2__msse3__msse4_1__msse4_2" >&6; } +if test "x$ax_cv_check_cflags__Werror__msse__msse2__msse3__msse4_1__msse4_2" = xyes +then : + + LIBHACL_SIMD128_FLAGS="-msse -msse2 -msse3 -msse4.1 -msse4.2" + + +printf "%s\n" "#define _Py_HACL_CAN_COMPILE_VEC128 1" >>confdefs.h + + + # macOS universal2 builds *support* the -msse etc flags because they're + # available on x86_64. However, performance of the HACL SIMD128 implementation + # isn't great, so it's disabled on ARM64. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HACL* SIMD128 implementation" >&5 +printf %s "checking for HACL* SIMD128 implementation... " >&6; } + if test "$use_hacl_universal2_impl" = "yes"; then + LIBHACL_BLAKE2_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: universal2" >&5 +printf "%s\n" "universal2" >&6; } + else + LIBHACL_BLAKE2_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: standard" >&5 +printf "%s\n" "standard" >&6; } + fi + + +else case e in #( + e) : ;; +esac +fi + +fi + + + +# The SIMD files use aligned_alloc, which is not available on older versions of +# Android. +# The *mmintrin.h headers are x86-family-specific, so can't be used on WASI. +# +# Although AVX support is not guaranteed on Android +# (https://developer.android.com/ndk/guides/abis#86-64), this is safe because we do a +# runtime CPUID check. +if test "$ac_sys_system" != "Linux-android" -a "$ac_sys_system" != "WASI" || \ + { test -n "$ANDROID_API_LEVEL" && test "$ANDROID_API_LEVEL" -ge 28; } +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -mavx2" >&5 +printf %s "checking whether C compiler accepts -mavx2... " >&6; } +if test ${ax_cv_check_cflags__Werror__mavx2+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -mavx2" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__mavx2=yes +else case e in #( + e) ax_cv_check_cflags__Werror__mavx2=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__mavx2" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__mavx2" >&6; } +if test "x$ax_cv_check_cflags__Werror__mavx2" = xyes +then : + + LIBHACL_SIMD256_FLAGS="-mavx2" + +printf "%s\n" "#define _Py_HACL_CAN_COMPILE_VEC256 1" >>confdefs.h + + + # macOS universal2 builds *support* the -mavx2 compiler flag because it's + # available on x86_64; but the HACL SIMD256 build then fails because the + # implementation requires symbols that aren't available on ARM64. Use a + # wrapped implementation if we're building for universal2. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HACL* SIMD256 implementation" >&5 +printf %s "checking for HACL* SIMD256 implementation... " >&6; } + if test "$use_hacl_universal2_impl" = "yes"; then + LIBHACL_BLAKE2_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: universal2" >&5 +printf "%s\n" "universal2" >&6; } + else + LIBHACL_BLAKE2_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: standard" >&5 +printf "%s\n" "standard" >&6; } + fi + +else case e in #( + e) : ;; +esac +fi + +fi + + +### end(HACL* configuration) + +############################################################################### +# HACL*-based cryptographic primitives + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HACL* library linking type" >&5 +printf %s "checking for HACL* library linking type... " >&6; } +if test "$ac_sys_system" = "WASI" || test "$MODULE_BUILDTYPE" = "static"; then + LIBHACL_LDEPS_LIBTYPE=STATIC + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static" >&5 +printf "%s\n" "static" >&6; } +else + LIBHACL_LDEPS_LIBTYPE=SHARED + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared" >&5 +printf "%s\n" "shared" >&6; } +fi +# Used to complete the "MODULE_<NAME>_LDEPS" Makefile variable. +# The LDEPS variable is a Makefile rule prerequisite. + + + + + + + LIBHACL_MD5_LDFLAGS=LIBHACL_MD5_LIB_${LIBHACL_LDEPS_LIBTYPE} + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _md5" >&5 +printf %s "checking for stdlib extension module _md5... " >&6; } + if test "$py_cv_module__md5" != "n/a" +then : + + if test "$with_builtin_md5" = yes +then : + if true +then : + py_cv_module__md5=yes +else case e in #( + e) py_cv_module__md5=missing ;; +esac +fi +else case e in #( + e) py_cv_module__md5=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__MD5_STATE=$py_cv_module__md5$as_nl" + if test "x$py_cv_module__md5" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__MD5_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__MD5_LDFLAGS=\$($LIBHACL_MD5_LDFLAGS)$as_nl" + +fi + if test "$py_cv_module__md5" = yes; then + MODULE__MD5_TRUE= + MODULE__MD5_FALSE='#' +else + MODULE__MD5_TRUE='#' + MODULE__MD5_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__md5" >&5 +printf "%s\n" "$py_cv_module__md5" >&6; } + + + + + + LIBHACL_SHA1_LDFLAGS=LIBHACL_SHA1_LIB_${LIBHACL_LDEPS_LIBTYPE} + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha1" >&5 +printf %s "checking for stdlib extension module _sha1... " >&6; } + if test "$py_cv_module__sha1" != "n/a" +then : + + if test "$with_builtin_sha1" = yes +then : + if true +then : + py_cv_module__sha1=yes +else case e in #( + e) py_cv_module__sha1=missing ;; +esac +fi +else case e in #( + e) py_cv_module__sha1=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SHA1_STATE=$py_cv_module__sha1$as_nl" + if test "x$py_cv_module__sha1" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__SHA1_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA1_LDFLAGS=\$($LIBHACL_SHA1_LDFLAGS)$as_nl" + +fi + if test "$py_cv_module__sha1" = yes; then + MODULE__SHA1_TRUE= + MODULE__SHA1_FALSE='#' +else + MODULE__SHA1_TRUE='#' + MODULE__SHA1_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha1" >&5 +printf "%s\n" "$py_cv_module__sha1" >&6; } + + + + + + LIBHACL_SHA2_LDFLAGS=LIBHACL_SHA2_LIB_${LIBHACL_LDEPS_LIBTYPE} + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha2" >&5 +printf %s "checking for stdlib extension module _sha2... " >&6; } + if test "$py_cv_module__sha2" != "n/a" +then : + + if test "$with_builtin_sha2" = yes +then : + if true +then : + py_cv_module__sha2=yes +else case e in #( + e) py_cv_module__sha2=missing ;; +esac +fi +else case e in #( + e) py_cv_module__sha2=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SHA2_STATE=$py_cv_module__sha2$as_nl" + if test "x$py_cv_module__sha2" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__SHA2_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA2_LDFLAGS=\$($LIBHACL_SHA2_LDFLAGS)$as_nl" + +fi + if test "$py_cv_module__sha2" = yes; then + MODULE__SHA2_TRUE= + MODULE__SHA2_FALSE='#' +else + MODULE__SHA2_TRUE='#' + MODULE__SHA2_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha2" >&5 +printf "%s\n" "$py_cv_module__sha2" >&6; } + + + + + + LIBHACL_SHA3_LDFLAGS=LIBHACL_SHA3_LIB_${LIBHACL_LDEPS_LIBTYPE} + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha3" >&5 +printf %s "checking for stdlib extension module _sha3... " >&6; } + if test "$py_cv_module__sha3" != "n/a" +then : + + if test "$with_builtin_sha3" = yes +then : + if true +then : + py_cv_module__sha3=yes +else case e in #( + e) py_cv_module__sha3=missing ;; +esac +fi +else case e in #( + e) py_cv_module__sha3=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SHA3_STATE=$py_cv_module__sha3$as_nl" + if test "x$py_cv_module__sha3" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__SHA3_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA3_LDFLAGS=\$($LIBHACL_SHA3_LDFLAGS)$as_nl" + +fi + if test "$py_cv_module__sha3" = yes; then + MODULE__SHA3_TRUE= + MODULE__SHA3_FALSE='#' +else + MODULE__SHA3_TRUE='#' + MODULE__SHA3_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha3" >&5 +printf "%s\n" "$py_cv_module__sha3" >&6; } + + + + + + LIBHACL_BLAKE2_LDFLAGS=LIBHACL_BLAKE2_LIB_${LIBHACL_LDEPS_LIBTYPE} + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _blake2" >&5 +printf %s "checking for stdlib extension module _blake2... " >&6; } + if test "$py_cv_module__blake2" != "n/a" +then : + + if test "$with_builtin_blake2" = yes +then : + if true +then : + py_cv_module__blake2=yes +else case e in #( + e) py_cv_module__blake2=missing ;; +esac +fi +else case e in #( + e) py_cv_module__blake2=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_STATE=$py_cv_module__blake2$as_nl" + if test "x$py_cv_module__blake2" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_LDFLAGS=\$($LIBHACL_BLAKE2_LDFLAGS)$as_nl" + +fi + if test "$py_cv_module__blake2" = yes; then + MODULE__BLAKE2_TRUE= + MODULE__BLAKE2_FALSE='#' +else + MODULE__BLAKE2_TRUE='#' + MODULE__BLAKE2_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__blake2" >&5 +printf "%s\n" "$py_cv_module__blake2" >&6; } + + + + + + + LIBHACL_HMAC_LDFLAGS=LIBHACL_HMAC_LIB_${LIBHACL_LDEPS_LIBTYPE} + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hmac" >&5 +printf %s "checking for stdlib extension module _hmac... " >&6; } + if test "$py_cv_module__hmac" != "n/a" +then : + + if test "$ac_sys_system" != "Emscripten" +then : + if true +then : + py_cv_module__hmac=yes +else case e in #( + e) py_cv_module__hmac=missing ;; +esac +fi +else case e in #( + e) py_cv_module__hmac=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__HMAC_STATE=$py_cv_module__hmac$as_nl" + if test "x$py_cv_module__hmac" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__HMAC_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HMAC_LDFLAGS=\$($LIBHACL_HMAC_LDFLAGS)$as_nl" + +fi + if test "$py_cv_module__hmac" = yes; then + MODULE__HMAC_TRUE= + MODULE__HMAC_FALSE='#' +else + MODULE__HMAC_TRUE='#' + MODULE__HMAC_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__hmac" >&5 +printf "%s\n" "$py_cv_module__hmac" >&6; } + + + +### end(cryptographic primitives) + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes" >&5 +printf %s "checking for stdlib extension module _ctypes... " >&6; } + if test "$py_cv_module__ctypes" != "n/a" +then : + + if true +then : + if test "$have_libffi" = yes +then : + py_cv_module__ctypes=yes +else case e in #( + e) py_cv_module__ctypes=missing ;; +esac +fi +else case e in #( + e) py_cv_module__ctypes=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CTYPES_STATE=$py_cv_module__ctypes$as_nl" + if test "x$py_cv_module__ctypes" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__CTYPES_CFLAGS=$NO_STRICT_OVERFLOW_CFLAGS $LIBFFI_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CTYPES_LDFLAGS=$LIBFFI_LIBS$as_nl" + +fi + if test "$py_cv_module__ctypes" = yes; then + MODULE__CTYPES_TRUE= + MODULE__CTYPES_FALSE='#' +else + MODULE__CTYPES_TRUE='#' + MODULE__CTYPES_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ctypes" >&5 +printf "%s\n" "$py_cv_module__ctypes" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _curses" >&5 +printf %s "checking for stdlib extension module _curses... " >&6; } + if test "$py_cv_module__curses" != "n/a" +then : + + if true +then : + if test "$have_curses" = "yes" +then : + py_cv_module__curses=yes +else case e in #( + e) py_cv_module__curses=missing ;; +esac +fi +else case e in #( + e) py_cv_module__curses=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CURSES_STATE=$py_cv_module__curses$as_nl" + if test "x$py_cv_module__curses" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__CURSES_CFLAGS=$CURSES_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CURSES_LDFLAGS=$CURSES_LIBS +$as_nl" + +fi + if test "$py_cv_module__curses" = yes; then + MODULE__CURSES_TRUE= + MODULE__CURSES_FALSE='#' +else + MODULE__CURSES_TRUE='#' + MODULE__CURSES_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__curses" >&5 +printf "%s\n" "$py_cv_module__curses" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _curses_panel" >&5 +printf %s "checking for stdlib extension module _curses_panel... " >&6; } + if test "$py_cv_module__curses_panel" != "n/a" +then : + + if true +then : + if test "$have_curses" = "yes" && test "$have_panel" = "yes" +then : + py_cv_module__curses_panel=yes +else case e in #( + e) py_cv_module__curses_panel=missing ;; +esac +fi +else case e in #( + e) py_cv_module__curses_panel=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_STATE=$py_cv_module__curses_panel$as_nl" + if test "x$py_cv_module__curses_panel" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_CFLAGS=$PANEL_CFLAGS $CURSES_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_LDFLAGS=$PANEL_LIBS $CURSES_LIBS +$as_nl" + +fi + if test "$py_cv_module__curses_panel" = yes; then + MODULE__CURSES_PANEL_TRUE= + MODULE__CURSES_PANEL_FALSE='#' +else + MODULE__CURSES_PANEL_TRUE='#' + MODULE__CURSES_PANEL_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__curses_panel" >&5 +printf "%s\n" "$py_cv_module__curses_panel" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _decimal" >&5 +printf %s "checking for stdlib extension module _decimal... " >&6; } + if test "$py_cv_module__decimal" != "n/a" +then : + + if true +then : + if test "$have_mpdec" = "yes" +then : + py_cv_module__decimal=yes +else case e in #( + e) py_cv_module__decimal=missing ;; +esac +fi +else case e in #( + e) py_cv_module__decimal=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__DECIMAL_STATE=$py_cv_module__decimal$as_nl" + if test "x$py_cv_module__decimal" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__DECIMAL_CFLAGS=$LIBMPDEC_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__DECIMAL_LDFLAGS=$LIBMPDEC_LIBS$as_nl" + +fi + if test "$py_cv_module__decimal" = yes; then + MODULE__DECIMAL_TRUE= + MODULE__DECIMAL_FALSE='#' +else + MODULE__DECIMAL_TRUE='#' + MODULE__DECIMAL_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__decimal" >&5 +printf "%s\n" "$py_cv_module__decimal" >&6; } + + +if test "$have_mpdec" = "no" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: no system libmpdec found; falling back to pure-Python version for the decimal module" >&5 +printf "%s\n" "$as_me: WARNING: no system libmpdec found; falling back to pure-Python version for the decimal module" >&2;} +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _dbm" >&5 +printf %s "checking for stdlib extension module _dbm... " >&6; } + if test "$py_cv_module__dbm" != "n/a" +then : + + if test -n "$with_dbmliborder" +then : + if test "$have_dbm" != "no" +then : + py_cv_module__dbm=yes +else case e in #( + e) py_cv_module__dbm=missing ;; +esac +fi +else case e in #( + e) py_cv_module__dbm=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__DBM_STATE=$py_cv_module__dbm$as_nl" + if test "x$py_cv_module__dbm" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__DBM_CFLAGS=$DBM_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__DBM_LDFLAGS=$DBM_LIBS$as_nl" + +fi + if test "$py_cv_module__dbm" = yes; then + MODULE__DBM_TRUE= + MODULE__DBM_FALSE='#' +else + MODULE__DBM_TRUE='#' + MODULE__DBM_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__dbm" >&5 +printf "%s\n" "$py_cv_module__dbm" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _gdbm" >&5 +printf %s "checking for stdlib extension module _gdbm... " >&6; } + if test "$py_cv_module__gdbm" != "n/a" +then : + + if test "$have_gdbm_dbmliborder" = yes +then : + if test "$have_gdbm" = yes +then : + py_cv_module__gdbm=yes +else case e in #( + e) py_cv_module__gdbm=missing ;; +esac +fi +else case e in #( + e) py_cv_module__gdbm=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__GDBM_STATE=$py_cv_module__gdbm$as_nl" + if test "x$py_cv_module__gdbm" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__GDBM_CFLAGS=$GDBM_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__GDBM_LDFLAGS=$GDBM_LIBS$as_nl" + +fi + if test "$py_cv_module__gdbm" = yes; then + MODULE__GDBM_TRUE= + MODULE__GDBM_FALSE='#' +else + MODULE__GDBM_TRUE='#' + MODULE__GDBM_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__gdbm" >&5 +printf "%s\n" "$py_cv_module__gdbm" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module readline" >&5 +printf %s "checking for stdlib extension module readline... " >&6; } + if test "$py_cv_module_readline" != "n/a" +then : + + if true +then : + if test "$with_readline" != "no" +then : + py_cv_module_readline=yes +else case e in #( + e) py_cv_module_readline=missing ;; +esac +fi +else case e in #( + e) py_cv_module_readline=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_READLINE_STATE=$py_cv_module_readline$as_nl" + if test "x$py_cv_module_readline" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE_READLINE_CFLAGS=$READLINE_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_READLINE_LDFLAGS=$READLINE_LIBS$as_nl" + +fi + if test "$py_cv_module_readline" = yes; then + MODULE_READLINE_TRUE= + MODULE_READLINE_FALSE='#' +else + MODULE_READLINE_TRUE='#' + MODULE_READLINE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_readline" >&5 +printf "%s\n" "$py_cv_module_readline" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sqlite3" >&5 +printf %s "checking for stdlib extension module _sqlite3... " >&6; } + if test "$py_cv_module__sqlite3" != "n/a" +then : + + if test "$have_sqlite3" = "yes" +then : + if test "$have_supported_sqlite3" = "yes" +then : + py_cv_module__sqlite3=yes +else case e in #( + e) py_cv_module__sqlite3=missing ;; +esac +fi +else case e in #( + e) py_cv_module__sqlite3=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SQLITE3_STATE=$py_cv_module__sqlite3$as_nl" + if test "x$py_cv_module__sqlite3" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__SQLITE3_CFLAGS=$LIBSQLITE3_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SQLITE3_LDFLAGS=$LIBSQLITE3_LIBS$as_nl" + +fi + if test "$py_cv_module__sqlite3" = yes; then + MODULE__SQLITE3_TRUE= + MODULE__SQLITE3_FALSE='#' +else + MODULE__SQLITE3_TRUE='#' + MODULE__SQLITE3_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sqlite3" >&5 +printf "%s\n" "$py_cv_module__sqlite3" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _tkinter" >&5 +printf %s "checking for stdlib extension module _tkinter... " >&6; } + if test "$py_cv_module__tkinter" != "n/a" +then : + + if true +then : + if test "$have_tcltk" = "yes" +then : + py_cv_module__tkinter=yes +else case e in #( + e) py_cv_module__tkinter=missing ;; +esac +fi +else case e in #( + e) py_cv_module__tkinter=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TKINTER_STATE=$py_cv_module__tkinter$as_nl" + if test "x$py_cv_module__tkinter" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__TKINTER_CFLAGS=$TCLTK_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__TKINTER_LDFLAGS=$TCLTK_LIBS$as_nl" + +fi + if test "$py_cv_module__tkinter" = yes; then + MODULE__TKINTER_TRUE= + MODULE__TKINTER_FALSE='#' +else + MODULE__TKINTER_TRUE='#' + MODULE__TKINTER_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__tkinter" >&5 +printf "%s\n" "$py_cv_module__tkinter" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _uuid" >&5 +printf %s "checking for stdlib extension module _uuid... " >&6; } + if test "$py_cv_module__uuid" != "n/a" +then : + + if true +then : + if test "$have_uuid" = "yes" +then : + py_cv_module__uuid=yes +else case e in #( + e) py_cv_module__uuid=missing ;; +esac +fi +else case e in #( + e) py_cv_module__uuid=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__UUID_STATE=$py_cv_module__uuid$as_nl" + if test "x$py_cv_module__uuid" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__UUID_CFLAGS=$LIBUUID_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__UUID_LDFLAGS=$LIBUUID_LIBS$as_nl" + +fi + if test "$py_cv_module__uuid" = yes; then + MODULE__UUID_TRUE= + MODULE__UUID_FALSE='#' +else + MODULE__UUID_TRUE='#' + MODULE__UUID_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__uuid" >&5 +printf "%s\n" "$py_cv_module__uuid" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module zlib" >&5 +printf %s "checking for stdlib extension module zlib... " >&6; } + if test "$py_cv_module_zlib" != "n/a" +then : + + if true +then : + if test "$have_zlib" = yes +then : + py_cv_module_zlib=yes +else case e in #( + e) py_cv_module_zlib=missing ;; +esac +fi +else case e in #( + e) py_cv_module_zlib=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_ZLIB_STATE=$py_cv_module_zlib$as_nl" + if test "x$py_cv_module_zlib" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE_ZLIB_CFLAGS=$ZLIB_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_ZLIB_LDFLAGS=$ZLIB_LIBS$as_nl" + +fi + if test "$py_cv_module_zlib" = yes; then + MODULE_ZLIB_TRUE= + MODULE_ZLIB_FALSE='#' +else + MODULE_ZLIB_TRUE='#' + MODULE_ZLIB_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_zlib" >&5 +printf "%s\n" "$py_cv_module_zlib" >&6; } + + + if test "$py_cv_module_binascii" != "n/a" +then : + py_cv_module_binascii=yes +fi + if test "$py_cv_module_binascii" = yes; then + MODULE_BINASCII_TRUE= + MODULE_BINASCII_FALSE='#' +else + MODULE_BINASCII_TRUE='#' + MODULE_BINASCII_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_BINASCII_STATE=$py_cv_module_binascii$as_nl" + if test "x$py_cv_module_binascii" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE_BINASCII_CFLAGS=$BINASCII_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_BINASCII_LDFLAGS=$BINASCII_LIBS$as_nl" + +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _bz2" >&5 +printf %s "checking for stdlib extension module _bz2... " >&6; } + if test "$py_cv_module__bz2" != "n/a" +then : + + if true +then : + if test "$have_bzip2" = yes +then : + py_cv_module__bz2=yes +else case e in #( + e) py_cv_module__bz2=missing ;; +esac +fi +else case e in #( + e) py_cv_module__bz2=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__BZ2_STATE=$py_cv_module__bz2$as_nl" + if test "x$py_cv_module__bz2" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__BZ2_CFLAGS=$BZIP2_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__BZ2_LDFLAGS=$BZIP2_LIBS$as_nl" + +fi + if test "$py_cv_module__bz2" = yes; then + MODULE__BZ2_TRUE= + MODULE__BZ2_FALSE='#' +else + MODULE__BZ2_TRUE='#' + MODULE__BZ2_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__bz2" >&5 +printf "%s\n" "$py_cv_module__bz2" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _lzma" >&5 +printf %s "checking for stdlib extension module _lzma... " >&6; } + if test "$py_cv_module__lzma" != "n/a" +then : + + if true +then : + if test "$have_liblzma" = yes +then : + py_cv_module__lzma=yes +else case e in #( + e) py_cv_module__lzma=missing ;; +esac +fi +else case e in #( + e) py_cv_module__lzma=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__LZMA_STATE=$py_cv_module__lzma$as_nl" + if test "x$py_cv_module__lzma" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__LZMA_CFLAGS=$LIBLZMA_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__LZMA_LDFLAGS=$LIBLZMA_LIBS$as_nl" + +fi + if test "$py_cv_module__lzma" = yes; then + MODULE__LZMA_TRUE= + MODULE__LZMA_FALSE='#' +else + MODULE__LZMA_TRUE='#' + MODULE__LZMA_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__lzma" >&5 +printf "%s\n" "$py_cv_module__lzma" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _zstd" >&5 +printf %s "checking for stdlib extension module _zstd... " >&6; } + if test "$py_cv_module__zstd" != "n/a" +then : + + if true +then : + if test "$have_libzstd" = yes +then : + py_cv_module__zstd=yes +else case e in #( + e) py_cv_module__zstd=missing ;; +esac +fi +else case e in #( + e) py_cv_module__zstd=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__ZSTD_STATE=$py_cv_module__zstd$as_nl" + if test "x$py_cv_module__zstd" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__ZSTD_CFLAGS=$LIBZSTD_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__ZSTD_LDFLAGS=$LIBZSTD_LIBS$as_nl" + +fi + if test "$py_cv_module__zstd" = yes; then + MODULE__ZSTD_TRUE= + MODULE__ZSTD_FALSE='#' +else + MODULE__ZSTD_TRUE='#' + MODULE__ZSTD_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__zstd" >&5 +printf "%s\n" "$py_cv_module__zstd" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ssl" >&5 +printf %s "checking for stdlib extension module _ssl... " >&6; } + if test "$py_cv_module__ssl" != "n/a" +then : + + if true +then : + if test "$ac_cv_working_openssl_ssl" = yes +then : + py_cv_module__ssl=yes +else case e in #( + e) py_cv_module__ssl=missing ;; +esac +fi +else case e in #( + e) py_cv_module__ssl=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SSL_STATE=$py_cv_module__ssl$as_nl" + if test "x$py_cv_module__ssl" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__SSL_CFLAGS=$OPENSSL_INCLUDES$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SSL_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS$as_nl" + +fi + if test "$py_cv_module__ssl" = yes; then + MODULE__SSL_TRUE= + MODULE__SSL_FALSE='#' +else + MODULE__SSL_TRUE='#' + MODULE__SSL_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ssl" >&5 +printf "%s\n" "$py_cv_module__ssl" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hashlib" >&5 +printf %s "checking for stdlib extension module _hashlib... " >&6; } + if test "$py_cv_module__hashlib" != "n/a" +then : + + if true +then : + if test "$ac_cv_working_openssl_hashlib" = yes +then : + py_cv_module__hashlib=yes +else case e in #( + e) py_cv_module__hashlib=missing ;; +esac +fi +else case e in #( + e) py_cv_module__hashlib=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_STATE=$py_cv_module__hashlib$as_nl" + if test "x$py_cv_module__hashlib" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_CFLAGS=$OPENSSL_INCLUDES$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS$as_nl" + +fi + if test "$py_cv_module__hashlib" = yes; then + MODULE__HASHLIB_TRUE= + MODULE__HASHLIB_FALSE='#' +else + MODULE__HASHLIB_TRUE='#' + MODULE__HASHLIB_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__hashlib" >&5 +printf "%s\n" "$py_cv_module__hashlib" >&6; } + + +case $ac_sys_system in #( + # On FreeBSD, _testcapi.get_process_memory_usage() calls kvm_openfiles() + # and so needs libkvm. + FreeBSD*) : + LIBKVM="-lkvm" + ;; #( + *) : + ;; +esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testcapi" >&5 +printf %s "checking for stdlib extension module _testcapi... " >&6; } + if test "$py_cv_module__testcapi" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__testcapi=yes +else case e in #( + e) py_cv_module__testcapi=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testcapi=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTCAPI_STATE=$py_cv_module__testcapi$as_nl" + if test "x$py_cv_module__testcapi" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE__TESTCAPI_LDFLAGS=$LIBATOMIC $LIBKVM$as_nl" + +fi + if test "$py_cv_module__testcapi" = yes; then + MODULE__TESTCAPI_TRUE= + MODULE__TESTCAPI_FALSE='#' +else + MODULE__TESTCAPI_TRUE='#' + MODULE__TESTCAPI_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testcapi" >&5 +printf "%s\n" "$py_cv_module__testcapi" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testclinic" >&5 +printf %s "checking for stdlib extension module _testclinic... " >&6; } + if test "$py_cv_module__testclinic" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__testclinic=yes +else case e in #( + e) py_cv_module__testclinic=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testclinic=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTCLINIC_STATE=$py_cv_module__testclinic$as_nl" + if test "x$py_cv_module__testclinic" = xyes +then : + + + + +fi + if test "$py_cv_module__testclinic" = yes; then + MODULE__TESTCLINIC_TRUE= + MODULE__TESTCLINIC_FALSE='#' +else + MODULE__TESTCLINIC_TRUE='#' + MODULE__TESTCLINIC_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testclinic" >&5 +printf "%s\n" "$py_cv_module__testclinic" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testclinic_limited" >&5 +printf %s "checking for stdlib extension module _testclinic_limited... " >&6; } + if test "$py_cv_module__testclinic_limited" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__testclinic_limited=yes +else case e in #( + e) py_cv_module__testclinic_limited=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testclinic_limited=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTCLINIC_LIMITED_STATE=$py_cv_module__testclinic_limited$as_nl" + if test "x$py_cv_module__testclinic_limited" = xyes +then : + + + + +fi + if test "$py_cv_module__testclinic_limited" = yes; then + MODULE__TESTCLINIC_LIMITED_TRUE= + MODULE__TESTCLINIC_LIMITED_FALSE='#' +else + MODULE__TESTCLINIC_LIMITED_TRUE='#' + MODULE__TESTCLINIC_LIMITED_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testclinic_limited" >&5 +printf "%s\n" "$py_cv_module__testclinic_limited" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testlimitedcapi" >&5 +printf %s "checking for stdlib extension module _testlimitedcapi... " >&6; } + if test "$py_cv_module__testlimitedcapi" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__testlimitedcapi=yes +else case e in #( + e) py_cv_module__testlimitedcapi=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testlimitedcapi=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTLIMITEDCAPI_STATE=$py_cv_module__testlimitedcapi$as_nl" + if test "x$py_cv_module__testlimitedcapi" = xyes +then : + + + + +fi + if test "$py_cv_module__testlimitedcapi" = yes; then + MODULE__TESTLIMITEDCAPI_TRUE= + MODULE__TESTLIMITEDCAPI_FALSE='#' +else + MODULE__TESTLIMITEDCAPI_TRUE='#' + MODULE__TESTLIMITEDCAPI_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testlimitedcapi" >&5 +printf "%s\n" "$py_cv_module__testlimitedcapi" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testinternalcapi" >&5 +printf %s "checking for stdlib extension module _testinternalcapi... " >&6; } + if test "$py_cv_module__testinternalcapi" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__testinternalcapi=yes +else case e in #( + e) py_cv_module__testinternalcapi=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testinternalcapi=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTINTERNALCAPI_STATE=$py_cv_module__testinternalcapi$as_nl" + if test "x$py_cv_module__testinternalcapi" = xyes +then : + + + + +fi + if test "$py_cv_module__testinternalcapi" = yes; then + MODULE__TESTINTERNALCAPI_TRUE= + MODULE__TESTINTERNALCAPI_FALSE='#' +else + MODULE__TESTINTERNALCAPI_TRUE='#' + MODULE__TESTINTERNALCAPI_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testinternalcapi" >&5 +printf "%s\n" "$py_cv_module__testinternalcapi" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testbuffer" >&5 +printf %s "checking for stdlib extension module _testbuffer... " >&6; } + if test "$py_cv_module__testbuffer" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__testbuffer=yes +else case e in #( + e) py_cv_module__testbuffer=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testbuffer=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTBUFFER_STATE=$py_cv_module__testbuffer$as_nl" + if test "x$py_cv_module__testbuffer" = xyes +then : + + + + +fi + if test "$py_cv_module__testbuffer" = yes; then + MODULE__TESTBUFFER_TRUE= + MODULE__TESTBUFFER_FALSE='#' +else + MODULE__TESTBUFFER_TRUE='#' + MODULE__TESTBUFFER_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testbuffer" >&5 +printf "%s\n" "$py_cv_module__testbuffer" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testimportmultiple" >&5 +printf %s "checking for stdlib extension module _testimportmultiple... " >&6; } + if test "$py_cv_module__testimportmultiple" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : + py_cv_module__testimportmultiple=yes +else case e in #( + e) py_cv_module__testimportmultiple=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testimportmultiple=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTIMPORTMULTIPLE_STATE=$py_cv_module__testimportmultiple$as_nl" + if test "x$py_cv_module__testimportmultiple" = xyes +then : + + + + +fi + if test "$py_cv_module__testimportmultiple" = yes; then + MODULE__TESTIMPORTMULTIPLE_TRUE= + MODULE__TESTIMPORTMULTIPLE_FALSE='#' +else + MODULE__TESTIMPORTMULTIPLE_TRUE='#' + MODULE__TESTIMPORTMULTIPLE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testimportmultiple" >&5 +printf "%s\n" "$py_cv_module__testimportmultiple" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testmultiphase" >&5 +printf %s "checking for stdlib extension module _testmultiphase... " >&6; } + if test "$py_cv_module__testmultiphase" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : + py_cv_module__testmultiphase=yes +else case e in #( + e) py_cv_module__testmultiphase=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testmultiphase=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTMULTIPHASE_STATE=$py_cv_module__testmultiphase$as_nl" + if test "x$py_cv_module__testmultiphase" = xyes +then : + + + + +fi + if test "$py_cv_module__testmultiphase" = yes; then + MODULE__TESTMULTIPHASE_TRUE= + MODULE__TESTMULTIPHASE_FALSE='#' +else + MODULE__TESTMULTIPHASE_TRUE='#' + MODULE__TESTMULTIPHASE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testmultiphase" >&5 +printf "%s\n" "$py_cv_module__testmultiphase" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testsinglephase" >&5 +printf %s "checking for stdlib extension module _testsinglephase... " >&6; } + if test "$py_cv_module__testsinglephase" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : + py_cv_module__testsinglephase=yes +else case e in #( + e) py_cv_module__testsinglephase=missing ;; +esac +fi +else case e in #( + e) py_cv_module__testsinglephase=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTSINGLEPHASE_STATE=$py_cv_module__testsinglephase$as_nl" + if test "x$py_cv_module__testsinglephase" = xyes +then : + + + + +fi + if test "$py_cv_module__testsinglephase" = yes; then + MODULE__TESTSINGLEPHASE_TRUE= + MODULE__TESTSINGLEPHASE_FALSE='#' +else + MODULE__TESTSINGLEPHASE_TRUE='#' + MODULE__TESTSINGLEPHASE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testsinglephase" >&5 +printf "%s\n" "$py_cv_module__testsinglephase" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxsubtype" >&5 +printf %s "checking for stdlib extension module xxsubtype... " >&6; } + if test "$py_cv_module_xxsubtype" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module_xxsubtype=yes +else case e in #( + e) py_cv_module_xxsubtype=missing ;; +esac +fi +else case e in #( + e) py_cv_module_xxsubtype=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXSUBTYPE_STATE=$py_cv_module_xxsubtype$as_nl" + if test "x$py_cv_module_xxsubtype" = xyes +then : + + + + +fi + if test "$py_cv_module_xxsubtype" = yes; then + MODULE_XXSUBTYPE_TRUE= + MODULE_XXSUBTYPE_FALSE='#' +else + MODULE_XXSUBTYPE_TRUE='#' + MODULE_XXSUBTYPE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxsubtype" >&5 +printf "%s\n" "$py_cv_module_xxsubtype" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _xxtestfuzz" >&5 +printf %s "checking for stdlib extension module _xxtestfuzz... " >&6; } + if test "$py_cv_module__xxtestfuzz" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__xxtestfuzz=yes +else case e in #( + e) py_cv_module__xxtestfuzz=missing ;; +esac +fi +else case e in #( + e) py_cv_module__xxtestfuzz=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__XXTESTFUZZ_STATE=$py_cv_module__xxtestfuzz$as_nl" + if test "x$py_cv_module__xxtestfuzz" = xyes +then : + + + + +fi + if test "$py_cv_module__xxtestfuzz" = yes; then + MODULE__XXTESTFUZZ_TRUE= + MODULE__XXTESTFUZZ_FALSE='#' +else + MODULE__XXTESTFUZZ_TRUE='#' + MODULE__XXTESTFUZZ_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__xxtestfuzz" >&5 +printf "%s\n" "$py_cv_module__xxtestfuzz" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes_test" >&5 +printf %s "checking for stdlib extension module _ctypes_test... " >&6; } + if test "$py_cv_module__ctypes_test" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if test "$have_libffi" = yes -a "$ac_cv_func_dlopen" = yes +then : + py_cv_module__ctypes_test=yes +else case e in #( + e) py_cv_module__ctypes_test=missing ;; +esac +fi +else case e in #( + e) py_cv_module__ctypes_test=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_STATE=$py_cv_module__ctypes_test$as_nl" + if test "x$py_cv_module__ctypes_test" = xyes +then : + + + as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_LDFLAGS=$LIBM$as_nl" + +fi + if test "$py_cv_module__ctypes_test" = yes; then + MODULE__CTYPES_TEST_TRUE= + MODULE__CTYPES_TEST_FALSE='#' +else + MODULE__CTYPES_TEST_TRUE='#' + MODULE__CTYPES_TEST_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ctypes_test" >&5 +printf "%s\n" "$py_cv_module__ctypes_test" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited" >&5 +printf %s "checking for stdlib extension module xxlimited... " >&6; } + if test "$py_cv_module_xxlimited" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : + py_cv_module_xxlimited=yes +else case e in #( + e) py_cv_module_xxlimited=missing ;; +esac +fi +else case e in #( + e) py_cv_module_xxlimited=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_STATE=$py_cv_module_xxlimited$as_nl" + if test "x$py_cv_module_xxlimited" = xyes +then : + + + + +fi + if test "$py_cv_module_xxlimited" = yes; then + MODULE_XXLIMITED_TRUE= + MODULE_XXLIMITED_FALSE='#' +else + MODULE_XXLIMITED_TRUE='#' + MODULE_XXLIMITED_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited" >&5 +printf "%s\n" "$py_cv_module_xxlimited" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited_35" >&5 +printf %s "checking for stdlib extension module xxlimited_35... " >&6; } + if test "$py_cv_module_xxlimited_35" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : + py_cv_module_xxlimited_35=yes +else case e in #( + e) py_cv_module_xxlimited_35=missing ;; +esac +fi +else case e in #( + e) py_cv_module_xxlimited_35=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_35_STATE=$py_cv_module_xxlimited_35$as_nl" + if test "x$py_cv_module_xxlimited_35" = xyes +then : + + + + +fi + if test "$py_cv_module_xxlimited_35" = yes; then + MODULE_XXLIMITED_35_TRUE= + MODULE_XXLIMITED_35_FALSE='#' +else + MODULE_XXLIMITED_35_TRUE='#' + MODULE_XXLIMITED_35_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited_35" >&5 +printf "%s\n" "$py_cv_module_xxlimited_35" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited_3_13" >&5 +printf %s "checking for stdlib extension module xxlimited_3_13... " >&6; } + if test "$py_cv_module_xxlimited_3_13" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : + py_cv_module_xxlimited_3_13=yes +else case e in #( + e) py_cv_module_xxlimited_3_13=missing ;; +esac +fi +else case e in #( + e) py_cv_module_xxlimited_3_13=disabled ;; +esac +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_3_13_STATE=$py_cv_module_xxlimited_3_13$as_nl" + if test "x$py_cv_module_xxlimited_3_13" = xyes +then : + + + + +fi + if test "$py_cv_module_xxlimited_3_13" = yes; then + MODULE_XXLIMITED_3_13_TRUE= + MODULE_XXLIMITED_3_13_FALSE='#' +else + MODULE_XXLIMITED_3_13_TRUE='#' + MODULE_XXLIMITED_3_13_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited_3_13" >&5 +printf "%s\n" "$py_cv_module_xxlimited_3_13" >&6; } + + +# Determine JIT stencils header files based on target platform +JIT_STENCILS_H="" +JIT_SHIM_O="" +JIT_SHIM_BUILD_O="" +if ${jit_flags:+false} : +then : + +else case e in #( + e) if test "${enable_universalsdk}" && test "$UNIVERSAL_ARCHS" = "universal2"; then + JIT_STENCILS_H="jit_stencils-aarch64-apple-darwin.h jit_stencils-x86_64-apple-darwin.h" + JIT_SHIM_O="jit_shim-universal2-apple-darwin.o" + JIT_SHIM_BUILD_O="jit_shim-aarch64-apple-darwin.o jit_shim-x86_64-apple-darwin.o" + else + case "$host" in + aarch64-apple-darwin*) + JIT_STENCILS_H="jit_stencils-aarch64-apple-darwin.h" + JIT_SHIM_O="jit_shim-aarch64-apple-darwin.o" + ;; + x86_64-apple-darwin*) + JIT_STENCILS_H="jit_stencils-x86_64-apple-darwin.h" + JIT_SHIM_O="jit_shim-x86_64-apple-darwin.o" + ;; + aarch64-pc-windows-msvc) + JIT_STENCILS_H="jit_stencils-aarch64-pc-windows-msvc.h" + JIT_SHIM_O="jit_shim-aarch64-pc-windows-msvc.o" + ;; + i686-pc-windows-msvc) + JIT_STENCILS_H="jit_stencils-i686-pc-windows-msvc.h" + JIT_SHIM_O="jit_shim-i686-pc-windows-msvc.o" + ;; + x86_64-pc-windows-msvc) + JIT_STENCILS_H="jit_stencils-x86_64-pc-windows-msvc.h" + JIT_SHIM_O="jit_shim-x86_64-pc-windows-msvc.o" + ;; + aarch64-*-linux-gnu) + JIT_STENCILS_H="jit_stencils-aarch64-unknown-linux-gnu.h" + JIT_SHIM_O="jit_shim-aarch64-unknown-linux-gnu.o" + ;; + x86_64-*-linux-gnu) + JIT_STENCILS_H="jit_stencils-x86_64-unknown-linux-gnu.h" + JIT_SHIM_O="jit_shim-x86_64-unknown-linux-gnu.o" + ;; + esac + JIT_SHIM_BUILD_O="$JIT_SHIM_O" + fi ;; +esac +fi + + + + + +# substitute multiline block, must come after last PY_STDLIB_MOD() + + +# generate output files +ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh" + +ac_config_files="$ac_config_files Modules/Setup.bootstrap Modules/Setup.stdlib" + +ac_config_files="$ac_config_files Modules/ld_so_aix" + +# Generate files like pyconfig.h +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# 'ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* 'ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # 'set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # 'set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +if test -z "${MODULE__IO_TRUE}" && test -z "${MODULE__IO_FALSE}"; then + as_fn_error $? "conditional \"MODULE__IO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_TIME_TRUE}" && test -z "${MODULE_TIME_FALSE}"; then + as_fn_error $? "conditional \"MODULE_TIME\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_ARRAY_TRUE}" && test -z "${MODULE_ARRAY_FALSE}"; then + as_fn_error $? "conditional \"MODULE_ARRAY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__MATH_INTEGER_TRUE}" && test -z "${MODULE__MATH_INTEGER_FALSE}"; then + as_fn_error $? "conditional \"MODULE__MATH_INTEGER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__ASYNCIO_TRUE}" && test -z "${MODULE__ASYNCIO_FALSE}"; then + as_fn_error $? "conditional \"MODULE__ASYNCIO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__BISECT_TRUE}" && test -z "${MODULE__BISECT_FALSE}"; then + as_fn_error $? "conditional \"MODULE__BISECT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CSV_TRUE}" && test -z "${MODULE__CSV_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CSV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__HEAPQ_TRUE}" && test -z "${MODULE__HEAPQ_FALSE}"; then + as_fn_error $? "conditional \"MODULE__HEAPQ\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__JSON_TRUE}" && test -z "${MODULE__JSON_FALSE}"; then + as_fn_error $? "conditional \"MODULE__JSON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__LSPROF_TRUE}" && test -z "${MODULE__LSPROF_FALSE}"; then + as_fn_error $? "conditional \"MODULE__LSPROF\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__PICKLE_TRUE}" && test -z "${MODULE__PICKLE_FALSE}"; then + as_fn_error $? "conditional \"MODULE__PICKLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__POSIXSUBPROCESS_TRUE}" && test -z "${MODULE__POSIXSUBPROCESS_FALSE}"; then + as_fn_error $? "conditional \"MODULE__POSIXSUBPROCESS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__QUEUE_TRUE}" && test -z "${MODULE__QUEUE_FALSE}"; then + as_fn_error $? "conditional \"MODULE__QUEUE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__RANDOM_TRUE}" && test -z "${MODULE__RANDOM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__RANDOM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__REMOTE_DEBUGGING_TRUE}" && test -z "${MODULE__REMOTE_DEBUGGING_FALSE}"; then + as_fn_error $? "conditional \"MODULE__REMOTE_DEBUGGING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_SELECT_TRUE}" && test -z "${MODULE_SELECT_FALSE}"; then + as_fn_error $? "conditional \"MODULE_SELECT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__STRUCT_TRUE}" && test -z "${MODULE__STRUCT_FALSE}"; then + as_fn_error $? "conditional \"MODULE__STRUCT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TYPES_TRUE}" && test -z "${MODULE__TYPES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TYPES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TYPING_TRUE}" && test -z "${MODULE__TYPING_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TYPING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__INTERPRETERS_TRUE}" && test -z "${MODULE__INTERPRETERS_FALSE}"; then + as_fn_error $? "conditional \"MODULE__INTERPRETERS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__INTERPCHANNELS_TRUE}" && test -z "${MODULE__INTERPCHANNELS_FALSE}"; then + as_fn_error $? "conditional \"MODULE__INTERPCHANNELS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__INTERPQUEUES_TRUE}" && test -z "${MODULE__INTERPQUEUES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__INTERPQUEUES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__ZONEINFO_TRUE}" && test -z "${MODULE__ZONEINFO_FALSE}"; then + as_fn_error $? "conditional \"MODULE__ZONEINFO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__MULTIPROCESSING_TRUE}" && test -z "${MODULE__MULTIPROCESSING_FALSE}"; then + as_fn_error $? "conditional \"MODULE__MULTIPROCESSING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__POSIXSHMEM_TRUE}" && test -z "${MODULE__POSIXSHMEM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__POSIXSHMEM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__STATISTICS_TRUE}" && test -z "${MODULE__STATISTICS_FALSE}"; then + as_fn_error $? "conditional \"MODULE__STATISTICS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_CMATH_TRUE}" && test -z "${MODULE_CMATH_FALSE}"; then + as_fn_error $? "conditional \"MODULE_CMATH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_MATH_TRUE}" && test -z "${MODULE_MATH_FALSE}"; then + as_fn_error $? "conditional \"MODULE_MATH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__DATETIME_TRUE}" && test -z "${MODULE__DATETIME_FALSE}"; then + as_fn_error $? "conditional \"MODULE__DATETIME\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_FCNTL_TRUE}" && test -z "${MODULE_FCNTL_FALSE}"; then + as_fn_error $? "conditional \"MODULE_FCNTL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_MMAP_TRUE}" && test -z "${MODULE_MMAP_FALSE}"; then + as_fn_error $? "conditional \"MODULE_MMAP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SOCKET_TRUE}" && test -z "${MODULE__SOCKET_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SOCKET\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_GRP_TRUE}" && test -z "${MODULE_GRP_FALSE}"; then + as_fn_error $? "conditional \"MODULE_GRP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_PWD_TRUE}" && test -z "${MODULE_PWD_FALSE}"; then + as_fn_error $? "conditional \"MODULE_PWD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_RESOURCE_TRUE}" && test -z "${MODULE_RESOURCE_FALSE}"; then + as_fn_error $? "conditional \"MODULE_RESOURCE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SCPROXY_TRUE}" && test -z "${MODULE__SCPROXY_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SCPROXY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_SYSLOG_TRUE}" && test -z "${MODULE_SYSLOG_FALSE}"; then + as_fn_error $? "conditional \"MODULE_SYSLOG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_TERMIOS_TRUE}" && test -z "${MODULE_TERMIOS_FALSE}"; then + as_fn_error $? "conditional \"MODULE_TERMIOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_PYEXPAT_TRUE}" && test -z "${MODULE_PYEXPAT_FALSE}"; then + as_fn_error $? "conditional \"MODULE_PYEXPAT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__ELEMENTTREE_TRUE}" && test -z "${MODULE__ELEMENTTREE_FALSE}"; then + as_fn_error $? "conditional \"MODULE__ELEMENTTREE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CODECS_CN_TRUE}" && test -z "${MODULE__CODECS_CN_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CODECS_CN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CODECS_HK_TRUE}" && test -z "${MODULE__CODECS_HK_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CODECS_HK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CODECS_ISO2022_TRUE}" && test -z "${MODULE__CODECS_ISO2022_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CODECS_ISO2022\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CODECS_JP_TRUE}" && test -z "${MODULE__CODECS_JP_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CODECS_JP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CODECS_KR_TRUE}" && test -z "${MODULE__CODECS_KR_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CODECS_KR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CODECS_TW_TRUE}" && test -z "${MODULE__CODECS_TW_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CODECS_TW\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__MULTIBYTECODEC_TRUE}" && test -z "${MODULE__MULTIBYTECODEC_FALSE}"; then + as_fn_error $? "conditional \"MODULE__MULTIBYTECODEC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_UNICODEDATA_TRUE}" && test -z "${MODULE_UNICODEDATA_FALSE}"; then + as_fn_error $? "conditional \"MODULE_UNICODEDATA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__MD5_TRUE}" && test -z "${MODULE__MD5_FALSE}"; then + as_fn_error $? "conditional \"MODULE__MD5\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SHA1_TRUE}" && test -z "${MODULE__SHA1_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SHA1\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SHA2_TRUE}" && test -z "${MODULE__SHA2_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SHA2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SHA3_TRUE}" && test -z "${MODULE__SHA3_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SHA3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__BLAKE2_TRUE}" && test -z "${MODULE__BLAKE2_FALSE}"; then + as_fn_error $? "conditional \"MODULE__BLAKE2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__HMAC_TRUE}" && test -z "${MODULE__HMAC_FALSE}"; then + as_fn_error $? "conditional \"MODULE__HMAC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CTYPES_TRUE}" && test -z "${MODULE__CTYPES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CTYPES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CURSES_TRUE}" && test -z "${MODULE__CURSES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CURSES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CURSES_PANEL_TRUE}" && test -z "${MODULE__CURSES_PANEL_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CURSES_PANEL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__DECIMAL_TRUE}" && test -z "${MODULE__DECIMAL_FALSE}"; then + as_fn_error $? "conditional \"MODULE__DECIMAL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__DBM_TRUE}" && test -z "${MODULE__DBM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__DBM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__GDBM_TRUE}" && test -z "${MODULE__GDBM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__GDBM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_READLINE_TRUE}" && test -z "${MODULE_READLINE_FALSE}"; then + as_fn_error $? "conditional \"MODULE_READLINE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SQLITE3_TRUE}" && test -z "${MODULE__SQLITE3_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SQLITE3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TKINTER_TRUE}" && test -z "${MODULE__TKINTER_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TKINTER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__UUID_TRUE}" && test -z "${MODULE__UUID_FALSE}"; then + as_fn_error $? "conditional \"MODULE__UUID\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_ZLIB_TRUE}" && test -z "${MODULE_ZLIB_FALSE}"; then + as_fn_error $? "conditional \"MODULE_ZLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_BINASCII_TRUE}" && test -z "${MODULE_BINASCII_FALSE}"; then + as_fn_error $? "conditional \"MODULE_BINASCII\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__BZ2_TRUE}" && test -z "${MODULE__BZ2_FALSE}"; then + as_fn_error $? "conditional \"MODULE__BZ2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__LZMA_TRUE}" && test -z "${MODULE__LZMA_FALSE}"; then + as_fn_error $? "conditional \"MODULE__LZMA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__ZSTD_TRUE}" && test -z "${MODULE__ZSTD_FALSE}"; then + as_fn_error $? "conditional \"MODULE__ZSTD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SSL_TRUE}" && test -z "${MODULE__SSL_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SSL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__HASHLIB_TRUE}" && test -z "${MODULE__HASHLIB_FALSE}"; then + as_fn_error $? "conditional \"MODULE__HASHLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTCAPI_TRUE}" && test -z "${MODULE__TESTCAPI_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTCAPI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTCLINIC_TRUE}" && test -z "${MODULE__TESTCLINIC_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTCLINIC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTCLINIC_LIMITED_TRUE}" && test -z "${MODULE__TESTCLINIC_LIMITED_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTCLINIC_LIMITED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTLIMITEDCAPI_TRUE}" && test -z "${MODULE__TESTLIMITEDCAPI_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTLIMITEDCAPI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTINTERNALCAPI_TRUE}" && test -z "${MODULE__TESTINTERNALCAPI_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTINTERNALCAPI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTBUFFER_TRUE}" && test -z "${MODULE__TESTBUFFER_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTBUFFER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTIMPORTMULTIPLE_TRUE}" && test -z "${MODULE__TESTIMPORTMULTIPLE_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTIMPORTMULTIPLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTMULTIPHASE_TRUE}" && test -z "${MODULE__TESTMULTIPHASE_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTMULTIPHASE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__TESTSINGLEPHASE_TRUE}" && test -z "${MODULE__TESTSINGLEPHASE_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTSINGLEPHASE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_XXSUBTYPE_TRUE}" && test -z "${MODULE_XXSUBTYPE_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXSUBTYPE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__XXTESTFUZZ_TRUE}" && test -z "${MODULE__XXTESTFUZZ_FALSE}"; then + as_fn_error $? "conditional \"MODULE__XXTESTFUZZ\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CTYPES_TEST_TRUE}" && test -z "${MODULE__CTYPES_TEST_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CTYPES_TEST\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_XXLIMITED_TRUE}" && test -z "${MODULE_XXLIMITED_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXLIMITED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_XXLIMITED_35_TRUE}" && test -z "${MODULE_XXLIMITED_35_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXLIMITED_35\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_XXLIMITED_3_13_TRUE}" && test -z "${MODULE_XXLIMITED_3_13_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXLIMITED_3_13\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else case e in #( + e) case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi +if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as 'sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else case e in #( + e) as_fn_append () + { + eval $1=\$$1\$2 + } ;; +esac +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else case e in #( + e) as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } ;; +esac +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated + +# Sed expression to map a string onto a valid variable name. +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by python $as_me 3.16, which was +generated by GNU Autoconf 2.72. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +'$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to <https://github.com/python/cpython/issues/>." + +_ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config='$ac_cs_config_escaped' +ac_cs_version="\\ +python config.status 3.16 +configured by $0, generated by GNU Autoconf 2.72, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2023 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + printf "%s\n" "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + printf "%s\n" "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: '$1' +Try '$0 --help' for more information.";; + --help | --hel | -h ) + printf "%s\n" "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: '$1' +Try '$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + printf "%s\n" "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "pyconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS pyconfig.h" ;; + "Mac/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/Makefile" ;; + "Mac/PythonLauncher/Makefile") CONFIG_FILES="$CONFIG_FILES Mac/PythonLauncher/Makefile" ;; + "Mac/Resources/framework/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/framework/Info.plist" ;; + "Mac/Resources/app/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/app/Info.plist" ;; + "Platforms/Apple/iOS/Resources/Info.plist") CONFIG_FILES="$CONFIG_FILES Platforms/Apple/iOS/Resources/Info.plist" ;; + "Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;; + "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; + "Misc/python-embed.pc") CONFIG_FILES="$CONFIG_FILES Misc/python-embed.pc" ;; + "Misc/python-config.sh") CONFIG_FILES="$CONFIG_FILES Misc/python-config.sh" ;; + "Modules/Setup.bootstrap") CONFIG_FILES="$CONFIG_FILES Modules/Setup.bootstrap" ;; + "Modules/Setup.stdlib") CONFIG_FILES="$CONFIG_FILES Modules/Setup.stdlib" ;; + "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;; + + *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to '$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with './config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with './config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script 'defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain ':'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is 'configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`printf "%s\n" "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when '$srcdir' = '.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + + esac + + + case $ac_file$ac_mode in + "Modules/ld_so_aix":F) chmod +x Modules/ld_so_aix ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating Modules/Setup.local" >&5 +printf "%s\n" "$as_me: creating Modules/Setup.local" >&6;} +if test ! -f Modules/Setup.local +then + echo "# Edit this file for local setup changes" >Modules/Setup.local +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating Makefile" >&5 +printf "%s\n" "$as_me: creating Makefile" >&6;} +$SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ + -s Modules \ + Modules/Setup.local Modules/Setup.stdlib Modules/Setup.bootstrap $srcdir/Modules/Setup +if test $? -ne 0; then + as_fn_error $? "makesetup failed" "$LINENO" 5 +fi + +mv config.c Modules + +if test -z "$PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&5 +printf "%s\n" "$as_me: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&2;} +fi + +if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: + +If you want a release build with all stable optimizations active (PGO, etc), +please run ./configure --enable-optimizations +" >&5 +printf "%s\n" "$as_me: + +If you want a release build with all stable optimizations active (PGO, etc), +please run ./configure --enable-optimizations +" >&6;} +fi + +if test "x$PY_SUPPORT_TIER" = x0 +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: + +Platform \"$host\" with compiler \"$ac_cv_cc_name\" is not supported by the +CPython core team, see https://peps.python.org/pep-0011/ for more information. +" >&5 +printf "%s\n" "$as_me: WARNING: + +Platform \"$host\" with compiler \"$ac_cv_cc_name\" is not supported by the +CPython core team, see https://peps.python.org/pep-0011/ for more information. +" >&2;} +fi + +if test "$ac_cv_header_stdatomic_h" != "yes"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Your compiler or platform does have a working C11 stdatomic.h. A future version of Python may require stdatomic.h." >&5 +printf "%s\n" "$as_me: Your compiler or platform does have a working C11 stdatomic.h. A future version of Python may require stdatomic.h." >&6;} +fi + diff --git a/stdlib/kvlang/reference/python/cpython/configure.ac b/stdlib/kvlang/reference/python/cpython/configure.ac new file mode 100644 index 00000000..8345c973 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/configure.ac @@ -0,0 +1,8904 @@ +dnl ************************************************************ +dnl * Please run autoreconf -ivf -Werror to test your changes! * +dnl ************************************************************ +dnl +dnl Python's configure script requires autoconf 2.72, autoconf-archive, +dnl aclocal 1.16, and pkg-config. +dnl +dnl It is recommended to use the Tools/build/regen-configure.sh shell script +dnl to regenerate the configure script. +dnl + +# Set VERSION so we only need to edit in one place (i.e., here) +m4_define([PYTHON_VERSION], [3.16]) + +AC_PREREQ([2.72]) + +AC_INIT([python],[PYTHON_VERSION],[https://github.com/python/cpython/issues/]) + +m4_ifdef( + [AX_C_FLOAT_WORDS_BIGENDIAN], + [], + [AC_MSG_ERROR([Please install autoconf-archive package and re-run autoreconf])] +)dnl +m4_ifdef( + [PKG_PROG_PKG_CONFIG], + [], + [AC_MSG_ERROR([Please install pkgconf's m4 macro package and re-run autoreconf])] +)dnl + +dnl Helpers for saving and restoring environment variables: +dnl - _SAVE_VAR([VAR]) Helper for SAVE_ENV; stores VAR as save_VAR +dnl - _RESTORE_VAR([VAR]) Helper for RESTORE_ENV; restores VAR from save_VAR +dnl - SAVE_ENV Saves CFLAGS, LDFLAGS, LIBS, and CPPFLAGS +dnl - RESTORE_ENV Restores CFLAGS, LDFLAGS, LIBS, and CPPFLAGS +dnl - WITH_SAVE_ENV([SCRIPT]) Runs SCRIPT wrapped with SAVE_ENV/RESTORE_ENV +AC_DEFUN([_SAVE_VAR], [AS_VAR_COPY([save_][$1], [$1])])dnl +AC_DEFUN([_RESTORE_VAR], [AS_VAR_COPY([$1], [save_][$1])])dnl +AC_DEFUN([SAVE_ENV], +[_SAVE_VAR([CFLAGS])] +[_SAVE_VAR([CPPFLAGS])] +[_SAVE_VAR([LDFLAGS])] +[_SAVE_VAR([LIBS])] +)dnl +AC_DEFUN([RESTORE_ENV], +[_RESTORE_VAR([CFLAGS])] +[_RESTORE_VAR([CPPFLAGS])] +[_RESTORE_VAR([LDFLAGS])] +[_RESTORE_VAR([LIBS])] +)dnl +AC_DEFUN([WITH_SAVE_ENV], +[SAVE_ENV] +[$1] +[RESTORE_ENV] +)dnl + +dnl PY_CHECK_FUNC(FUNCTION, [INCLUDES], [AC_DEFINE-VAR]) +AC_DEFUN([PY_CHECK_FUNC], +[ AS_VAR_PUSHDEF([py_var], [ac_cv_func_$1]) + AS_VAR_PUSHDEF([py_define], m4_ifblank([$3], [[HAVE_]m4_toupper($1)], [$3])) + AC_CACHE_CHECK( + [for $1], + [py_var], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2], [void *x=$1])], + [AS_VAR_SET([py_var], [yes])], + [AS_VAR_SET([py_var], [no])])] + ) + AS_VAR_IF( + [py_var], + [yes], + [AC_DEFINE([py_define], [1], [Define if you have the '$1' function.])]) + AS_VAR_POPDEF([py_var]) + AS_VAR_POPDEF([py_define]) +]) + +dnl PY_CHECK_LIB(LIBRARY, FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES]) +dnl Like AC_CHECK_LIB() but does not modify LIBS +AC_DEFUN([PY_CHECK_LIB], +[AS_VAR_COPY([py_check_lib_save_LIBS], [LIBS])] +[AC_CHECK_LIB([$1], [$2], [$3], [$4], [$5])] +[AS_VAR_COPY([LIBS], [py_check_lib_save_LIBS])] +) + +dnl PY_CHECK_EMSCRIPTEN_PORT(PKG_VAR, [EMPORT_ARGS]) +dnl Use Emscripten port unless user passes ${PKG_VAR}_CFLAGS +dnl or ${PKG_VAR}_LIBS to configure. +AC_DEFUN([PY_CHECK_EMSCRIPTEN_PORT], [ + AS_VAR_PUSHDEF([py_cflags], [$1_CFLAGS]) + AS_VAR_PUSHDEF([py_libs], [$1_LIBS]) + AS_IF([test "$ac_sys_system" = "Emscripten" -a -z "$py_cflags" -a -z "$py_libs"], [ + py_cflags="$2" + py_libs="$2" + ]) + AS_VAR_POPDEF([py_cflags]) + AS_VAR_POPDEF([py_libs]) +]) + +AC_SUBST([BASECPPFLAGS]) +if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then + # If we're building out-of-tree, we need to make sure the following + # resources get picked up before their $srcdir counterparts. + # Objects/ -> slots_generated.c + # Include/ -> Python.h + # (A side effect of this is that these resources will automatically be + # regenerated when building out-of-tree, regardless of whether or not + # the $srcdir counterpart is up-to-date. This is an acceptable trade + # off.) + BASECPPFLAGS="-IObjects -IInclude -IPython" +else + BASECPPFLAGS="" +fi + +AC_SUBST([GITVERSION]) +AC_SUBST([GITTAG]) +AC_SUBST([GITBRANCH]) + +if test -e $srcdir/.git +then +AC_CHECK_PROG([HAS_GIT], [git], [found], [not-found]) +else +HAS_GIT=no-repository +fi +if test $HAS_GIT = found +then + GITVERSION="git --git-dir \$(srcdir)/.git rev-parse --short HEAD" + GITTAG="git --git-dir \$(srcdir)/.git describe --all --always --dirty" + GITBRANCH="git --git-dir \$(srcdir)/.git name-rev --name-only HEAD" +else + GITVERSION="" + GITTAG="" + GITBRANCH="" +fi + +AC_CONFIG_SRCDIR([Include/object.h]) +AC_CONFIG_HEADERS([pyconfig.h]) + +AC_CANONICAL_HOST +AC_SUBST([build]) +AC_SUBST([host]) + +AS_VAR_IF([cross_compiling], [maybe], + [AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH])] +) + +# pybuilddir.txt will be created by --generate-posix-vars in the Makefile +rm -f pybuilddir.txt + +AC_ARG_WITH([build-python], + [AS_HELP_STRING([--with-build-python=python]PYTHON_VERSION, + [path to build python binary for cross compiling (default: _bootstrap_python or python]PYTHON_VERSION[)])], + [ + AC_MSG_CHECKING([for --with-build-python]) + + AS_VAR_IF([with_build_python], [yes], [with_build_python=python$PACKAGE_VERSION]) + AS_VAR_IF([with_build_python], [no], [AC_MSG_ERROR([invalid --with-build-python option: expected path or "yes", not "no"])]) + + if ! $(command -v "$with_build_python" >/dev/null 2>&1); then + AC_MSG_ERROR([invalid or missing build python binary "$with_build_python"]) + fi + build_python_ver=$($with_build_python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") + if test "$build_python_ver" != "$PACKAGE_VERSION"; then + AC_MSG_ERROR(["$with_build_python" has incompatible version $build_python_ver (expected: $PACKAGE_VERSION)]) + fi + dnl Build Python interpreter is used for regeneration and freezing. + ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python + PYTHON_FOR_FREEZE="$with_build_python" + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python + AC_MSG_RESULT([$with_build_python]) + ], [ + AS_VAR_IF([cross_compiling], [yes], + [AC_MSG_ERROR([Cross compiling requires --with-build-python])] + ) + PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' + PYTHON_FOR_FREEZE="./_bootstrap_python" + ] +) +AC_SUBST([PYTHON_FOR_BUILD]) + +AC_MSG_CHECKING([for Python interpreter freezing]) +AC_MSG_RESULT([$PYTHON_FOR_FREEZE]) +AC_SUBST([PYTHON_FOR_FREEZE]) + +AS_VAR_IF([cross_compiling], [yes], + [ + dnl external build Python, freezing depends on Programs/_freeze_module.py + FREEZE_MODULE_BOOTSTRAP='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_BOOTSTRAP_DEPS='$(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE='$(FREEZE_MODULE_BOOTSTRAP)' + FREEZE_MODULE_DEPS='$(FREEZE_MODULE_BOOTSTRAP_DEPS)' + PYTHON_FOR_BUILD_DEPS='' + ], + [ + dnl internal build tools also depend on Programs/_freeze_module and _bootstrap_python. + FREEZE_MODULE_BOOTSTRAP='./Programs/_freeze_module' + FREEZE_MODULE_BOOTSTRAP_DEPS="Programs/_freeze_module" + FREEZE_MODULE='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_DEPS="_bootstrap_python \$(srcdir)/Programs/_freeze_module.py" + PYTHON_FOR_BUILD_DEPS='$(BUILDPYTHON)' + ] +) +AC_SUBST([FREEZE_MODULE_BOOTSTRAP]) +AC_SUBST([FREEZE_MODULE_BOOTSTRAP_DEPS]) +AC_SUBST([FREEZE_MODULE]) +AC_SUBST([FREEZE_MODULE_DEPS]) +AC_SUBST([PYTHON_FOR_BUILD_DEPS]) + +AC_CHECK_PROGS([PYTHON_FOR_REGEN], + [python$PACKAGE_VERSION python3.16 python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 python3 python], + [python3]) +AC_SUBST([PYTHON_FOR_REGEN]) + +AC_MSG_CHECKING([Python for regen version]) +if command -v "$PYTHON_FOR_REGEN" >/dev/null 2>&1; then + AC_MSG_RESULT([$($PYTHON_FOR_REGEN -V 2>/dev/null)]) +else + AC_MSG_RESULT([missing]) +fi + +dnl Ensure that if prefix is specified, it does not end in a slash. If +dnl it does, we get path names containing '//' which is both ugly and +dnl can cause trouble. + +dnl Last slash shouldn't be stripped if prefix=/ +if test "$prefix" != "/"; then + prefix=`echo "$prefix" | sed -e 's/\/$//g'` +fi + +dnl This is for stuff that absolutely must end up in pyconfig.h. +dnl Please use pyport.h instead, if possible. +AH_TOP([ +#ifndef Py_PYCONFIG_H +#define Py_PYCONFIG_H +]) +AH_BOTTOM([ +/* Define the macros needed if on a UnixWare 7.x system. */ +#if defined(__USLC__) && defined(__SCO_VERSION__) +#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ +#endif + +#endif /*Py_PYCONFIG_H*/ +]) + +# We don't use PACKAGE_ variables, and they cause conflicts +# with other autoconf-based packages that include Python.h +grep -v 'define PACKAGE_' <confdefs.h >confdefs.h.new +rm confdefs.h +mv confdefs.h.new confdefs.h + +AC_SUBST([VERSION]) +VERSION=PYTHON_VERSION + +# Version number of Python's own shared library file. +AC_SUBST([SOVERSION]) +SOVERSION=1.0 + +# The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables +# certain features on NetBSD, so we need _NETBSD_SOURCE to re-enable +# them. +AC_DEFINE([_NETBSD_SOURCE], [1], + [Define on NetBSD to activate all library features]) + +# The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables +# certain features on FreeBSD, so we need __BSD_VISIBLE to re-enable +# them. +AC_DEFINE([__BSD_VISIBLE], [1], + [Define on FreeBSD to activate all library features]) + +# The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables +# certain features on Mac OS X, so we need _DARWIN_C_SOURCE to re-enable +# them. +AC_DEFINE([_DARWIN_C_SOURCE], [1], + [Define on Darwin to activate all library features]) + + +define_xopen_source=yes + +# Arguments passed to configure. +AC_SUBST([CONFIG_ARGS]) +CONFIG_ARGS="$ac_configure_args" + +dnl Allow users to disable pkg-config or require pkg-config +AC_ARG_WITH([pkg-config], + [AS_HELP_STRING([[--with-pkg-config=[yes|no|check]]], + [use pkg-config to detect build options (default is check)])], + [], + [with_pkg_config=check] +) +AS_CASE([$with_pkg_config], + [yes|check], [ + if test -z "$PKG_CONFIG"; then + dnl invalidate stale config.cache values + AS_UNSET([PKG_CONFIG]) + AS_UNSET([ac_cv_path_ac_pt_PKG_CONFIG]) + AS_UNSET([ac_cv_prog_ac_ct_PKG_CONFIG]) + fi + PKG_PROG_PKG_CONFIG + ], + [no], [ + PKG_CONFIG='' + dnl force AX_CHECK_OPENSSL to ignore pkg-config + ac_cv_path_ac_pt_PKG_CONFIG='' + ac_cv_prog_ac_ct_PKG_CONFIG='' + ], + [AC_MSG_ERROR([invalid argument --with-pkg-config=$with_pkg_config])] +) +if test "$with_pkg_config" = yes -a -z "$PKG_CONFIG"; then + AC_MSG_ERROR([pkg-config is required])] +fi + +dnl Allow distributors to provide custom missing stdlib module error messages +AC_ARG_WITH([missing-stdlib-config], + [AS_HELP_STRING([--with-missing-stdlib-config=FILE], + [File with custom module error messages for missing stdlib modules])], + [MISSING_STDLIB_CONFIG="$withval"], + [MISSING_STDLIB_CONFIG=""] +) +AC_SUBST([MISSING_STDLIB_CONFIG]) + +# Set name for machine-dependent library files +AC_ARG_VAR([MACHDEP], [name for machine-dependent library files]) +AC_MSG_CHECKING([MACHDEP]) +if test -z "$MACHDEP" +then + # avoid using uname for cross builds + if test "$cross_compiling" = yes; then + # ac_sys_system and ac_sys_release are used for setting + # a lot of different things including 'define_xopen_source' + # in the case statement below. + case "$host" in + *-*-linux-android*) + ac_sys_system=Linux-android + ;; + *-*-linux*) + ac_sys_system=Linux + ;; + *-*-cygwin*) + ac_sys_system=CYGWIN + ;; + *-apple-ios*) + ac_sys_system=iOS + ;; + *-*-darwin*) + ac_sys_system=Darwin + ;; + *-gnu) + ac_sys_system=GNU + ;; + *-*-vxworks*) + ac_sys_system=VxWorks + ;; + *-*-emscripten) + ac_sys_system=Emscripten + ;; + *-*-wasi*) + ac_sys_system=WASI + ;; + *) + # for now, limit cross builds to known configurations + MACHDEP="unknown" + AC_MSG_ERROR([cross build not supported for $host]) + esac + ac_sys_release= + else + ac_sys_system=`uname -s` + if test "$ac_sys_system" = "AIX" \ + -o "$ac_sys_system" = "UnixWare" -o "$ac_sys_system" = "OpenUNIX"; then + ac_sys_release=`uname -v` + else + ac_sys_release=`uname -r` + fi + fi + ac_md_system=`echo $ac_sys_system | + tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'` + ac_md_release=`echo $ac_sys_release | + tr -d '[/ ]' | sed 's/^[[A-Z]]\.//' | sed 's/\..*//'` + MACHDEP="$ac_md_system$ac_md_release" + + case $MACHDEP in + aix*) MACHDEP="aix";; + freebsd*) MACHDEP="freebsd";; + linux-android*) MACHDEP="android";; + linux*) MACHDEP="linux";; + cygwin*) MACHDEP="cygwin";; + darwin*) MACHDEP="darwin";; + '') MACHDEP="unknown";; + esac + + if test "$ac_sys_system" = "SunOS"; then + # For Solaris, there isn't an OS version specific macro defined + # in most compilers, so we define one here. + SUNOS_VERSION=`echo $ac_sys_release | sed -e 's!\.\([0-9]\)$!.0\1!g' | tr -d '.'` + AC_DEFINE_UNQUOTED([Py_SUNOS_VERSION], [$SUNOS_VERSION], + [The version of SunOS/Solaris as reported by `uname -r' without the dot.]) + fi +fi +AC_MSG_RESULT(["$MACHDEP"]) + +dnl For cross compilation, we distinguish between "prefix" (where we install the +dnl files) and "host_prefix" (where we expect to find the files at runtime) + +if test -z "$host_prefix"; then + AS_CASE([$ac_sys_system], + [Emscripten], [host_prefix=/], + [host_prefix='${prefix}'] + ) +fi +AC_SUBST([host_prefix]) + +if test -z "$host_exec_prefix"; then + AS_CASE([$ac_sys_system], + [Emscripten], [host_exec_prefix=$host_prefix], + [host_exec_prefix='${exec_prefix}'] + ) +fi +AC_SUBST([host_exec_prefix]) + +# On cross-compile builds, configure will look for a host-specific compiler by +# prepending the user-provided host triple to the required binary name. +# +# On iOS, this results in binaries like "arm64-apple-ios13.0-simulator-gcc", +# which isn't a binary that exists, and isn't very convenient, as it contains the +# iOS version. As the default cross-compiler name won't exist, configure falls +# back to gcc, which *definitely* won't work. We're providing wrapper scripts for +# these tools; the binary names of these scripts are better defaults than "gcc". +# This only requires that the user put the platform scripts folder (e.g., +# "iOS/Resources/bin") in their path, rather than defining platform-specific +# names/paths for AR, CC, CPP, and CXX explicitly; and if the user forgets to +# either put the platform scripts folder in the path, or specify CC etc, +# configure will fail. +if test -z "$AR"; then + case "$host" in + aarch64-apple-ios*-simulator) AR=arm64-apple-ios-simulator-ar ;; + aarch64-apple-ios*) AR=arm64-apple-ios-ar ;; + x86_64-apple-ios*-simulator) AR=x86_64-apple-ios-simulator-ar ;; + *) + esac +fi +if test -z "$CC"; then + case "$host" in + aarch64-apple-ios*-simulator) CC=arm64-apple-ios-simulator-clang ;; + aarch64-apple-ios*) CC=arm64-apple-ios-clang ;; + x86_64-apple-ios*-simulator) CC=x86_64-apple-ios-simulator-clang ;; + *) + esac +fi +if test -z "$CPP"; then + case "$host" in + aarch64-apple-ios*-simulator) CPP=arm64-apple-ios-simulator-cpp ;; + aarch64-apple-ios*) CPP=arm64-apple-ios-cpp ;; + x86_64-apple-ios*-simulator) CPP=x86_64-apple-ios-simulator-cpp ;; + *) + esac +fi +if test -z "$CXX"; then + case "$host" in + aarch64-apple-ios*-simulator) CXX=arm64-apple-ios-simulator-clang++ ;; + aarch64-apple-ios*) CXX=arm64-apple-ios-clang++ ;; + x86_64-apple-ios*-simulator) CXX=x86_64-apple-ios-simulator-clang++ ;; + *) + esac +fi + +AC_MSG_CHECKING([for --enable-universalsdk]) +AC_ARG_ENABLE([universalsdk], + AS_HELP_STRING([--enable-universalsdk@<:@=SDKDIR@:>@], + [create a universal binary build. + SDKDIR specifies which macOS SDK should be used to perform the build, + see Mac/README.rst. (default is no)]), +[ + case $enableval in + yes) + # Locate the best usable SDK, see Mac/README for more + # information + enableval="`/usr/bin/xcodebuild -version -sdk macosx Path 2>/dev/null`" + if ! ( echo $enableval | grep -E '\.sdk' 1>/dev/null ) + then + enableval=/Developer/SDKs/MacOSX10.4u.sdk + if test ! -d "${enableval}" + then + enableval=/ + fi + fi + ;; + esac + case $enableval in + no) + UNIVERSALSDK= + enable_universalsdk= + ;; + *) + UNIVERSALSDK=$enableval + if test ! -d "${UNIVERSALSDK}" + then + AC_MSG_ERROR([--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}]) + fi + ;; + esac + +],[ + UNIVERSALSDK= + enable_universalsdk= +]) +if test -n "${UNIVERSALSDK}" +then + AC_MSG_RESULT([${UNIVERSALSDK}]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST([UNIVERSALSDK]) + +AC_SUBST([ARCH_RUN_32BIT]) +ARCH_RUN_32BIT="" + +# For backward compatibility reasons we prefer to select '32-bit' if available, +# otherwise use 'intel' +UNIVERSAL_ARCHS="32-bit" +if test "`uname -s`" = "Darwin" +then + if test -n "${UNIVERSALSDK}" + then + if test -z "`/usr/bin/file -L "${UNIVERSALSDK}/usr/lib/libSystem.dylib" | grep ppc`" + then + UNIVERSAL_ARCHS="intel" + fi + fi +fi + +AC_SUBST([LIPO_32BIT_FLAGS]) +AC_SUBST([LIPO_INTEL64_FLAGS]) +AC_MSG_CHECKING([for --with-universal-archs]) +AC_ARG_WITH([universal-archs], + AS_HELP_STRING([--with-universal-archs=ARCH], + [specify the kind of macOS universal binary that should be created. + This option is only valid when --enable-universalsdk is set; options are: + ("universal2", "intel-64", "intel-32", "intel", "32-bit", + "64-bit", "3-way", or "all") + see Mac/README.rst]), +[ + UNIVERSAL_ARCHS="$withval" +], +[]) +if test -n "${UNIVERSALSDK}" +then + AC_MSG_RESULT([${UNIVERSAL_ARCHS}]) +else + AC_MSG_RESULT([no]) +fi + +AC_ARG_WITH([framework-name], + AS_HELP_STRING([--with-framework-name=FRAMEWORK], + [specify the name for the python framework on macOS + only valid when --enable-framework is set. see Mac/README.rst + (default is 'Python')]), +[ + PYTHONFRAMEWORK=${withval} + PYTHONFRAMEWORKDIR=${withval}.framework + PYTHONFRAMEWORKIDENTIFIER=org.python.`echo $withval | tr '[A-Z]' '[a-z]'` + ],[ + PYTHONFRAMEWORK=Python + PYTHONFRAMEWORKDIR=Python.framework + PYTHONFRAMEWORKIDENTIFIER=org.python.python +]) +dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output +AC_ARG_ENABLE([framework], + AS_HELP_STRING([--enable-framework@<:@=INSTALLDIR@:>@], + [create a Python.framework rather than a traditional Unix install. + optional INSTALLDIR specifies the installation path. see Mac/README.rst + (default is no)]), +[ + case $enableval in + yes) + case $ac_sys_system in + Darwin) enableval=/Library/Frameworks ;; + iOS) enableval=Platforms/Apple/iOS/Frameworks/\$\(MULTIARCH\) ;; + *) AC_MSG_ERROR([Unknown platform for framework build]) + esac + esac + + case $enableval in + no) + case $ac_sys_system in + iOS) AC_MSG_ERROR([iOS builds must use --enable-framework]) ;; + *) + PYTHONFRAMEWORK= + PYTHONFRAMEWORKDIR=no-framework + PYTHONFRAMEWORKPREFIX= + PYTHONFRAMEWORKINSTALLDIR= + PYTHONFRAMEWORKINSTALLNAMEPREFIX= + RESSRCDIR= + FRAMEWORKINSTALLFIRST= + FRAMEWORKINSTALLLAST= + FRAMEWORKALTINSTALLFIRST= + FRAMEWORKALTINSTALLLAST= + FRAMEWORKPYTHONW= + INSTALLTARGETS="commoninstall bininstall maninstall" + + if test "x${prefix}" = "xNONE"; then + FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi + enable_framework= + esac + ;; + *) + PYTHONFRAMEWORKPREFIX="${enableval}" + PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR + + case $ac_sys_system in #( + Darwin) : + FRAMEWORKINSTALLFIRST="frameworkinstallversionedstructure" + FRAMEWORKALTINSTALLFIRST="frameworkinstallversionedstructure " + FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" + FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" + FRAMEWORKPYTHONW="frameworkpythonw" + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + INSTALLTARGETS="commoninstall bininstall maninstall" + + if test "x${prefix}" = "xNONE" ; then + FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" + + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi + + case "${enableval}" in + /System*) + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + if test "${prefix}" = "NONE" ; then + # See below + FRAMEWORKUNIXTOOLSPREFIX="/usr" + fi + ;; + + /Library*) + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + ;; + + */Library/Frameworks) + MDIR="`dirname "${enableval}"`" + MDIR="`dirname "${MDIR}"`" + FRAMEWORKINSTALLAPPSPREFIX="${MDIR}/Applications" + + if test "${prefix}" = "NONE"; then + # User hasn't specified the + # --prefix option, but wants to install + # the framework in a non-default location, + # ensure that the compatibility links get + # installed relative to that prefix as well + # instead of in /usr/local. + FRAMEWORKUNIXTOOLSPREFIX="${MDIR}" + fi + ;; + + *) + FRAMEWORKINSTALLAPPSPREFIX="/Applications" + ;; + esac + + prefix=$PYTHONFRAMEWORKINSTALLDIR/Versions/$VERSION + PYTHONFRAMEWORKINSTALLNAMEPREFIX=${prefix} + RESSRCDIR=Mac/Resources/framework + + # Add files for Mac specific code to the list of output + # files: + AC_CONFIG_FILES([Mac/Makefile]) + AC_CONFIG_FILES([Mac/PythonLauncher/Makefile]) + AC_CONFIG_FILES([Mac/Resources/framework/Info.plist]) + AC_CONFIG_FILES([Mac/Resources/app/Info.plist]) + ;; + iOS) : + FRAMEWORKINSTALLFIRST="frameworkinstallunversionedstructure" + FRAMEWORKALTINSTALLFIRST="frameworkinstallunversionedstructure " + FRAMEWORKINSTALLLAST="frameworkinstallmobileheaders" + FRAMEWORKALTINSTALLLAST="frameworkinstallmobileheaders" + FRAMEWORKPYTHONW= + INSTALLTARGETS="libinstall inclinstall sharedinstall" + + prefix=$PYTHONFRAMEWORKPREFIX + PYTHONFRAMEWORKINSTALLNAMEPREFIX="@rpath/$PYTHONFRAMEWORKDIR" + RESSRCDIR=Platforms/Apple/iOS/Resources + + AC_CONFIG_FILES([Platforms/Apple/iOS/Resources/Info.plist]) + ;; + *) + AC_MSG_ERROR([Unknown platform for framework build]) + ;; + esac + esac + ],[ + case $ac_sys_system in + iOS) AC_MSG_ERROR([iOS builds must use --enable-framework]) ;; + *) + PYTHONFRAMEWORK= + PYTHONFRAMEWORKDIR=no-framework + PYTHONFRAMEWORKPREFIX= + PYTHONFRAMEWORKINSTALLDIR= + PYTHONFRAMEWORKINSTALLNAMEPREFIX= + RESSRCDIR= + FRAMEWORKINSTALLFIRST= + FRAMEWORKINSTALLLAST= + FRAMEWORKALTINSTALLFIRST= + FRAMEWORKALTINSTALLLAST= + FRAMEWORKPYTHONW= + INSTALLTARGETS="commoninstall bininstall maninstall" + if test "x${prefix}" = "xNONE" ; then + FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" + else + FRAMEWORKUNIXTOOLSPREFIX="${prefix}" + fi + enable_framework= + esac +]) +AC_SUBST([PYTHONFRAMEWORK]) +AC_SUBST([PYTHONFRAMEWORKIDENTIFIER]) +AC_SUBST([PYTHONFRAMEWORKDIR]) +AC_SUBST([PYTHONFRAMEWORKPREFIX]) +AC_SUBST([PYTHONFRAMEWORKINSTALLDIR]) +AC_SUBST([PYTHONFRAMEWORKINSTALLNAMEPREFIX]) +AC_SUBST([RESSRCDIR]) +AC_SUBST([FRAMEWORKINSTALLFIRST]) +AC_SUBST([FRAMEWORKINSTALLLAST]) +AC_SUBST([FRAMEWORKALTINSTALLFIRST]) +AC_SUBST([FRAMEWORKALTINSTALLLAST]) +AC_SUBST([FRAMEWORKPYTHONW]) +AC_SUBST([FRAMEWORKUNIXTOOLSPREFIX]) +AC_SUBST([FRAMEWORKINSTALLAPPSPREFIX]) +AC_SUBST([INSTALLTARGETS]) + +AC_DEFINE_UNQUOTED([_PYTHONFRAMEWORK], ["${PYTHONFRAMEWORK}"], + [framework name]) + +dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output +AC_MSG_CHECKING([for --with-app-store-compliance]) +AC_ARG_WITH( + [app_store_compliance], + [AS_HELP_STRING( + [--with-app-store-compliance=@<:@PATCH-FILE@:>@], + [Enable any patches required for compiliance with app stores. + Optional PATCH-FILE specifies the custom patch to apply.] + )],[ + case "$withval" in + yes) + case $ac_sys_system in + Darwin|iOS) + # iOS is able to share the macOS patch + APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch" + ;; + *) AC_MSG_ERROR([no default app store compliance patch available for $ac_sys_system]) ;; + esac + AC_MSG_RESULT([applying default app store compliance patch]) + ;; + *) + APP_STORE_COMPLIANCE_PATCH="${withval}" + AC_MSG_RESULT([applying custom app store compliance patch]) + ;; + esac + ],[ + case $ac_sys_system in + iOS) + # Always apply the compliance patch on iOS; we can use the macOS patch + APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch" + AC_MSG_RESULT([applying default app store compliance patch]) + ;; + *) + # No default app compliance patching on any other platform + APP_STORE_COMPLIANCE_PATCH= + AC_MSG_RESULT([not patching for app store compliance]) + ;; + esac +]) +AC_SUBST([APP_STORE_COMPLIANCE_PATCH]) + +AC_SUBST([_PYTHON_HOST_PLATFORM]) +if test "$cross_compiling" = yes; then + case "$host" in + *-*-linux*) + case "$host_cpu" in + arm*) + _host_ident=arm + ;; + *) + _host_ident=$host_cpu + esac + ;; + *-gnu) + _host_ident=$host_cpu + ;; + *-*-cygwin*) + _host_ident= + ;; + *-apple-ios*) + _host_os=`echo $host | cut -d '-' -f3` + _host_device=`echo $host | cut -d '-' -f4` + _host_device=${_host_device:=os} + + # IPHONEOS_DEPLOYMENT_TARGET is the minimum supported iOS version + AC_MSG_CHECKING([iOS deployment target]) + IPHONEOS_DEPLOYMENT_TARGET=$(echo ${_host_os} | cut -c4-) + IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET:=13.0} + AC_MSG_RESULT([$IPHONEOS_DEPLOYMENT_TARGET]) + + case "$host_cpu" in + aarch64) + _host_ident=${IPHONEOS_DEPLOYMENT_TARGET}-arm64-iphone${_host_device} + ;; + *) + _host_ident=${IPHONEOS_DEPLOYMENT_TARGET}-$host_cpu-iphone${_host_device} + ;; + esac + ;; + *-*-darwin*) + case "$host_cpu" in + arm*) + _host_ident=arm + ;; + *) + _host_ident=$host_cpu + esac + ;; + *-*-vxworks*) + _host_ident=$host_cpu + ;; + *-*-emscripten) + _host_ident=$(emcc -dumpversion | cut -f1 -d-)-$host_cpu + ;; + wasm32-*-* | wasm64-*-*) + _host_ident=$host_cpu + ;; + *) + # for now, limit cross builds to known configurations + MACHDEP="unknown" + AC_MSG_ERROR([cross build not supported for $host]) + esac + _PYTHON_HOST_PLATFORM="$MACHDEP${_host_ident:+-$_host_ident}" +fi + +# Some systems cannot stand _XOPEN_SOURCE being defined at all; they +# disable features if it is defined, without any means to access these +# features as extensions. For these systems, we skip the definition of +# _XOPEN_SOURCE. Before adding a system to the list to gain access to +# some feature, make sure there is no alternative way to access this +# feature. Also, when using wildcards, make sure you have verified the +# need for not defining _XOPEN_SOURCE on all systems matching the +# wildcard, and that the wildcard does not include future systems +# (which may remove their limitations). +dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output +case $ac_sys_system/$ac_sys_release in + # On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined, + # even though select is a POSIX function. Reported by J. Ribbens. + # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish. + # In addition, Stefan Krah confirms that issue #1244610 exists through + # OpenBSD 4.6, but is fixed in 4.7. + OpenBSD/2.* | OpenBSD/3.* | OpenBSD/4.@<:@0123456@:>@) + define_xopen_source=no + # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is + # also defined. This can be overridden by defining _BSD_SOURCE + # As this has a different meaning on Linux, only define it on OpenBSD + AC_DEFINE([_BSD_SOURCE], [1], + [Define on OpenBSD to activate all library features]) + ;; + OpenBSD/*) + # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is + # also defined. This can be overridden by defining _BSD_SOURCE + # As this has a different meaning on Linux, only define it on OpenBSD + AC_DEFINE([_BSD_SOURCE], [1], + [Define on OpenBSD to activate all library features]) + ;; + # Defining _XOPEN_SOURCE on NetBSD version prior to the introduction of + # _NETBSD_SOURCE disables certain features (eg. setgroups). Reported by + # Marc Recht + NetBSD/1.5 | NetBSD/1.5.* | NetBSD/1.6 | NetBSD/1.6.* | NetBSD/1.6@<:@A-S@:>@) + define_xopen_source=no;; + # On Solaris, _XOPEN_SOURCE=800 hides platform specific features. + # A lower level is defined below. + SunOS/*) + define_xopen_source=no;; + # On UnixWare 7, u_long is never defined with _XOPEN_SOURCE, + # but used in /usr/include/netinet/tcp.h. Reported by Tim Rice. + # Reconfirmed for 7.1.4 by Martin v. Loewis. + OpenUNIX/8.0.0| UnixWare/7.1.@<:@0-4@:>@) + define_xopen_source=no;; + # On OpenServer 5, u_short is never defined with _XOPEN_SOURCE, + # but used in struct sockaddr.sa_family. Reported by Tim Rice. + SCO_SV/3.2) + define_xopen_source=no;; + # On MacOS X 10.2, a bug in ncurses.h means that it craps out if + # _XOPEN_EXTENDED_SOURCE is defined. Apparently, this is fixed in 10.3, which + # identifies itself as Darwin/7.* + # On Mac OS X 10.4, defining _POSIX_C_SOURCE or _XOPEN_SOURCE + # disables platform specific features beyond repair. + # On Mac OS X 10.3, defining _POSIX_C_SOURCE or _XOPEN_SOURCE + # has no effect, don't bother defining them + Darwin/@<:@6789@:>@.*) + define_xopen_source=no;; + Darwin/@<:@[12]@:>@@<:@0-9@:>@.*) + define_xopen_source=no;; + # On iOS, defining _POSIX_C_SOURCE also disables platform specific features. + iOS/*) + define_xopen_source=no;; + # On QNX 6.3.2, defining _XOPEN_SOURCE prevents netdb.h from + # defining NI_NUMERICHOST. + QNX/6.3.2) + define_xopen_source=no + ;; + # On VxWorks, defining _XOPEN_SOURCE causes compile failures + # in network headers still using system V types. + VxWorks/*) + define_xopen_source=no + ;; + + # On HP-UX, defining _XOPEN_SOURCE to 600 or greater hides + # chroot() and other functions + hp*|HP*) + define_xopen_source=no + ;; + +esac + +if test $define_xopen_source = yes +then + # X/Open 8, incorporating POSIX.1-2024 + AC_DEFINE([_XOPEN_SOURCE], [800], + [Define to the level of X/Open that your system supports]) + + # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires + # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else + # several APIs are not declared. Since this is also needed in some + # cases for HP-UX, we define it globally. + AC_DEFINE([_XOPEN_SOURCE_EXTENDED], [1], + [Define to activate Unix95-and-earlier features]) + + AC_DEFINE([_POSIX_C_SOURCE], [202405L], + [Define to activate features from IEEE Std 1003.1-2024]) + + # Defining _POSIX_C_SOURCE and _XOPEN_SOURCE hides C23 library + # declarations on FreeBSD (e.g. sinpi() in math.h) when compiling + # with -std=c11. Defining _ISOC23_SOURCE makes them visible again. + AC_DEFINE([_ISOC23_SOURCE], [1], + [Define to activate ISO C23 library declarations]) +elif test "$ac_sys_system" = "SunOS" +then + # On illumos the socket ancillary-data API (CMSG_*, sendmsg(), recvmsg()) + # is declared only with _XOPEN_SOURCE >= 600; Solaris declares it anyway. + # __EXTENSIONS__ keeps the platform specific features which _XOPEN_SOURCE + # would otherwise hide. See gh-57208. + AC_DEFINE([_XOPEN_SOURCE], [600], + [Define to the level of X/Open that your system supports]) +fi + +# On HP-UX mbstate_t requires _INCLUDE__STDC_A1_SOURCE +case $ac_sys_system in + hp*|HP*) + define_stdc_a1=yes;; + *) + define_stdc_a1=no;; +esac + +if test $define_stdc_a1 = yes +then + AC_DEFINE([_INCLUDE__STDC_A1_SOURCE], [1], + [Define to include mbstate_t for mbrtowc]) +fi + +# Record the configure-time value of MACOSX_DEPLOYMENT_TARGET, +# it may influence the way we can build extensions, so distutils +# needs to check it +AC_SUBST([CONFIGURE_MACOSX_DEPLOYMENT_TARGET]) +AC_SUBST([EXPORT_MACOSX_DEPLOYMENT_TARGET]) +CONFIGURE_MACOSX_DEPLOYMENT_TARGET= +EXPORT_MACOSX_DEPLOYMENT_TARGET='#' + +# Record the value of IPHONEOS_DEPLOYMENT_TARGET enforced by the selected host triple. +AC_SUBST([IPHONEOS_DEPLOYMENT_TARGET]) + +# checks for alternative programs + +# compiler flags are generated in two sets, BASECFLAGS and OPT. OPT is just +# for debug/optimization stuff. BASECFLAGS is for flags that are required +# just to get things to compile and link. Users are free to override OPT +# when running configure or make. The build should not break if they do. +# BASECFLAGS should generally not be messed with, however. + +# If the user switches compilers, we can't believe the cache +if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" +then + AC_MSG_ERROR([cached CC is different -- throw away $cache_file +(it is also a good idea to do 'make clean' before compiling)]) +fi + +# Don't let AC_PROG_CC set the default CFLAGS. It normally sets -g -O2 +# when the compiler supports them, but we don't always want -O2, and +# we set -g later. +if test -z "$CFLAGS"; then + CFLAGS= +fi + +dnl Emscripten SDK and WASI SDK default to wasm32. +dnl On Emscripten use MEMORY64 setting to build target wasm64-emscripten. +dnl for wasm64. +AS_CASE([$host], + [wasm64-*-emscripten], [ + AS_VAR_APPEND([CFLAGS], [" -sMEMORY64=1"]) + AS_VAR_APPEND([LDFLAGS], [" -sMEMORY64=1"]) + ], +) + +dnl Add the compiler flag for the iOS minimum supported OS version. +AS_CASE([$host], + [*-apple-ios*-simulator], [ + AS_VAR_APPEND([CFLAGS], [" -mios-simulator-version-min=${IPHONEOS_DEPLOYMENT_TARGET}"]) + AS_VAR_APPEND([LDFLAGS], [" -mios-simulator-version-min=${IPHONEOS_DEPLOYMENT_TARGET}"]) + ], + [*-apple-ios*], [ + AS_VAR_APPEND([CFLAGS], [" -mios-version-min=${IPHONEOS_DEPLOYMENT_TARGET}"]) + AS_VAR_APPEND([LDFLAGS], [" -mios-version-min=${IPHONEOS_DEPLOYMENT_TARGET}"]) + ], +) + +if test "$ac_sys_system" = "Darwin" +then + dnl look for SDKROOT + AC_CHECK_PROG([HAS_XCRUN], [xcrun], [yes], [missing]) + AC_MSG_CHECKING([macOS SDKROOT]) + if test -z "$SDKROOT"; then + dnl SDKROOT not set + if test "$HAS_XCRUN" = "yes"; then + dnl detect with Xcode + SDKROOT=$(xcrun --show-sdk-path) + else + dnl default to root + SDKROOT="/" + fi + fi + AC_MSG_RESULT([$SDKROOT]) + + # Compiler selection on MacOSX is more complicated than + # AC_PROG_CC can handle, see Mac/README for more + # information + if test -z "${CC}" + then + found_gcc= + found_clang= + as_save_IFS=$IFS; IFS=: + for as_dir in $PATH + do + IFS=$as_save_IFS + if test -x "${as_dir}/gcc"; then + if test -z "${found_gcc}"; then + found_gcc="${as_dir}/gcc" + fi + fi + if test -x "${as_dir}/clang"; then + if test -z "${found_clang}"; then + found_clang="${as_dir}/clang" + fi + fi + done + IFS=$as_save_IFS + + if test -n "$found_gcc" -a -n "$found_clang" + then + if test -n "`"$found_gcc" --version | grep llvm-gcc`" + then + AC_MSG_NOTICE([Detected llvm-gcc, falling back to clang]) + CC="$found_clang" + CXX="$found_clang++" + fi + + + elif test -z "$found_gcc" -a -n "$found_clang" + then + AC_MSG_NOTICE([No GCC found, use CLANG]) + CC="$found_clang" + CXX="$found_clang++" + + elif test -z "$found_gcc" -a -z "$found_clang" + then + found_clang=`/usr/bin/xcrun -find clang 2>/dev/null` + if test -n "${found_clang}" + then + AC_MSG_NOTICE([Using clang from Xcode.app]) + CC="${found_clang}" + CXX="`/usr/bin/xcrun -find clang++`" + + # else: use default behaviour + fi + fi + fi +fi +AC_PROG_CC +AC_PROG_CPP +AC_PROG_GREP +AC_PROG_SED +AC_PROG_EGREP + +dnl GNU Autoconf recommends the use of expr instead of basename. +AS_VAR_SET([CC_BASENAME], [$(expr "//$CC" : '.*/\(.*\)')]) + +dnl detect compiler name +dnl check for xlc before clang, newer xlc's can use clang as frontend. +dnl check for GCC last, other compilers set __GNUC__, too. +dnl msvc is listed for completeness. +AC_CACHE_CHECK([for CC compiler name], [ac_cv_cc_name], [ +cat > conftest.c <<EOF +#if defined(__EMSCRIPTEN__) + emcc +#elif defined(__INTEL_CLANG_COMPILER) || defined(__INTEL_LLVM_COMPILER) + icx +#elif defined(__INTEL_COMPILER) || defined(__ICC) + icc +#elif defined(__ibmxl__) || defined(__xlc__) || defined(__xlC__) + xlc +#elif defined(_MSC_VER) + msvc +#elif defined(__clang__) + clang +#elif defined(__GNUC__) + gcc +#else +# error unknown compiler +#endif +EOF + +if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then + ac_cv_cc_name=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` + AS_VAR_IF([CC_BASENAME], [mpicc], [ac_cv_cc_name=mpicc]) +else + ac_cv_cc_name="unknown" +fi +rm -f conftest.c conftest.out +]) + +# checks for UNIX variants that set C preprocessor variables +# may set _GNU_SOURCE, __EXTENSIONS__, _POSIX_PTHREAD_SEMANTICS, +# _POSIX_SOURCE, _POSIX_1_SOURCE, and more +AC_USE_SYSTEM_EXTENSIONS + +AC_CACHE_CHECK([for GCC compatible compiler], + [ac_cv_gcc_compat], + [AC_PREPROC_IFELSE([AC_LANG_SOURCE([ + #if !defined(__GNUC__) + #error "not GCC compatible" + #else + /* GCC compatible! */ + #endif + ], [])], + [ac_cv_gcc_compat=yes], + [ac_cv_gcc_compat=no])]) + +AC_SUBST([CXX]) + +preset_cxx="$CXX" +if test -z "$CXX" +then + case "$ac_cv_cc_name" in + gcc) AC_PATH_TOOL([CXX], [g++], [notfound]) ;; + cc) AC_PATH_TOOL([CXX], [c++], [notfound]) ;; + clang) AC_PATH_TOOL([CXX], [clang++], [notfound]) ;; + icx) AC_PATH_TOOL([CXX], [icpx], [notfound]) ;; + icc) AC_PATH_TOOL([CXX], [icpc], [notfound]) ;; + esac + if test "$CXX" = "notfound" + then + CXX="" + fi +fi +if test -z "$CXX" +then + AC_CHECK_TOOLS([CXX], [$CCC c++ g++ gcc CC cxx cc++ cl], [notfound]) + if test "$CXX" = "notfound" + then + CXX="" + fi +fi +if test "$preset_cxx" != "$CXX" +then + AC_MSG_NOTICE([ + + By default, distutils will build C++ extension modules with "$CXX". + If this is not intended, then set CXX on the configure command line. + ]) +fi + + +AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) +if $CPP $CPPFLAGS $srcdir/Misc/platform_triplet.c >conftest.out 2>/dev/null; then + PLATFORM_TRIPLET=`grep '^PLATFORM_TRIPLET=' conftest.out | tr -d ' '` + PLATFORM_TRIPLET="${PLATFORM_TRIPLET@%:@PLATFORM_TRIPLET=}" + AC_MSG_RESULT([$PLATFORM_TRIPLET]) +else + AC_MSG_RESULT([none]) +fi +rm -f conftest.out + +dnl On some platforms, using a true "triplet" for MULTIARCH would be redundant. +dnl For example, `arm64-apple-darwin` is redundant, because there isn't a +dnl non-Apple Darwin. Including the CPU architecture can also be potentially +dnl redundant - on macOS, for example, it's possible to do a single compile +dnl pass that includes multiple architectures, so it would be misleading for +dnl MULTIARCH (and thus the sysconfigdata module name) to include a single CPU +dnl architecture. PLATFORM_TRIPLET will be a pair or single value for these +dnl platforms. +AC_MSG_CHECKING([for multiarch]) +AS_CASE([$ac_sys_system], + [Darwin*], [MULTIARCH=""], + [iOS], [MULTIARCH=""], + [FreeBSD*], [MULTIARCH=""], + [OpenBSD*], [MULTIARCH=""], + [MULTIARCH=$($CC --print-multiarch 2>/dev/null)] +) +AC_SUBST([MULTIARCH]) + +if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then + if test x$PLATFORM_TRIPLET != x$MULTIARCH; then + AC_MSG_ERROR([internal configure error for the platform triplet, please file a bug report]) + fi +elif test x$PLATFORM_TRIPLET != x && test x$MULTIARCH = x; then + MULTIARCH=$PLATFORM_TRIPLET +fi +AC_SUBST([PLATFORM_TRIPLET]) +AC_MSG_RESULT([$MULTIARCH]) + +dnl Even if we *do* include the CPU architecture in the MULTIARCH value, some +dnl platforms don't need the CPU architecture in the SOABI tag. These platforms +dnl will have multiple sysconfig modules (one for each CPU architecture), but +dnl use a single "fat" binary at runtime. SOABI_PLATFORM is the component of +dnl the PLATFORM_TRIPLET that will be used in binary module extensions. +AS_CASE([$ac_sys_system], + [iOS], [SOABI_PLATFORM=`echo "$PLATFORM_TRIPLET" | cut -d '-' -f2`], + [SOABI_PLATFORM=$PLATFORM_TRIPLET] +) + +if test x$SOABI_PLATFORM != x; then + AC_DEFINE_UNQUOTED([SOABI_PLATFORM], ["${SOABI_PLATFORM}"], [Platform tag, used in binary module extension filenames.]) +fi + +if test x$MULTIARCH != x; then + MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" +fi +AC_SUBST([MULTIARCH_CPPFLAGS]) + +# Guess C stack direction +AS_CASE([$host], + [hppa*], [_Py_STACK_GROWS_DOWN=0], + [_Py_STACK_GROWS_DOWN=1]) +AC_DEFINE_UNQUOTED([_Py_STACK_GROWS_DOWN], [$_Py_STACK_GROWS_DOWN], + [Define to 1 if the machine stack grows down (default); 0 if it grows up.]) +AC_SUBST([_Py_STACK_GROWS_DOWN]) + +dnl Support tiers according to https://peps.python.org/pep-0011/ +dnl +dnl NOTE: Windows support tiers are defined in PC/pyconfig.h. +dnl +AC_MSG_CHECKING([for PEP 11 support tier]) +AS_CASE([$host/$ac_cv_cc_name], + [x86_64-*-linux-gnu/gcc], [PY_SUPPORT_TIER=1], dnl Linux on AMD64, any vendor, glibc, gcc + [x86_64-apple-darwin*/clang], [PY_SUPPORT_TIER=1], dnl macOS on Intel, any version + [aarch64-apple-darwin*/clang], [PY_SUPPORT_TIER=1], dnl macOS on M1, any version + [i686-pc-windows-msvc/msvc], [PY_SUPPORT_TIER=1], dnl 32bit Windows on Intel, MSVC + [x86_64-pc-windows-msvc/msvc], [PY_SUPPORT_TIER=1], dnl 64bit Windows on AMD64, MSVC + + [aarch64-*-linux-gnu/gcc], [PY_SUPPORT_TIER=2], dnl Linux ARM64, glibc, gcc+clang + [aarch64-*-linux-gnu/clang], [PY_SUPPORT_TIER=2], + [powerpc64le-*-linux-gnu/gcc], [PY_SUPPORT_TIER=2], dnl Linux on PPC64 little endian, glibc, gcc + [wasm32-unknown-wasip1/clang], [PY_SUPPORT_TIER=2], dnl WebAssembly System Interface preview1, clang + [x86_64-*-linux-gnu/clang], [PY_SUPPORT_TIER=2], dnl Linux on AMD64, any vendor, glibc, clang + + [aarch64-pc-windows-msvc/msvc], [PY_SUPPORT_TIER=3], dnl Windows ARM64, MSVC + [armv7l-*-linux-gnueabihf/gcc], [PY_SUPPORT_TIER=3], dnl ARMv7 LE with hardware floats, any vendor, glibc, gcc + [powerpc64le-*-linux-gnu/clang], [PY_SUPPORT_TIER=3], dnl Linux on PPC64 little endian, glibc, clang + [riscv64-*-linux-gnu/gcc], [PY_SUPPORT_TIER=3], dnl Linux on RISC-V 64bit, glibc, gcc+clang + [riscv64-*-linux-gnu/clang], [PY_SUPPORT_TIER=3], + [s390x-*-linux-gnu/gcc], [PY_SUPPORT_TIER=3], dnl Linux on 64bit s390x (big endian), glibc, gcc + [x86_64-*-freebsd*/clang], [PY_SUPPORT_TIER=3], dnl FreeBSD on AMD64 + [aarch64-apple-ios*-simulator/clang], [PY_SUPPORT_TIER=3], dnl iOS Simulator on arm64 + [aarch64-apple-ios*/clang], [PY_SUPPORT_TIER=3], dnl iOS on ARM64 + [aarch64-*-linux-android/clang], [PY_SUPPORT_TIER=3], dnl Android on ARM64 + [x86_64-*-linux-android/clang], [PY_SUPPORT_TIER=3], dnl Android on AMD64 + [wasm32-*-emscripten/emcc], [PY_SUPPORT_TIER=3], dnl Emscripten + + [PY_SUPPORT_TIER=0] +) + +AS_CASE([$PY_SUPPORT_TIER], + [1], [AC_MSG_RESULT([$host/$ac_cv_cc_name has tier 1 (supported)])], + [2], [AC_MSG_RESULT([$host/$ac_cv_cc_name has tier 2 (supported)])], + [3], [AC_MSG_RESULT([$host/$ac_cv_cc_name has tier 3 (partially supported)])], + [AC_MSG_WARN([$host/$ac_cv_cc_name is not supported])] +) + +AC_DEFINE_UNQUOTED([PY_SUPPORT_TIER], [$PY_SUPPORT_TIER], [PEP 11 Support tier (1, 2, 3 or 0 for unsupported)]) + +AC_CACHE_CHECK([for -Wl,--no-as-needed], [ac_cv_wl_no_as_needed], [ + save_LDFLAGS="$LDFLAGS" + AS_VAR_APPEND([LDFLAGS], [" -Wl,--no-as-needed"]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [NO_AS_NEEDED="-Wl,--no-as-needed" + ac_cv_wl_no_as_needed=yes], + [NO_AS_NEEDED="" + ac_cv_wl_no_as_needed=no]) + LDFLAGS="$save_LDFLAGS" +]) +AC_SUBST([NO_AS_NEEDED]) + +AC_MSG_CHECKING([for the Android API level]) +cat > conftest.c <<EOF +#ifdef __ANDROID__ +android_api = __ANDROID_API__ +arm_arch = __ARM_ARCH +#else +#error not Android +#endif +EOF + +if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then + ANDROID_API_LEVEL=`sed -n -e '/__ANDROID_API__/d' -e 's/^android_api = //p' conftest.out` + _arm_arch=`sed -n -e '/__ARM_ARCH/d' -e 's/^arm_arch = //p' conftest.out` + AC_MSG_RESULT([$ANDROID_API_LEVEL]) + if test -z "$ANDROID_API_LEVEL"; then + AC_MSG_ERROR([Fatal: you must define __ANDROID_API__]) + fi + AC_DEFINE_UNQUOTED([ANDROID_API_LEVEL], [$ANDROID_API_LEVEL], + [The Android API level.]) + + # For __android_log_write() in Python/pylifecycle.c. + LIBS="$LIBS -llog" + + AC_MSG_CHECKING([for the Android arm ABI]) + AC_MSG_RESULT([$_arm_arch]) + if test "$_arm_arch" = 7; then + BASECFLAGS="${BASECFLAGS} -mfloat-abi=softfp -mfpu=vfpv3-d16" + LDFLAGS="${LDFLAGS} -march=armv7-a -Wl,--fix-cortex-a8" + fi +else + AC_MSG_RESULT([not Android]) +fi +rm -f conftest.c conftest.out + +# Check for unsupported systems +AS_CASE([$ac_sys_system/$ac_sys_release], + [atheos*|Linux*/1*], [ + AC_MSG_ERROR([m4_normalize([ + This system \($ac_sys_system/$ac_sys_release\) is no longer supported. + See README for details. + ])]) + ] +) + +dnl On Emscripten dlopen() requires -s MAIN_MODULE and -fPIC. The flags +dnl disables dead code elimination and increases the size of the WASM module +dnl by about 1.5 to 2MB. MAIN_MODULE defines __wasm_mutable_globals__. +dnl See https://emscripten.org/docs/compiling/Dynamic-Linking.html +AC_MSG_CHECKING([for --enable-wasm-dynamic-linking]) +AC_ARG_ENABLE([wasm-dynamic-linking], + [AS_HELP_STRING([--enable-wasm-dynamic-linking], + [Enable dynamic linking support for WebAssembly (default is no); WASI requires an external dynamic loader to handle imports])], +[ + AS_CASE([$ac_sys_system], + [Emscripten], [], + [WASI], [], + [AC_MSG_ERROR([--enable-wasm-dynamic-linking only applies to Emscripten and WASI])] + ) +], [ + enable_wasm_dynamic_linking=missing +]) +AC_MSG_RESULT([$enable_wasm_dynamic_linking]) + +AC_MSG_CHECKING([for --enable-wasm-pthreads]) +AC_ARG_ENABLE([wasm-pthreads], + [AS_HELP_STRING([--enable-wasm-pthreads], + [Enable pthread emulation for WebAssembly (default is no)])], +[ + AS_CASE([$ac_sys_system], + [Emscripten], [], + [WASI], [], + [AC_MSG_ERROR([--enable-wasm-pthreads only applies to Emscripten and WASI])] + ) +], [ + enable_wasm_pthreads=missing +]) +AC_MSG_RESULT([$enable_wasm_pthreads]) + +AC_MSG_CHECKING([for --enable-emscripten-syscalls]) +AC_ARG_ENABLE([emscripten-syscalls], + [AS_HELP_STRING([--disable-emscripten-syscalls], + [Disable the Emscripten syscall overrides in Python/emscripten_syscalls.c (default is enabled for Emscripten)])], +[ + AS_CASE([$ac_sys_system], + [Emscripten], [], + [AC_MSG_ERROR([--enable-emscripten-syscalls only applies to Emscripten])] + ) +], [ + enable_emscripten_syscalls=yes +]) +AC_MSG_RESULT([$enable_emscripten_syscalls]) + +AC_MSG_CHECKING([for --with-suffix]) +AC_ARG_WITH([suffix], + [AS_HELP_STRING([--with-suffix=SUFFIX], [set executable suffix to SUFFIX (default is empty, yes is mapped to '.exe')])], +[ + AS_CASE([$with_suffix], + [no], [EXEEXT=], + [yes], [EXEEXT=.exe], + [EXEEXT=$with_suffix] + ) +], [ + AS_CASE([$ac_sys_system], + [Emscripten], [EXEEXT=.mjs], + [WASI], [EXEEXT=.wasm], + [EXEEXT=] + ) +]) +AC_MSG_RESULT([$EXEEXT]) + +# Make sure we keep EXEEXT and ac_exeext sync'ed. +AS_VAR_SET([ac_exeext], [$EXEEXT]) + +# Test whether we're running on a non-case-sensitive system, in which +# case we give a warning if no ext is given +AC_SUBST([BUILDEXEEXT]) +AC_MSG_CHECKING([for case-insensitive build directory]) +if test ! -d CaseSensitiveTestDir; then +mkdir CaseSensitiveTestDir +fi + +if test -d casesensitivetestdir && test -z "$EXEEXT" +then + AC_MSG_RESULT([yes]) + BUILDEXEEXT=.exe +else + AC_MSG_RESULT([no]) + BUILDEXEEXT=$EXEEXT +fi +rmdir CaseSensitiveTestDir + +case $ac_sys_system in +hp*|HP*) + case $ac_cv_cc_name in + cc|*/cc) CC="$CC -Ae";; + esac;; +esac + +AC_SUBST([LIBRARY]) +AC_MSG_CHECKING([LIBRARY]) +if test -z "$LIBRARY" +then + LIBRARY='libpython$(VERSION)$(ABIFLAGS).a' +fi +AC_MSG_RESULT([$LIBRARY]) + +# LDLIBRARY is the name of the library to link against (as opposed to the +# name of the library into which to insert object files). BLDLIBRARY is also +# the library to link against, usually. On Mac OS X frameworks, BLDLIBRARY +# is blank as the main program is not linked directly against LDLIBRARY. +# LDLIBRARYDIR is the path to LDLIBRARY, which is made in a subdirectory. On +# systems without shared libraries, LDLIBRARY is the same as LIBRARY +# (defined in the Makefiles). On Cygwin LDLIBRARY is the import library, +# DLLLIBRARY is the shared (i.e., DLL) library. +# +# RUNSHARED is used to run shared python without installed libraries +# +# INSTSONAME is the name of the shared library that will be use to install +# on the system - some systems like version suffix, others don't +# +# LDVERSION is the shared library version number, normally the Python version +# with the ABI build flags appended. +AC_SUBST([LDLIBRARY]) +AC_SUBST([DLLLIBRARY]) +AC_SUBST([BLDLIBRARY]) +AC_SUBST([PY3LIBRARY]) +AC_SUBST([LDLIBRARYDIR]) +AC_SUBST([INSTSONAME]) +AC_SUBST([RUNSHARED]) +AC_SUBST([LDVERSION]) +LDLIBRARY="$LIBRARY" +BLDLIBRARY='$(LDLIBRARY)' +INSTSONAME='$(LDLIBRARY)' +DLLLIBRARY='' +LDLIBRARYDIR='' +RUNSHARED='' +LDVERSION="$VERSION" + +# LINKCC is the command that links the python executable -- default is $(CC). +# If CXX is set, and if it is needed to link a main function that was +# compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable: +# python might then depend on the C++ runtime +AC_SUBST([LINKCC]) +AC_MSG_CHECKING([LINKCC]) +if test -z "$LINKCC" +then + LINKCC='$(PURIFY) $(CC)' + case $ac_sys_system in + QNX*) + # qcc must be used because the other compilers do not + # support -N. + LINKCC=qcc;; + esac +fi +AC_MSG_RESULT([$LINKCC]) + +# EXPORTSYMS holds the list of exported symbols for AIX. +# EXPORTSFROM holds the module name exporting symbols on AIX. +EXPORTSYMS= +EXPORTSFROM= +AC_SUBST([EXPORTSYMS]) +AC_SUBST([EXPORTSFROM]) +AC_MSG_CHECKING([EXPORTSYMS]) +case $ac_sys_system in +AIX*) + EXPORTSYMS="Modules/python.exp" + EXPORTSFROM=. # the main executable + ;; +esac +AC_MSG_RESULT([$EXPORTSYMS]) + +# GNULD is set to "yes" if the GNU linker is used. If this goes wrong +# make sure we default having it set to "no": this is used by +# distutils.unixccompiler to know if it should add --enable-new-dtags +# to linker command lines, and failing to detect GNU ld simply results +# in the same behaviour as before. +AC_SUBST([GNULD]) +AC_MSG_CHECKING([for GNU ld]) +ac_prog=ld +if test "$ac_cv_cc_name" = "gcc"; then + ac_prog=`$CC -print-prog-name=ld` +fi +case `"$ac_prog" -V 2>&1 < /dev/null` in + *GNU*) + GNULD=yes;; + *) + GNULD=no;; +esac +AC_MSG_RESULT([$GNULD]) + +AC_MSG_CHECKING([for --enable-shared]) +AC_ARG_ENABLE([shared], + AS_HELP_STRING([--enable-shared], [enable building a shared Python library (default is no)])) + +if test -z "$enable_shared" +then + case $ac_sys_system in + CYGWIN*) + enable_shared="yes";; + *) + enable_shared="no";; + esac +fi +AC_MSG_RESULT([$enable_shared]) + +# --with-static-libpython +STATIC_LIBPYTHON=1 +AC_MSG_CHECKING([for --with-static-libpython]) +AC_ARG_WITH([static-libpython], + AS_HELP_STRING([--without-static-libpython], + [do not build libpythonMAJOR.MINOR.a and do not install python.o (default is yes)]), +[ +if test "$withval" = no +then + AC_MSG_RESULT([no]); + STATIC_LIBPYTHON=0 +else + AC_MSG_RESULT([yes]); +fi], +[AC_MSG_RESULT([yes])]) +AC_SUBST([STATIC_LIBPYTHON]) + +AC_MSG_CHECKING([for --enable-static-libpython-for-interpreter]) +AC_ARG_ENABLE([static-libpython-for-interpreter], + AS_HELP_STRING([--enable-static-libpython-for-interpreter], + [even with --enable-shared, statically link libpython into the interpreter (default is to use the shared library)])) + +if test -z "$enable_static_libpython_for_interpreter" +then + enable_static_libpython_for_interpreter="no" +fi +AC_MSG_RESULT([$enable_static_libpython_for_interpreter]) + +AC_MSG_CHECKING([for --enable-profiling]) +AC_ARG_ENABLE([profiling], + AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) +if test "x$enable_profiling" = xyes; then + ac_save_cc="$CC" + CC="$CC -pg" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])], + [], + [enable_profiling=no]) + CC="$ac_save_cc" +else + enable_profiling=no +fi +AC_MSG_RESULT([$enable_profiling]) + +if test "x$enable_profiling" = xyes; then + BASECFLAGS="-pg $BASECFLAGS" + LDFLAGS="-pg $LDFLAGS" +fi + +AC_MSG_CHECKING([LDLIBRARY]) + +# Apple framework builds need more magic. LDLIBRARY is the dynamic +# library that we build, but we do not want to link against it (we +# will find it with a -framework option). For this reason there is an +# extra variable BLDLIBRARY against which Python and the extension +# modules are linked, BLDLIBRARY. This is normally the same as +# LDLIBRARY, but empty for MacOSX framework builds. iOS does the same, +# but uses a non-versioned framework layout. +if test "$enable_framework" +then + case $ac_sys_system in + Darwin) + LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)';; + iOS) + LDLIBRARY='$(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)';; + *) + AC_MSG_ERROR([Unknown platform for framework build]);; + esac + BLDLIBRARY='' + RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}} +else + BLDLIBRARY='$(LDLIBRARY)' +fi + +# Other platforms follow +if test $enable_shared = "yes"; then + PY_ENABLE_SHARED=1 + AC_DEFINE([Py_ENABLE_SHARED], [1], + [Defined if Python is built as a shared library.]) + case $ac_sys_system in + CYGWIN*) + LDLIBRARY='libpython$(LDVERSION).dll.a' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + DLLLIBRARY='cygpython$(LDVERSION).dll' + ;; + SunOS*) + LDLIBRARY='libpython$(LDVERSION).so' + BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + INSTSONAME="$LDLIBRARY".$SOVERSION + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so + fi + ;; + Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*|VxWorks*) + LDLIBRARY='libpython$(LDVERSION).so' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + + # The Android Gradle plugin will only package libraries whose names end + # with ".so". + if test "$ac_sys_system" != "Linux-android"; then + INSTSONAME="$LDLIBRARY".$SOVERSION + fi + + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so + fi + ;; + hp*|HP*) + case `uname -m` in + ia64) + LDLIBRARY='libpython$(LDVERSION).so' + ;; + *) + LDLIBRARY='libpython$(LDVERSION).sl' + ;; + esac + BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)' + RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}} + ;; + Darwin*) + LDLIBRARY='libpython$(LDVERSION).dylib' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}} + ;; + iOS) + LDLIBRARY='libpython$(LDVERSION).dylib' + ;; + AIX*) + LDLIBRARY='libpython$(LDVERSION).so' + RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}} + ;; + + esac +else # shared is disabled + PY_ENABLE_SHARED=0 + case $ac_sys_system in + CYGWIN*) + BLDLIBRARY='$(LIBRARY)' + LDLIBRARY='libpython$(LDVERSION).a' + ;; + esac +fi +AC_MSG_RESULT([$LDLIBRARY]) + +# HOSTRUNNER - Program to run CPython for the host platform +AC_MSG_CHECKING([HOSTRUNNER]) +if test -z "$HOSTRUNNER" +then + AS_CASE([$ac_sys_system], + [Emscripten], [ + AC_PATH_TOOL([NODE], [node], [node]) + HOSTRUNNER="$NODE" + AS_VAR_IF([host_cpu], [wasm64], [AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-memory64"])]) + ], + [WASI], [ + AC_MSG_ERROR([HOSTRUNNER must be set when cross-compiling to WASI]) + ], + [HOSTRUNNER=''] + ) +fi +AC_SUBST([HOSTRUNNER]) +AC_MSG_RESULT([$HOSTRUNNER]) + +if test -n "$HOSTRUNNER"; then + dnl Pass hostrunner variable as env var in order to expand shell expressions. + PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" +fi + +# LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable +LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)' + +LINK_PYTHON_DEPS='$(LIBRARY_DEPS)' +if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then + LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS" + if test "$STATIC_LIBPYTHON" = 1; then + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + fi + # Link Python program to the shared library + if test "$enable_static_libpython_for_interpreter" = "yes"; then + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' + else + LINK_PYTHON_OBJS='$(BLDLIBRARY)' + fi +else + if test "$STATIC_LIBPYTHON" = 0; then + # Build Python needs object files but don't need to build + # Python static library + LINK_PYTHON_DEPS="$LIBRARY_DEPS \$(LIBRARY_OBJS)" + fi + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + # Link Python program to object files + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' +fi +AC_SUBST([LIBRARY_DEPS]) +AC_SUBST([LINK_PYTHON_DEPS]) +AC_SUBST([LINK_PYTHON_OBJS]) + +# ar program +AC_SUBST([AR]) +AC_CHECK_TOOLS([AR], [ar aal], [ar]) + +# tweak ARFLAGS only if the user didn't set it on the command line +AC_SUBST([ARFLAGS]) +if test -z "$ARFLAGS" +then + ARFLAGS="rcs" +fi + +case $MACHDEP in +hp*|HP*) + # install -d does not work on HP-UX + if test -z "$INSTALL" + then + INSTALL="${srcdir}/install-sh -c" + fi +esac +AC_PROG_INSTALL +AC_PROG_MKDIR_P + +# Not every filesystem supports hard links +AC_SUBST([LN]) +if test -z "$LN" ; then + case $ac_sys_system in + CYGWIN*) LN="ln -s";; + *) LN=ln;; + esac +fi + +# For calculating the .so ABI tag. +AC_SUBST([ABIFLAGS]) +AC_SUBST([ABI_THREAD]) +ABIFLAGS="" +ABI_THREAD="" + +# Check for --disable-gil +# --disable-gil +AC_MSG_CHECKING([for --disable-gil]) +AC_ARG_ENABLE([gil], + [AS_HELP_STRING([--disable-gil], [enable support for running without the GIL (default is no)])], + [AS_VAR_IF([enable_gil], [yes], [disable_gil=no], [disable_gil=yes])], [disable_gil=no] +) +AC_MSG_RESULT([$disable_gil]) + +if test "$disable_gil" = "yes" +then + AC_DEFINE([Py_GIL_DISABLED], [1], + [Define if you want to disable the GIL]) + # Add "t" for "threaded" + ABIFLAGS="${ABIFLAGS}t" + ABI_THREAD="t" +fi + +# Check for --with-pydebug +AC_MSG_CHECKING([for --with-pydebug]) +AC_ARG_WITH([pydebug], + [AS_HELP_STRING([--with-pydebug], [build with Py_DEBUG defined (default is no)]) ], +[ +if test "$withval" != no +then + AC_DEFINE([Py_DEBUG], [1], + [Define if you want to build an interpreter with many run-time checks.]) + AC_MSG_RESULT([yes]); + Py_DEBUG='true' + ABIFLAGS="${ABIFLAGS}d" +else AC_MSG_RESULT([no]); Py_DEBUG='false' +fi], +[AC_MSG_RESULT([no])]) + +# Check for --with-trace-refs +# --with-trace-refs +AC_MSG_CHECKING([for --with-trace-refs]) +AC_ARG_WITH([trace-refs], + [AS_HELP_STRING([--with-trace-refs], [enable tracing references for debugging purpose (default is no)])], + [], [with_trace_refs=no] +) +AC_MSG_RESULT([$with_trace_refs]) + +if test "$with_trace_refs" = "yes" +then + AC_DEFINE([Py_TRACE_REFS], [1], + [Define if you want to enable tracing references for debugging purpose]) +fi + +if test "$disable_gil" = "yes" -a "$with_trace_refs" = "yes"; +then + AC_MSG_ERROR([--disable-gil cannot be used with --with-trace-refs]) +fi + +# Check for --enable-pystats +AC_MSG_CHECKING([for --enable-pystats]) +AC_ARG_ENABLE([pystats], + [AS_HELP_STRING( + [--enable-pystats], + [enable internal statistics gathering (default is no)] + )], + [], [enable_pystats=no] +) +AC_MSG_RESULT([$enable_pystats]) + +AS_VAR_IF([enable_pystats], [yes], [ + AC_DEFINE([Py_STATS], [1], [Define if you want to enable internal statistics gathering.]) +]) + +# Check for --with-assertions. +# This allows enabling assertions without Py_DEBUG. +assertions='false' +AC_MSG_CHECKING([for --with-assertions]) +AC_ARG_WITH([assertions], + AS_HELP_STRING([--with-assertions],[build with C assertions enabled (default is no)]), +[ +if test "$withval" != no +then + assertions='true' +fi], +[]) +if test "$assertions" = 'true'; then + AC_MSG_RESULT([yes]) +elif test "$Py_DEBUG" = 'true'; then + assertions='true' + AC_MSG_RESULT([implied by --with-pydebug]) +else + AC_MSG_RESULT([no]) +fi + +# Enable optimization flags +AC_SUBST([DEF_MAKE_ALL_RULE]) +AC_SUBST([DEF_MAKE_RULE]) +Py_OPT='false' +AC_MSG_CHECKING([for --enable-optimizations]) +AC_ARG_ENABLE([optimizations], AS_HELP_STRING( + [--enable-optimizations], + [enable expensive, stable optimizations (PGO, etc.) (default is no)]), +[ +if test "$enableval" != no +then + Py_OPT='true' + AC_MSG_RESULT([yes]); +else + Py_OPT='false' + AC_MSG_RESULT([no]); +fi], +[AC_MSG_RESULT([no])]) + +if test "$Py_OPT" = 'true' ; then + # Check for conflicting CFLAGS=-O0 and --enable-optimizations + case "$CFLAGS" in + *-O0*) + AC_MSG_WARN([m4_normalize([ + CFLAGS contains -O0 which may conflict with --enable-optimizations. + Consider removing -O0 from CFLAGS for optimal performance.])]) + ;; + esac + # Intentionally not forcing Py_LTO='true' here. Too many toolchains do not + # compile working code using it and both test_distutils and test_gdb are + # broken when you do manage to get a toolchain that works with it. People + # who want LTO need to use --with-lto themselves. + DEF_MAKE_ALL_RULE="profile-opt" + REQUIRE_PGO="yes" + DEF_MAKE_RULE="build_all" + AS_VAR_IF([ac_cv_gcc_compat], [yes], [ + AX_CHECK_COMPILE_FLAG([-fno-semantic-interposition],[ + CFLAGS_NODIST="$CFLAGS_NODIST -fno-semantic-interposition" + LDFLAGS_NODIST="$LDFLAGS_NODIST -fno-semantic-interposition" + ], [], [-Werror]) + ]) +elif test "$ac_sys_system" = "Emscripten"; then + dnl Build "python.[js,wasm]", "pybuilddir.txt", and "platform" files. + DEF_MAKE_ALL_RULE="build_emscripten" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" +elif test "$ac_sys_system" = "WASI"; then + dnl Build "python.wasm", "pybuilddir.txt", and "platform" files. + DEF_MAKE_ALL_RULE="build_wasm" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" +else + DEF_MAKE_ALL_RULE="build_all" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" +fi + +AC_ARG_VAR([PROFILE_TASK], [Python args for PGO generation task]) +AC_MSG_CHECKING([PROFILE_TASK]) +if test -z "$PROFILE_TASK" +then + PROFILE_TASK='-m test --pgo --timeout=$(TESTTIMEOUT)' +fi +AC_MSG_RESULT([$PROFILE_TASK]) + +# Make llvm-related checks work on systems where llvm tools are not installed with their +# normal names in the default $PATH (ie: Ubuntu). They exist under the +# non-suffixed name in their versioned llvm directory. + +llvm_bin_dir='' +llvm_path="${PATH}" +if test "${ac_cv_cc_name}" = "clang" +then + clang_bin=`which clang` + # Some systems install clang elsewhere as a symlink to the real path + # which is where the related llvm tools are located. + if test -L "${clang_bin}" + then + clang_dir=`dirname "${clang_bin}"` + clang_bin=`readlink "${clang_bin}"` + llvm_bin_dir="${clang_dir}/"`dirname "${clang_bin}"` + llvm_path="${llvm_path}${PATH_SEPARATOR}${llvm_bin_dir}" + fi +fi + +# Enable LTO flags +AC_MSG_CHECKING([for --with-lto]) +AC_ARG_WITH([lto], + [AS_HELP_STRING([--with-lto=@<:@full|thin|no|yes@:>@], [enable Link-Time-Optimization in any build (default is no)])], +[ +case "$withval" in + full) + Py_LTO='true' + Py_LTO_POLICY='full' + AC_MSG_RESULT([yes]) + ;; + thin) + Py_LTO='true' + Py_LTO_POLICY='thin' + AC_MSG_RESULT([yes]) + ;; + yes) + Py_LTO='true' + Py_LTO_POLICY='default' + AC_MSG_RESULT([yes]) + ;; + no) + Py_LTO='false' + AC_MSG_RESULT([no]) + ;; + *) + Py_LTO='false' + AC_MSG_ERROR([unknown lto option: '$withval']) + ;; +esac +], +[AC_MSG_RESULT([no])]) +if test "$Py_LTO" = 'true' ; then + case $ac_cv_cc_name in + clang) + LDFLAGS_NOLTO="-fno-lto" + dnl Clang linker requires -flto in order to link objects with LTO information. + dnl Thin LTO is faster and works for object files with full LTO information, too. + AX_CHECK_COMPILE_FLAG([-flto=thin],[LDFLAGS_NOLTO="-flto=thin"],[LDFLAGS_NOLTO="-flto"]) + AC_SUBST([LLVM_AR]) + AC_PATH_TOOL([LLVM_AR], [llvm-ar], [''], [${llvm_path}]) + AC_SUBST([LLVM_AR_FOUND]) + if test -n "${LLVM_AR}" -a -x "${LLVM_AR}" + then + LLVM_AR_FOUND="found" + else + LLVM_AR_FOUND="not-found" + fi + if test "$ac_sys_system" = "Darwin" -a "${LLVM_AR_FOUND}" = "not-found" + then + # The Apple-supplied ar in Xcode or the Command Line Tools is apparently sufficient + found_llvm_ar=`/usr/bin/xcrun -find ar 2>/dev/null` + if test -n "${found_llvm_ar}" + then + LLVM_AR='/usr/bin/xcrun ar' + LLVM_AR_FOUND=found + AC_MSG_NOTICE([llvm-ar found via xcrun: ${LLVM_AR}]) + fi + fi + if test $LLVM_AR_FOUND = not-found + then + LLVM_PROFR_ERR=yes + AC_MSG_ERROR([llvm-ar is required for a --with-lto build with clang but could not be found.]) + else + LLVM_AR_ERR=no + fi + AR="${LLVM_AR}" + case $ac_sys_system in + Darwin*) + # Any changes made here should be reflected in the GCC+Darwin case below + if test $Py_LTO_POLICY = default + then + # Check that ThinLTO is accepted. + AX_CHECK_COMPILE_FLAG([-flto=thin],[ + LTOFLAGS="-flto=thin -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=thin" + ],[ + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + ] + ) + else + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=${Py_LTO_POLICY}" + fi + ;; + *) + if test $Py_LTO_POLICY = default + then + # Check that ThinLTO is accepted + AX_CHECK_COMPILE_FLAG([-flto=thin],[LTOFLAGS="-flto=thin"],[LTOFLAGS="-flto"]) + else + LTOFLAGS="-flto=${Py_LTO_POLICY}" + fi + ;; + esac + ;; + emcc) + if test "$Py_LTO_POLICY" != "default"; then + AC_MSG_ERROR([emcc supports only default lto.]) + fi + LTOFLAGS="-flto" + LTOCFLAGS="-flto" + ;; + gcc) + if test $Py_LTO_POLICY = thin + then + AC_MSG_ERROR([thin lto is not supported under gcc compiler.]) + fi + dnl flag to disable lto during linking + LDFLAGS_NOLTO="-fno-lto" + case $ac_sys_system in + Darwin*) + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + ;; + *) + LTOFLAGS="-flto -fuse-linker-plugin -ffat-lto-objects" + ;; + esac + ;; + esac + + if test "$ac_cv_prog_cc_g" = "yes" + then + # bpo-30345: Add -g to LDFLAGS when compiling with LTO + # to get debug symbols. + LTOFLAGS="$LTOFLAGS -g" + fi + + CFLAGS_NODIST="$CFLAGS_NODIST ${LTOCFLAGS-$LTOFLAGS}" + LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS" +fi + +# Enable PGO flags. +AC_SUBST([PGO_PROF_GEN_FLAG]) +AC_SUBST([PGO_PROF_USE_FLAG]) +AC_SUBST([LLVM_PROF_MERGER]) +AC_SUBST([LLVM_PROF_FILE]) +AC_SUBST([LLVM_PROF_ERR]) +AC_SUBST([LLVM_PROFDATA]) +AC_PATH_TOOL([LLVM_PROFDATA], [llvm-profdata], [''], [${llvm_path}]) +AC_SUBST([LLVM_PROF_FOUND]) +if test -n "${LLVM_PROFDATA}" -a -x "${LLVM_PROFDATA}" +then + LLVM_PROF_FOUND="found" +else + LLVM_PROF_FOUND="not-found" +fi +if test "$ac_sys_system" = "Darwin" -a "${LLVM_PROF_FOUND}" = "not-found" +then + found_llvm_profdata=`/usr/bin/xcrun -find llvm-profdata 2>/dev/null` + if test -n "${found_llvm_profdata}" + then + # llvm-profdata isn't directly in $PATH in some cases. + # https://apple.stackexchange.com/questions/197053/ + LLVM_PROFDATA='/usr/bin/xcrun llvm-profdata' + LLVM_PROF_FOUND=found + AC_MSG_NOTICE([llvm-profdata found via xcrun: ${LLVM_PROFDATA}]) + fi +fi +LLVM_PROF_ERR=no + +case "$ac_cv_cc_name" in + clang|icx) + # Any changes made here should be reflected in the GCC+Darwin case below + PGO_PROF_GEN_FLAG="-fprofile-instr-generate" + PGO_PROF_USE_FLAG="-fprofile-instr-use=\"\$(shell pwd)/code.profclangd\"" + LLVM_PROF_MERGER=m4_normalize(" + ${LLVM_PROFDATA} merge + -output=\"\$(shell pwd)/code.profclangd\" + \"\$(shell pwd)\"/*.profclangr + ") + LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"\$(shell pwd)/code-%p.profclangr\"" + if test $LLVM_PROF_FOUND = not-found + then + LLVM_PROF_ERR=yes + if test "${REQUIRE_PGO}" = "yes" + then + AC_MSG_ERROR([llvm-profdata is required for a --enable-optimizations build but could not be found.]) + fi + fi + ;; + gcc) + # Check for 32-bit x86 ISA + AC_CACHE_CHECK([for i686], [ac_cv_i686], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ + #ifdef __i386__ + # error "i386" + #endif + ], []) + ],[ac_cv_i686=no],[ac_cv_i686=yes]) + ]) + + PGO_PROF_GEN_FLAG="-fprofile-generate" + + # Use -fprofile-update=atomic to fix a random GCC internal error on PGO + # build (gh-145801) caused by corruption of profile data (.gcda files). + # + # gh-148535: On i686, using -fprofile-update=atomic makes the PGO build + # way slower (up to 47x slower). So far, the GCC internal error on PGO + # build was not seen on i686, so don't use this flag on i686. + AS_VAR_IF([ac_cv_i686], [no], [ + AX_CHECK_COMPILE_FLAG( + [-fprofile-update=atomic], + [PGO_PROF_GEN_FLAG="$PGO_PROF_GEN_FLAG -fprofile-update=atomic"], + []) + ]) + + PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction" + LLVM_PROF_MERGER="true" + LLVM_PROF_FILE="" + ;; + icc) + PGO_PROF_GEN_FLAG="-prof-gen" + PGO_PROF_USE_FLAG="-prof-use" + LLVM_PROF_MERGER="true" + LLVM_PROF_FILE="" + ;; +esac + +# BOLT optimization. Always configured after PGO since it always runs after PGO. +Py_BOLT='false' +AC_MSG_CHECKING([for --enable-bolt]) +AC_ARG_ENABLE([bolt], [AS_HELP_STRING( + [--enable-bolt], + [enable usage of the llvm-bolt post-link optimizer (default is no)])], +[ +if test "$enableval" != no +then + Py_BOLT='true' + AC_MSG_RESULT([yes]); +else + Py_BOLT='false' + AC_MSG_RESULT([no]); +fi], +[AC_MSG_RESULT([no])]) + +AC_SUBST([PREBOLT_RULE]) +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" + + # -fno-reorder-blocks-and-partition is required for bolt to work. + # Possibly GCC only. + AX_CHECK_COMPILE_FLAG([-fno-reorder-blocks-and-partition],[ + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + ]) + + # These flags are required for bolt to work: + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" + + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" + AC_SUBST([LLVM_BOLT]) + AC_PATH_TOOL([LLVM_BOLT], [llvm-bolt], [''], [${llvm_path}]) + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + AC_MSG_RESULT(["Found llvm-bolt"]) + else + AC_MSG_ERROR([llvm-bolt is required for a --enable-bolt build but could not be found.]) + fi + + AC_SUBST([MERGE_FDATA]) + AC_PATH_TOOL([MERGE_FDATA], [merge-fdata], [''], [${llvm_path}]) + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + AC_MSG_RESULT(["Found merge-fdata"]) + else + AC_MSG_ERROR([merge-fdata is required for a --enable-bolt build but could not be found.]) + fi +fi + +dnl Enable BOLT of libpython if built and used by the python3 binary. +dnl (If it is built but not used, we cannot profile it.) +AC_SUBST([BOLT_BINARIES]) +BOLT_BINARIES='$(BUILDPYTHON)' +AS_VAR_IF([enable_shared], [yes], [ + AS_VAR_IF([enable_static_libpython_for_interpreter], [no], [ + BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" + ]) +]) + +AC_ARG_VAR( + [BOLT_COMMON_FLAGS], + [Common arguments to llvm-bolt when instrumenting and applying] +) + +AC_MSG_CHECKING([BOLT_COMMON_FLAGS]) +if test -z "${BOLT_COMMON_FLAGS}" +then + AS_VAR_SET( + [BOLT_COMMON_FLAGS], + [m4_normalize(" + [-update-debug-sections] + + dnl At least LLVM 19.x doesn't support computed gotos in PIC compiled code. + dnl Exclude functions containing computed gotos. + dnl TODO this may be fixed in LLVM 20.x via https://github.com/llvm/llvm-project/pull/120267. + dnl GCC's LTO creates .lto_priv.0 clones of these functions. + [-skip-funcs=_PyEval_EvalFrameDefault,sre_ucs1_match/1,sre_ucs2_match/1,sre_ucs4_match/1,sre_ucs1_match.lto_priv.0/1,sre_ucs2_match.lto_priv.0/1,sre_ucs4_match.lto_priv.0/1] + ")] + ) +fi + +AC_ARG_VAR( + [BOLT_INSTRUMENT_FLAGS], + [Arguments to llvm-bolt when instrumenting binaries] +) +AC_MSG_CHECKING([BOLT_INSTRUMENT_FLAGS]) +if test -z "${BOLT_INSTRUMENT_FLAGS}" +then + BOLT_INSTRUMENT_FLAGS="${BOLT_COMMON_FLAGS}" +fi +AC_MSG_RESULT([$BOLT_INSTRUMENT_FLAGS]) + +AC_ARG_VAR( + [BOLT_APPLY_FLAGS], + [Arguments to llvm-bolt when creating a BOLT optimized binary] +) +AC_MSG_CHECKING([BOLT_APPLY_FLAGS]) +if test -z "${BOLT_APPLY_FLAGS}" +then + AS_VAR_SET( + [BOLT_APPLY_FLAGS], + [m4_normalize(" + ${BOLT_COMMON_FLAGS} + -reorder-blocks=ext-tsp + -reorder-functions=cdsort + -split-functions + -icf=0 + -inline-all + -split-eh + -reorder-functions-use-hot-size + -peepholes=none + -jump-tables=aggressive + -inline-ap + -indirect-call-promotion=all + -dyno-stats + -use-gnu-stack + -frame-opt=hot + ")] + ) +fi +AC_MSG_RESULT([$BOLT_APPLY_FLAGS]) + +# XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be +# merged with this chunk of code? + +# Optimizer/debugger flags +# ------------------------ +# (The following bit of code is complicated enough - please keep things +# indented properly. Just pretend you're editing Python code. ;-) + +# There are two parallel sets of case statements below, one that checks to +# see if OPT was set and one that does BASECFLAGS setting based upon +# compiler and platform. BASECFLAGS tweaks need to be made even if the +# user set OPT. + +dnl Historically, some of our code assumed that signed integer overflow +dnl is defined behaviour via twos-complement. +dnl Set STRICT_OVERFLOW_CFLAGS and NO_STRICT_OVERFLOW_CFLAGS depending on compiler support. +dnl Pass the latter to modules that depend on such behaviour. +_SAVE_VAR([CFLAGS]) +CFLAGS="-fstrict-overflow -fno-strict-overflow" +AC_CACHE_CHECK([if $CC supports -fstrict-overflow and -fno-strict-overflow], + [ac_cv_cc_supports_fstrict_overflow], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [ac_cv_cc_supports_fstrict_overflow=yes], + [ac_cv_cc_supports_fstrict_overflow=no] + ) +) +_RESTORE_VAR([CFLAGS]) + +AS_VAR_IF([ac_cv_cc_supports_fstrict_overflow], [yes], + [STRICT_OVERFLOW_CFLAGS="-fstrict-overflow" + NO_STRICT_OVERFLOW_CFLAGS="-fno-strict-overflow"], + [STRICT_OVERFLOW_CFLAGS="" + NO_STRICT_OVERFLOW_CFLAGS=""]) + +AC_MSG_CHECKING([for --with-strict-overflow]) +AC_ARG_WITH([strict-overflow], + AS_HELP_STRING( + [--with-strict-overflow], + [if 'yes', add -fstrict-overflow to CFLAGS, else add -fno-strict-overflow (default is no)] + ), + [ + AS_VAR_IF( + [ac_cv_cc_supports_fstrict_overflow], [no], + [AC_MSG_WARN([--with-strict-overflow=yes requires a compiler that supports -fstrict-overflow])], + [] + ) + ], + [with_strict_overflow=no] +) +AC_MSG_RESULT([$with_strict_overflow]) + +# Check if CC supports -Og optimization level +_SAVE_VAR([CFLAGS]) +CFLAGS="-Og" +AC_CACHE_CHECK([if $CC supports -Og optimization level], + [ac_cv_cc_supports_og], + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM([[]], [[]]) + ],[ + ac_cv_cc_supports_og=yes + ],[ + ac_cv_cc_supports_og=no + ]) +) +_RESTORE_VAR([CFLAGS]) + +# Optimization messes up debuggers, so turn it off for +# debug builds. +PYDEBUG_CFLAGS="-O0" +AS_VAR_IF([ac_cv_cc_supports_og], [yes], + [PYDEBUG_CFLAGS="-Og"]) + +# gh-120688: WASI uses -O3 in debug mode to support more recursive calls +if test "$ac_sys_system" = "WASI"; then + PYDEBUG_CFLAGS="-O3" +fi + +# tweak OPT based on compiler and platform, only if the user didn't set +# it on the command line +AC_SUBST([OPT]) +AC_SUBST([CFLAGS_ALIASING]) +if test "${OPT-unset}" = "unset" +then + case $GCC in + yes) + if test "${ac_cv_cc_name}" != "clang" + then + # bpo-30104: disable strict aliasing to compile correctly dtoa.c, + # see Makefile.pre.in for more information + CFLAGS_ALIASING="-fno-strict-aliasing" + fi + + case $ac_cv_prog_cc_g in + yes) + if test "$Py_DEBUG" = 'true' ; then + OPT="-g $PYDEBUG_CFLAGS -Wall" + else + OPT="-g -O3 -Wall" + fi + ;; + *) + OPT="-O3 -Wall" + ;; + esac + + case $ac_sys_system in + SCO_SV*) OPT="$OPT -m486 -DSCO5" + ;; + esac + ;; + + *) + OPT="-O" + ;; + esac +fi + +# WASM flags +AS_CASE([$ac_sys_system], + [Emscripten], [ + dnl build with WASM debug info if either Py_DEBUG is set or the target is + dnl node-debug or browser-debug. + AS_VAR_IF([Py_DEBUG], [yes], [wasm_debug=yes], [wasm_debug=no]) + + dnl Start with 20 MB and allow to grow + AS_VAR_APPEND([LINKFORSHARED], [" -sALLOW_MEMORY_GROWTH -sINITIAL_MEMORY=20971520"]) + + dnl map int64_t and uint64_t to JS bigint + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sWASM_BIGINT"]) + + dnl Include file system support + AS_VAR_APPEND([LINKFORSHARED], [" -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"]) + AS_VAR_APPEND([LINKFORSHARED], [" -sEXPORTED_RUNTIME_METHODS=FS,callMain,ENV,HEAPU32,TTY,ERRNO_CODES"]) + AS_VAR_APPEND([LINKFORSHARED], [" -sEXPORTED_FUNCTIONS=_main,_Py_Version,__PyRuntime,_PyGILState_GetThisThreadState,__PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET"]) + AS_VAR_APPEND([LINKFORSHARED], [" -sSTACK_SIZE=5MB"]) + dnl Avoid bugs in JS fallback string decoding path + AS_VAR_APPEND([LINKFORSHARED], [" -sTEXTDECODER=2"]) + + AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"]) + ]) + + AS_VAR_IF([enable_wasm_pthreads], [yes], [ + AS_VAR_APPEND([CFLAGS_NODIST], [" -pthread"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sUSE_PTHREADS"]) + AS_VAR_APPEND([LINKFORSHARED], [" -sPROXY_TO_PTHREAD"]) + ]) + dnl not completely sure whether or not we want -sEXIT_RUNTIME, keeping it for now. + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXIT_RUNTIME"]) + WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map" + + AS_VAR_IF([wasm_debug], [yes], [ + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sASSERTIONS"]) + AS_VAR_APPEND([LINKFORSHARED], [" $WASM_LINKFORSHARED_DEBUG"]) + ], [ + AS_VAR_APPEND([LINKFORSHARED], [" -O2 -g0"]) + ]) + ], + [WASI], [ + AC_DEFINE([_WASI_EMULATED_SIGNAL], [1], [Define to 1 if you want to emulate signals on WASI]) + AC_DEFINE([_WASI_EMULATED_GETPID], [1], [Define to 1 if you want to emulate getpid() on WASI]) + AC_DEFINE([_WASI_EMULATED_PROCESS_CLOCKS], [1], [Define to 1 if you want to emulate process clocks on WASI]) + LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" + echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h + + AS_VAR_IF([enable_wasm_pthreads], [yes], [ + # Note: update CFLAGS because ac_compile/ac_link needs this too. + # without this, configure fails to find pthread_create, sem_init, + # etc because they are only available in the sysroot for + # wasm32-wasi-threads. + # Note: wasi-threads requires --import-memory. + # Note: wasi requires --export-memory. + # Note: --export-memory is implicit unless --import-memory is given + # Note: this requires LLVM >= 16. + AS_VAR_APPEND([CFLAGS], [" -target wasm32-wasi-threads -pthread"]) + AS_VAR_APPEND([CFLAGS_NODIST], [" -target wasm32-wasi-threads -pthread"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -target wasm32-wasi-threads -pthread"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--import-memory"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--export-memory"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--max-memory=10485760"]) + ]) + + dnl gh-117645: Set the memory size to 40 MiB, the stack size to 16 MiB, + dnl and move the stack first. + dnl https://github.com/WebAssembly/wasi-libc/issues/233 + AS_VAR_APPEND([LDFLAGS_NODIST], [" -z stack-size=16777216 -Wl,--stack-first -Wl,--initial-memory=41943040"]) + ] +) + +dnl On Linux, check the thread stack size. musl (ex: Alpine Linux) uses +dnl a default thread stack size of 128 kB, whereas the glibc uses 8 MiB. +dnl Python needs at least 1 MiB. +if test "$ac_sys_system" = "Linux" -a "$cross_compiling" = no; then + AC_CACHE_CHECK([for thread stack size], [ac_cv_thread_stack_size], [ + cat > conftest.c <<EOF +#include <pthread.h> + +int main() +{ + pthread_attr_t attrs; + size_t size; + + int rc = pthread_attr_init(&attrs); + if (rc != 0) { + return 2; + } + + rc = pthread_attr_getstacksize(&attrs, &size); + if (rc != 0) { + return 2; + } + + if (size < 1024 * 1024) { + return 1; + } + return 0; +} +EOF + + ac_cv_thread_stack_size=unknown + if $CC -pthread $CFLAGS conftest.c -o conftest &>/dev/null; then + ./conftest &>/dev/null + exitcode=$? + if test $exitcode -eq 1; then + ac_cv_thread_stack_size=1048576 + elif test $exitcode -eq 0; then + ac_cv_thread_stack_size="default" + fi + fi + rm -f conftest.c conftest + ]) + + if test "$ac_cv_thread_stack_size" != "default" -a "$ac_cv_thread_stack_size" != "unknown"; then + LDFLAGS="$LDFLAGS -Wl,-z,stack-size=$ac_cv_thread_stack_size" + # Stack size used by Python/ceval.c to set Py_C_STACK_SIZE + AC_DEFINE_UNQUOTED([_Py_LINKER_THREAD_STACK_SIZE], [$ac_cv_thread_stack_size], + [Thread stack size set by the linker (in bytes).]) + fi +fi + +AS_CASE([$enable_wasm_dynamic_linking], + [yes], [ac_cv_func_dlopen=yes], + [no], [ac_cv_func_dlopen=no], + [missing], [] +) + +AC_SUBST([BASECFLAGS]) +AC_SUBST([CFLAGS_NODIST]) +AC_SUBST([LDFLAGS_NODIST]) +AC_SUBST([EXE_LDFLAGS]) +AC_SUBST([LDFLAGS_NOLTO]) +AC_SUBST([WASM_ASSETS_DIR]) +AC_SUBST([WASM_STDLIB]) + +# The -arch flags for universal builds on macOS +UNIVERSAL_ARCH_FLAGS= +AC_SUBST([UNIVERSAL_ARCH_FLAGS]) + +dnl PY_CHECK_CC_WARNING(ENABLE, WARNING, [MSG]) +AC_DEFUN([PY_CHECK_CC_WARNING], [ + AS_VAR_PUSHDEF([py_var], [ac_cv_$1_]m4_normalize($2)[_warning]) + AC_CACHE_CHECK([m4_ifblank([$3], [if we can $1 $CC $2 warning], [$3])], [py_var], [ + AS_VAR_COPY([py_cflags], [CFLAGS]) + AS_VAR_APPEND([CFLAGS], [" -W$2 -Werror"]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [AS_VAR_SET([py_var], [yes])], + [AS_VAR_SET([py_var], [no])]) + AS_VAR_COPY([CFLAGS], [py_cflags]) + ]) + AS_VAR_POPDEF([py_var]) +]) + +# tweak BASECFLAGS based on compiler and platform +AS_VAR_IF([with_strict_overflow], [yes], + [BASECFLAGS="$BASECFLAGS $STRICT_OVERFLOW_CFLAGS"], + [BASECFLAGS="$BASECFLAGS $NO_STRICT_OVERFLOW_CFLAGS"]) + +# Enable flags that warn and protect for potential security vulnerabilities. +# These flags should be enabled by default for all builds. + +AC_MSG_CHECKING([for --enable-safety]) +AC_ARG_ENABLE([safety], + [AS_HELP_STRING([--enable-safety], [enable usage of the security compiler options with no performance overhead])], + [AS_VAR_IF([disable_safety], [yes], [enable_safety=no], [enable_safety=yes])], [enable_safety=no]) +AC_MSG_RESULT([$enable_safety]) + +if test "$enable_safety" = "yes" +then + AX_CHECK_COMPILE_FLAG([-fstack-protector-strong], [CFLAGS_NODIST="$CFLAGS_NODIST -fstack-protector-strong"], [AC_MSG_WARN([-fstack-protector-strong not supported])], [-Werror]) + AX_CHECK_COMPILE_FLAG([-Wtrampolines], [CFLAGS_NODIST="$CFLAGS_NODIST -Wtrampolines"], [AC_MSG_WARN([-Wtrampolines not supported])], [-Werror]) + AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough], [CFLAGS_NODIST="$CFLAGS_NODIST -Wimplicit-fallthrough"], [AC_MSG_WARN([-Wimplicit-fallthrough not supported])], [-Werror]) + AX_CHECK_COMPILE_FLAG([-Werror=format-security], [CFLAGS_NODIST="$CFLAGS_NODIST -Werror=format-security"], [AC_MSG_WARN([-Werror=format-security not supported])], [-Werror]) + AX_CHECK_COMPILE_FLAG([-Wbidi-chars=any], [CFLAGS_NODIST="$CFLAGS_NODIST -Wbidi-chars=any"], [AC_MSG_WARN([-Wbidi-chars=any not supported])], [-Werror]) + AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS_NODIST="$CFLAGS_NODIST -Wall"], [AC_MSG_WARN([-Wall not supported])], [-Werror]) +fi + +AC_MSG_CHECKING([for --enable-slower-safety]) +AC_ARG_ENABLE([slower-safety], + [AS_HELP_STRING([--enable-slower-safety], [enable usage of the security compiler options with performance overhead])], + [AS_VAR_IF([disable_slower_safety], [yes], [enable_slower_safety=no], [enable_slower_safety=yes])], [enable_slower_safety=no]) +AC_MSG_RESULT([$enable_slower_safety]) + +if test "$enable_slower_safety" = "yes" +then + AX_CHECK_COMPILE_FLAG([-D_FORTIFY_SOURCE=3], [CFLAGS_NODIST="$CFLAGS_NODIST -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3"], [AC_MSG_WARN([-D_FORTIFY_SOURCE=3 not supported])], [-Werror]) +fi + +AC_MSG_CHECKING([whether to build with frame pointers]) +AC_ARG_WITH([frame-pointers], + [AS_HELP_STRING([--without-frame-pointers], + [build without frame pointers (default is no)])], + [], + [with_frame_pointers=yes]) +AC_MSG_RESULT([$with_frame_pointers]) + +AS_VAR_IF([ac_cv_gcc_compat], [yes], [ + dnl Keep frame pointers in CPython, stdlib objects, and third-party + dnl extensions built against this Python (BASECFLAGS propagates via + dnl sysconfig) so native profilers can unwind interpreter frames and + dnl generated trampolines without DWARF. + frame_pointer_cflags= + AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [ + frame_pointer_cflags="-fno-omit-frame-pointer" + AX_CHECK_COMPILE_FLAG([-mno-omit-leaf-frame-pointer], [ + frame_pointer_cflags="$frame_pointer_cflags -mno-omit-leaf-frame-pointer" + ], [], [-Werror]) + AS_CASE([$host_cpu], [arm|armv*], [ + dnl GCC uses "-marm"; clang uses "-mno-thumb" + AX_CHECK_COMPILE_FLAG([-marm], [ + frame_pointer_cflags="$frame_pointer_cflags -marm" + ], [], [-Werror]) + AX_CHECK_COMPILE_FLAG([-mno-thumb], [ + frame_pointer_cflags="$frame_pointer_cflags -mno-thumb" + ], [], [-Werror]) + ]) + AS_CASE([$host_cpu], [powerpc64le], [ + frame_pointer_cflags="" + ]) + AS_CASE([$host_cpu], [s390*], [ + AX_CHECK_COMPILE_FLAG([-mbackchain], [ + dnl Do not use no-omit-frame-pointer; see gh-149362 + frame_pointer_cflags="-mbackchain" + ], [], [-Werror]) + ]) + ], [], [-Werror]) + if test -n "$frame_pointer_cflags" && test "x$with_frame_pointers" != xno; then + BASECFLAGS="$frame_pointer_cflags $BASECFLAGS" + AC_DEFINE([_Py_WITH_FRAME_POINTERS], [1], + [Define to 1 if frame unwinding via pointers is expected + to work, 0 if not. Leave undefined if unknown.]) + fi + + CFLAGS_NODIST="$CFLAGS_NODIST -std=c11" + + PY_CHECK_CC_WARNING([enable], [extra], [if we can add -Wextra]) + AS_VAR_IF([ac_cv_enable_extra_warning], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Wextra"]) + + # Python doesn't violate C99 aliasing rules, but older versions of + # GCC produce warnings for legal Python code. Enable + # -fno-strict-aliasing on versions of GCC that support but produce + # warnings. See Issue3326 + ac_save_cc="$CC" + CC="$CC -fno-strict-aliasing" + save_CFLAGS="$CFLAGS" + AC_CACHE_CHECK([whether $CC accepts and needs -fno-strict-aliasing], + [ac_cv_no_strict_aliasing], + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM([[]], [[]]) + ],[ + CC="$ac_save_cc -fstrict-aliasing" + CFLAGS="$CFLAGS -Werror -Wstrict-aliasing" + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM([[void f(int **x) {}]], + [[double *x; f((int **) &x);]]) + ],[ + ac_cv_no_strict_aliasing=no + ],[ + ac_cv_no_strict_aliasing=yes + ]) + ],[ + ac_cv_no_strict_aliasing=no + ])) + CFLAGS="$save_CFLAGS" + CC="$ac_save_cc" + AS_VAR_IF([ac_cv_no_strict_aliasing], [yes], + [BASECFLAGS="$BASECFLAGS -fno-strict-aliasing"]) + + # ICC doesn't recognize the option, but only emits a warning + ## XXX does it emit an unused result warning and can it be disabled? + AS_CASE(["$ac_cv_cc_name"], + [icc], [ac_cv_disable_unused_result_warning=no] + [PY_CHECK_CC_WARNING([disable], [unused-result])]) + AS_VAR_IF([ac_cv_disable_unused_result_warning], [yes], + [BASECFLAGS="$BASECFLAGS -Wno-unused-result" + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-result"]) + + PY_CHECK_CC_WARNING([disable], [unused-parameter]) + AS_VAR_IF([ac_cv_disable_unused_parameter_warning], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-parameter"]) + + PY_CHECK_CC_WARNING([disable], [int-conversion]) + AS_VAR_IF([ac_cv_disable_int_conversion], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-int-conversion"]) + + PY_CHECK_CC_WARNING([disable], [missing-field-initializers]) + AS_VAR_IF([ac_cv_disable_missing_field_initializers_warning], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-missing-field-initializers"]) + + PY_CHECK_CC_WARNING([enable], [sign-compare]) + AS_VAR_IF([ac_cv_enable_sign_compare_warning], [yes], + [BASECFLAGS="$BASECFLAGS -Wsign-compare"]) + + PY_CHECK_CC_WARNING([enable], [unreachable-code]) + # Don't enable unreachable code warning in debug mode, since it usually + # results in non-standard code paths. + # Issue #24324: Unfortunately, the unreachable code warning does not work + # correctly on gcc and has been silently removed from the compiler. + # It is supported on clang but on OS X systems gcc may be an alias + # for clang. Try to determine if the compiler is not really gcc and, + # if so, only then enable the warning. + if test $ac_cv_enable_unreachable_code_warning = yes && \ + test "$Py_DEBUG" != "true" && \ + test -z "`$CC --version 2>/dev/null | grep 'Free Software Foundation'`" + then + BASECFLAGS="$BASECFLAGS -Wunreachable-code" + else + ac_cv_enable_unreachable_code_warning=no + fi + + PY_CHECK_CC_WARNING([enable], [strict-prototypes]) + AS_VAR_IF([ac_cv_enable_strict_prototypes_warning], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Wstrict-prototypes"]) + + ac_save_cc="$CC" + CC="$CC -Werror=implicit-function-declaration" + AC_CACHE_CHECK([if we can make implicit function declaration an error in $CC], + [ac_cv_enable_implicit_function_declaration_error], + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM([[]], [[]]) + ],[ + ac_cv_enable_implicit_function_declaration_error=yes + ],[ + ac_cv_enable_implicit_function_declaration_error=no + ])) + CC="$ac_save_cc" + + AS_VAR_IF([ac_cv_enable_implicit_function_declaration_error], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Werror=implicit-function-declaration"]) + + ac_save_cc="$CC" + CC="$CC -fvisibility=hidden" + AC_CACHE_CHECK([if we can use visibility in $CC], [ac_cv_enable_visibility], + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM([[]], [[]]) + ],[ + ac_cv_enable_visibility=yes + ],[ + ac_cv_enable_visibility=no + ])) + CC="$ac_save_cc" + + AS_VAR_IF([ac_cv_enable_visibility], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -fvisibility=hidden"]) + + # if using gcc on alpha, use -mieee to get (near) full IEEE 754 + # support. Without this, treatment of subnormals doesn't follow + # the standard. + case $host in + alpha*) + BASECFLAGS="$BASECFLAGS -mieee" + ;; + esac + + case $ac_sys_system in + SCO_SV*) + BASECFLAGS="$BASECFLAGS -m486 -DSCO5" + ;; + + Darwin*) + # -Wno-long-double, -no-cpp-precomp, and -mno-fused-madd + # used to be here, but non-Apple gcc doesn't accept them. + AC_MSG_CHECKING([which compiler should be used]) + case "${UNIVERSALSDK}" in + */MacOSX10.4u.sdk) + # Build using 10.4 SDK, force usage of gcc when the + # compiler is gcc, otherwise the user will get very + # confusing error messages when building on OSX 10.6 + CC=gcc-4.0 + CPP=cpp-4.0 + ;; + esac + AC_MSG_RESULT([$CC]) + + # Error on unguarded use of new symbols, which will fail at runtime for + # users on older versions of macOS + AX_CHECK_COMPILE_FLAG([-Wunguarded-availability], + [AS_VAR_APPEND([CFLAGS_NODIST], [" -Werror=unguarded-availability"])], + [], + [-Werror]) + + LIPO_INTEL64_FLAGS="" + if test "${enable_universalsdk}" + then + case "$UNIVERSAL_ARCHS" in + 32-bit) + UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="" + ARCH_TRIPLES=`echo {ppc,i386}-apple-darwin` + ;; + 64-bit) + UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="true" + ARCH_TRIPLES=`echo {ppc64,x86_64}-apple-darwin` + ;; + all) + UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc" + ARCH_TRIPLES=`echo {i386,ppc,ppc64,x86_64}-apple-darwin` + ;; + universal2) + UNIVERSAL_ARCH_FLAGS="-arch arm64 -arch x86_64" + LIPO_32BIT_FLAGS="" + LIPO_INTEL64_FLAGS="-extract x86_64" + ARCH_RUN_32BIT="true" + ARCH_TRIPLES=`echo {aarch64,x86_64}-apple-darwin` + ;; + intel) + UNIVERSAL_ARCH_FLAGS="-arch i386 -arch x86_64" + LIPO_32BIT_FLAGS="-extract i386" + ARCH_RUN_32BIT="/usr/bin/arch -i386" + ARCH_TRIPLES=`echo {i386,x86_64}-apple-darwin` + ;; + intel-32) + UNIVERSAL_ARCH_FLAGS="-arch i386" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="" + ARCH_TRIPLES=i386-apple-darwin + ;; + intel-64) + UNIVERSAL_ARCH_FLAGS="-arch x86_64" + LIPO_32BIT_FLAGS="" + ARCH_RUN_32BIT="true" + ARCH_TRIPLES=x86_64-apple-darwin + ;; + 3-way) + UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc" + ARCH_TRIPLES=`echo {i386,ppc,x86_64}-apple-darwin` + ;; + *) + AC_MSG_ERROR([proper usage is --with-universal-arch=universal2|32-bit|64-bit|all|intel|3-way]) + ;; + esac + + if test "${UNIVERSALSDK}" != "/" + then + CFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${CFLAGS}" + LDFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${LDFLAGS}" + CPPFLAGS="-isysroot ${UNIVERSALSDK} ${CPPFLAGS}" + else + CFLAGS="${UNIVERSAL_ARCH_FLAGS} ${CFLAGS}" + LDFLAGS="${UNIVERSAL_ARCH_FLAGS} ${LDFLAGS}" + fi + fi + + # Calculate an appropriate deployment target for this build: + # The deployment target value is used explicitly to enable certain + # features are enabled (such as builtin libedit support for readline) + # through the use of Apple's Availability Macros and is used as a + # component of the string returned by distutils.get_platform(). + # + # Use the value from: + # 1. the MACOSX_DEPLOYMENT_TARGET environment variable if specified + # 2. the operating system version of the build machine if >= 10.6 + # 3. If running on OS X 10.3 through 10.5, use the legacy tests + # below to pick either 10.3, 10.4, or 10.5 as the target. + # 4. If we are running on OS X 10.2 or earlier, good luck! + + AC_MSG_CHECKING([which MACOSX_DEPLOYMENT_TARGET to use]) + cur_target_major=`sw_vers -productVersion | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + cur_target_minor=`sw_vers -productVersion | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + cur_target="${cur_target_major}.${cur_target_minor}" + if test ${cur_target_major} -eq 10 && \ + test ${cur_target_minor} -ge 3 && \ + test ${cur_target_minor} -le 5 + then + # OS X 10.3 through 10.5 + cur_target=10.3 + if test ${enable_universalsdk} + then + case "$UNIVERSAL_ARCHS" in + all|3-way|intel|64-bit) + # These configurations were first supported in 10.5 + cur_target='10.5' + ;; + esac + else + if test `/usr/bin/arch` = "i386" + then + # 10.4 was the first release to support Intel archs + cur_target="10.4" + fi + fi + fi + CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}} + + # Make sure that MACOSX_DEPLOYMENT_TARGET is set in the + # environment with a value that is the same as what we'll use + # in the Makefile to ensure that we'll get the same compiler + # environment during configure and build time. + MACOSX_DEPLOYMENT_TARGET="$CONFIGURE_MACOSX_DEPLOYMENT_TARGET" + export MACOSX_DEPLOYMENT_TARGET + EXPORT_MACOSX_DEPLOYMENT_TARGET='' + AC_MSG_RESULT([$MACOSX_DEPLOYMENT_TARGET]) + + AC_MSG_CHECKING([if specified universal architectures work]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <stdio.h>]], [[printf("%d", 42);]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([check config.log and use the '--with-universal-archs' option]) + ]) + + # end of Darwin* tests + ;; + esac +], [ + case $ac_sys_system in + OpenUNIX*|UnixWare*) + BASECFLAGS="$BASECFLAGS -K pentium,host,inline,loop_unroll,alloca " + ;; + SCO_SV*) + BASECFLAGS="$BASECFLAGS -belf -Ki486 -DSCO5" + ;; + esac +]) + +# Check for --enable-experimental-jit: +AC_MSG_CHECKING([for --enable-experimental-jit]) +AC_ARG_ENABLE([experimental-jit], + [AS_HELP_STRING([--enable-experimental-jit@<:@=no|yes|yes-off|interpreter@:>@], + [build the experimental just-in-time compiler (default is no)])], + [], + [enable_experimental_jit=no]) +case $enable_experimental_jit in + no) jit_flags=""; tier2_flags="" ;; + yes) jit_flags="-D_Py_JIT"; tier2_flags="-D_Py_TIER2=1" ;; + yes-off) jit_flags="-D_Py_JIT"; tier2_flags="-D_Py_TIER2=3" ;; + interpreter) jit_flags=""; tier2_flags="-D_Py_TIER2=4" ;; + interpreter-off) jit_flags=""; tier2_flags="-D_Py_TIER2=6" ;; # Secret option + *) AC_MSG_ERROR( + [invalid argument: --enable-experimental-jit=$enable_experimental_jit; expected no|yes|yes-off|interpreter]) ;; +esac +AS_VAR_IF([tier2_flags], + [], + [], + [AS_VAR_APPEND([CFLAGS_NODIST], [" $tier2_flags"])]) +AS_VAR_IF([jit_flags], + [], + [], + [AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"]) + AS_VAR_SET([REGEN_JIT_COMMAND], + ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\" --llvm-version=\"$LLVM_VERSION\" --llvm-tools-install-dir=\"$LLVM_TOOLS_INSTALL_DIR\""]) + AS_VAR_IF([Py_DEBUG], + [true], + [AS_VAR_APPEND([REGEN_JIT_COMMAND], [" --debug"])], + [])]) +AC_SUBST([REGEN_JIT_COMMAND]) +AC_MSG_RESULT([$tier2_flags $jit_flags]) + +if test "$disable_gil" = "yes" -a "$enable_experimental_jit" != "no"; then + # GH-133171: This configuration builds the JIT but never actually uses it, + # which is surprising (and strictly worse than not building it at all): + AC_MSG_WARN([--enable-experimental-jit does not work correctly with --disable-gil.]) +fi + +case "$ac_cv_cc_name" in +mpicc) + CFLAGS_NODIST="$CFLAGS_NODIST" + ;; +icx) + # ICX needs fp-model=precise (the default in clang) or floats behave badly + CFLAGS_NODIST="$CFLAGS_NODIST -ffp-model=precise" + ;; +icc) + # ICC needs -fp-model strict or floats behave badly + CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" + ;; +xlc) + CFLAGS_NODIST="$CFLAGS_NODIST -qalias=noansi -qmaxmem=-1" + ;; +esac + +if test "$assertions" = 'true'; then + : +else + OPT="-DNDEBUG $OPT" +fi + +if test "$ac_arch_flags" +then + BASECFLAGS="$BASECFLAGS $ac_arch_flags" +fi + +# On some compilers, pthreads are available without further options +# (e.g. MacOS X). On some of these systems, the compiler will not +# complain if unaccepted options are passed (e.g. gcc on Mac OS X). +# So we have to see first whether pthreads are available without +# options before we can check whether -Kpthread improves anything. +AC_CACHE_CHECK([whether pthreads are available without options], + [ac_cv_pthread_is_default], +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} +]])],[ + ac_cv_pthread_is_default=yes + ac_cv_kthread=no + ac_cv_pthread=no +],[ac_cv_pthread_is_default=no],[ac_cv_pthread_is_default=no]) +]) + + +if test $ac_cv_pthread_is_default = yes +then + ac_cv_kpthread=no +else +# -Kpthread, if available, provides the right #defines +# and linker options to make pthread_create available +# Some compilers won't report that they do not support -Kpthread, +# so we need to run a program to see whether it really made the +# function available. +AC_CACHE_CHECK([whether $CC accepts -Kpthread], [ac_cv_kpthread], +[ac_save_cc="$CC" +CC="$CC -Kpthread" +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} +]])],[ac_cv_kpthread=yes],[ac_cv_kpthread=no],[ac_cv_kpthread=no]) +CC="$ac_save_cc"]) +fi + +if test $ac_cv_kpthread = no -a $ac_cv_pthread_is_default = no +then +# -Kthread, if available, provides the right #defines +# and linker options to make pthread_create available +# Some compilers won't report that they do not support -Kthread, +# so we need to run a program to see whether it really made the +# function available. +AC_CACHE_CHECK([whether $CC accepts -Kthread], [ac_cv_kthread], +[ac_save_cc="$CC" +CC="$CC -Kthread" +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} +]])],[ac_cv_kthread=yes],[ac_cv_kthread=no],[ac_cv_kthread=no]) +CC="$ac_save_cc"]) +fi + +if test $ac_cv_kthread = no -a $ac_cv_pthread_is_default = no +then +# -pthread, if available, provides the right #defines +# and linker options to make pthread_create available +# Some compilers won't report that they do not support -pthread, +# so we need to run a program to see whether it really made the +# function available. +AC_CACHE_CHECK([whether $CC accepts -pthread], [ac_cv_pthread], +[ac_save_cc="$CC" +CC="$CC -pthread" +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdio.h> +#include <pthread.h> + +void* routine(void* p){return NULL;} + +int main(void){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + (void)pthread_detach(p); + return 0; +} +]])],[ac_cv_pthread=yes],[ac_cv_pthread=no],[ac_cv_pthread=no]) +CC="$ac_save_cc"]) +fi + +# If we have set a CC compiler flag for thread support then +# check if it works for CXX, too. +if test ! -z "$CXX" +then +AC_CACHE_CHECK([whether $CXX also accepts flags for thread support], [ac_cv_cxx_thread], +[ac_save_cxx="$CXX" + +if test "$ac_cv_kpthread" = "yes" +then + CXX="$CXX -Kpthread" + ac_cv_cxx_thread=yes +elif test "$ac_cv_kthread" = "yes" +then + CXX="$CXX -Kthread" + ac_cv_cxx_thread=yes +elif test "$ac_cv_pthread" = "yes" +then + CXX="$CXX -pthread" + ac_cv_cxx_thread=yes +else + ac_cv_cxx_thread=no +fi + +if test $ac_cv_cxx_thread = yes +then + echo 'void foo();int main(){foo();}void foo(){}' > conftest.$ac_ext + $CXX -c conftest.$ac_ext 2>&5 + if $CXX -o conftest$ac_exeext conftest.$ac_objext 2>&5 \ + && test -s conftest$ac_exeext && ./conftest$ac_exeext + then + ac_cv_cxx_thread=yes + else + ac_cv_cxx_thread=no + fi + rm -fr conftest* +fi +CXX="$ac_save_cxx"]) +else + ac_cv_cxx_thread=no +fi + +dnl # check for ANSI or K&R ("traditional") preprocessor +dnl AC_MSG_CHECKING(for C preprocessor type) +dnl AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +dnl #define spam(name, doc) {#name, &name, #name "() -- " doc} +dnl int foo; +dnl struct {char *name; int *addr; char *doc;} desc = spam(foo, "something"); +dnl ]], [[;]])],[cpp_type=ansi],[AC_DEFINE(HAVE_OLD_CPP) cpp_type=traditional]) +dnl AC_MSG_RESULT($cpp_type) + +dnl autoconf 2.71 deprecates STDC_HEADERS, keep for backwards compatibility +dnl assume C99 compilers provide ANSI C headers +AC_DEFINE([STDC_HEADERS], [1], + [Define to 1 if you have the ANSI C header files.]) + +# checks for header files +AC_CHECK_HEADERS([ \ + alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ + io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \ + linux/netfilter_ipv4.h linux/random.h linux/soundcard.h linux/sched.h \ + linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ + sched.h setjmp.h shadow.h signal.h spawn.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ + sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ + sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/pidfd.h sys/poll.h \ + sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ + sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysctl.h \ + sys/sysmacros.h sys/termio.h sys/time.h sys/times.h sys/timerfd.h \ + sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \ + termios.h util.h utime.h utmp.h \ +]) +AC_HEADER_DIRENT +AC_HEADER_MAJOR + +# On Linux, stropts.h may be empty +AC_CHECK_DECL([I_PUSH], [ + AC_DEFINE([HAVE_STROPTS_H], [1], + [Define to 1 if you have the <stropts.h> header file.])], [], [ + #ifdef HAVE_SYS_TYPES_H + # include <sys/types.h> + #endif + #include <stropts.h> +]) + +# bluetooth/bluetooth.h has been known to not compile with -std=c99. +# http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 +SAVE_CFLAGS=$CFLAGS +CFLAGS="-std=c99 $CFLAGS" +AC_CHECK_HEADERS([bluetooth/bluetooth.h]) +CFLAGS=$SAVE_CFLAGS + +# On Darwin (OS X) net/if.h requires sys/socket.h to be imported first. +AC_CHECK_HEADERS([net/if.h], [], [], +[#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +#endif +]) + +# On Linux, netlink.h requires asm/types.h +# On FreeBSD, netlink.h is located in netlink/netlink.h +AC_CHECK_HEADERS([linux/netlink.h netlink/netlink.h], [], [], [ +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +]) + +# On Linux, qrtr.h requires asm/types.h +AC_CHECK_HEADERS([linux/qrtr.h], [], [], [ +#ifdef HAVE_ASM_TYPES_H +#include <asm/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +]) + +AC_CHECK_HEADERS([linux/vm_sockets.h], [], [], [ +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +]) + +# On Linux, can.h, can/bcm.h, can/isotp.h, can/j1939.h, can/raw.h require sys/socket.h +# On NetBSD, netcan/can.h requires sys/socket.h +AC_CHECK_HEADERS( +[linux/can.h linux/can/bcm.h linux/can/isotp.h linux/can/j1939.h linux/can/raw.h netcan/can.h], +[], [], [ +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +]) + +# Check for clock_t in time.h. +AC_CHECK_TYPES([clock_t], [], + [AC_DEFINE([clock_t], [long], + [Define to 'long' if <time.h> does not define clock_t.])], + [@%:@include <time.h>]) + +AC_CACHE_CHECK([for makedev], [ac_cv_func_makedev], [ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if defined(MAJOR_IN_MKDEV) +#include <sys/mkdev.h> +#elif defined(MAJOR_IN_SYSMACROS) +#include <sys/sysmacros.h> +#else +#include <sys/types.h> +#endif +]], [[ + makedev(0, 0) ]]) +],[ac_cv_func_makedev=yes],[ac_cv_func_makedev=no]) +]) + +AS_VAR_IF([ac_cv_func_makedev], [yes], [ + AC_DEFINE([HAVE_MAKEDEV], [1], + [Define this if you have the makedev macro.]) +]) + +# byte swapping +AC_CACHE_CHECK([for le64toh], [ac_cv_func_le64toh], [ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#elif defined(HAVE_SYS_ENDIAN_H) +#include <sys/endian.h> +#endif +]], [[ + le64toh(1) ]]) +],[ac_cv_func_le64toh=yes],[ac_cv_func_le64toh=no]) +]) + +AS_VAR_IF([ac_cv_func_le64toh], [yes], [ + AC_DEFINE([HAVE_HTOLE64], [1], + [Define this if you have le64toh()]) +]) + +use_lfs=yes +# Don't use largefile support for GNU/Hurd +case $ac_sys_system in GNU*) + use_lfs=no +esac + +if test "$use_lfs" = "yes"; then +# Two defines needed to enable largefile support on various platforms +# These may affect some typedefs +case $ac_sys_system/$ac_sys_release in +AIX*) + AC_DEFINE([_LARGE_FILES], [1], + [This must be defined on AIX systems to enable large file support.]) + ;; +esac +AC_DEFINE([_LARGEFILE_SOURCE], [1], +[This must be defined on some systems to enable large file support.]) +AC_DEFINE([_FILE_OFFSET_BITS], [64], +[This must be set to 64 on some systems to enable large file support.]) +fi + +# Add some code to confdefs.h so that the test for off_t works on SCO +cat >> confdefs.h <<\EOF +#if defined(SCO_DS) +#undef _OFF_T +#endif +EOF + +# Type availability checks +AC_TYPE_MODE_T +AC_TYPE_OFF_T +AC_TYPE_PID_T +AC_DEFINE_UNQUOTED([RETSIGTYPE],[void],[assume C89 semantics that RETSIGTYPE is always void]) +AC_TYPE_SIZE_T +AC_TYPE_UID_T + +AC_CHECK_TYPES([ssize_t]) +AC_CHECK_TYPES([__uint128_t], + [AC_DEFINE([HAVE_GCC_UINT128_T], [1], + [Define if your compiler provides __uint128_t])]) + +# Sizes and alignments of various common basic types +# ANSI C requires sizeof(char) == 1, so no need to check it +AC_CHECK_SIZEOF([int], [4]) +AC_CHECK_SIZEOF([long], [4]) +AC_CHECK_ALIGNOF([long]) +AC_CHECK_SIZEOF([long long], [8]) +AC_CHECK_SIZEOF([void *], [4]) +AC_CHECK_SIZEOF([short], [2]) +AC_CHECK_SIZEOF([float], [4]) +AC_CHECK_SIZEOF([double], [8]) +AC_CHECK_SIZEOF([fpos_t], [4]) +AC_CHECK_SIZEOF([size_t], [4]) +AC_CHECK_ALIGNOF([size_t]) +AC_CHECK_SIZEOF([pid_t], [4]) +AC_CHECK_SIZEOF([uintptr_t]) +AC_CHECK_ALIGNOF([max_align_t]) + +AC_TYPE_LONG_DOUBLE +AC_CHECK_SIZEOF([long double], [16]) + +AC_CHECK_SIZEOF([_Bool], [1]) + +AC_CHECK_SIZEOF([off_t], [], [ +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +]) + +AC_MSG_CHECKING([whether to enable large file support]) +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ + "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then + have_largefile_support="yes" +else + have_largefile_support="no" +fi +AS_VAR_IF([have_largefile_support], [yes], [ + AC_DEFINE([HAVE_LARGEFILE_SUPPORT], [1], + [Defined to enable large file support when an off_t is bigger than a long + and long long is at least as big as an off_t. You may need + to add some flags for configuration and compilation to enable this mode. + (For Solaris and Linux, the necessary defines are already defined.)]) + AC_MSG_RESULT([yes]) +], [ + AC_MSG_RESULT([no]) +]) + +AC_CHECK_SIZEOF([time_t], [], [ +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_TIME_H +#include <time.h> +#endif +]) + +# if have pthread_t then define SIZEOF_PTHREAD_T +ac_save_cc="$CC" +if test "$ac_cv_kpthread" = "yes" +then CC="$CC -Kpthread" +elif test "$ac_cv_kthread" = "yes" +then CC="$CC -Kthread" +elif test "$ac_cv_pthread" = "yes" +then CC="$CC -pthread" +fi + +AC_CACHE_CHECK([for pthread_t], [ac_cv_have_pthread_t], [ +AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[@%:@include <pthread.h>]], [[pthread_t x; x = *(pthread_t*)0;]]) +], [ac_cv_have_pthread_t=yes], [ac_cv_have_pthread_t=no]) +]) +AS_VAR_IF([ac_cv_have_pthread_t], [yes], [ + AC_CHECK_SIZEOF([pthread_t], [], [ +#ifdef HAVE_PTHREAD_H +#include <pthread.h> +#endif + ]) +]) + +# Issue #25658: POSIX hasn't defined that pthread_key_t is compatible with int. +# This checking will be unnecessary after removing deprecated TLS API. +AC_CHECK_SIZEOF([pthread_key_t], [], [[@%:@include <pthread.h>]]) +AC_CACHE_CHECK([whether pthread_key_t is compatible with int], [ac_cv_pthread_key_t_is_arithmetic_type], [ +if test "$ac_cv_sizeof_pthread_key_t" -eq "$ac_cv_sizeof_int" ; then + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[@%:@include <pthread.h>]], [[pthread_key_t k; k * 1;]])], + [ac_cv_pthread_key_t_is_arithmetic_type=yes], + [ac_cv_pthread_key_t_is_arithmetic_type=no] + ) +else + ac_cv_pthread_key_t_is_arithmetic_type=no +fi +]) +AS_VAR_IF([ac_cv_pthread_key_t_is_arithmetic_type], [yes], [ + AC_DEFINE([PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT], [1], + [Define if pthread_key_t is compatible with int.]) +]) + +CC="$ac_save_cc" + +AC_MSG_CHECKING([for --enable-framework]) +if test "$enable_framework" +then + BASECFLAGS="$BASECFLAGS -fno-common -dynamic" + # -F. is needed to allow linking to the framework while + # in the build location. + AC_DEFINE([WITH_NEXT_FRAMEWORK], [1], + [Define if you want to produce an OpenStep/Rhapsody framework + (shared library plus accessory files).]) + AC_MSG_RESULT([yes]) + if test $enable_shared = "yes" + then + AC_MSG_ERROR([Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead]) + fi +else + AC_MSG_RESULT([no]) +fi + +# Check for --with-dsymutil +AC_SUBST([DSYMUTIL]) +AC_SUBST([DSYMUTIL_PATH]) +DSYMUTIL= +DSYMUTIL_PATH= +AC_MSG_CHECKING([for --with-dsymutil]) +AC_ARG_WITH( + [dsymutil], + [AS_HELP_STRING( + [--with-dsymutil], + [link debug information into final executable with dsymutil in macOS (default is no)] + )], +[ +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + AC_MSG_ERROR([dsymutil debug linking is only available in macOS.]) + fi + AC_MSG_RESULT([yes]); + DSYMUTIL='true' +else AC_MSG_RESULT([no]); DSYMUTIL= +fi], +[AC_MSG_RESULT([no])]) + +if test "$DSYMUTIL"; then + AC_PATH_PROG([DSYMUTIL_PATH], [dsymutil], [not found]) + if test "$DSYMUTIL_PATH" = "not found"; then + AC_MSG_ERROR([dsymutil command not found on \$PATH]) + fi +fi + +AC_MSG_CHECKING([for dyld]) +case $ac_sys_system/$ac_sys_release in + Darwin/*) + AC_DEFINE([WITH_DYLD], [1], + [Define if you want to use the new-style (Openstep, Rhapsody, MacOS) + dynamic linker (dyld) instead of the old-style (NextStep) dynamic + linker (rld). Dyld is necessary to support frameworks.]) + AC_MSG_RESULT([always on for Darwin]) + ;; + *) + AC_MSG_RESULT([no]) + ;; +esac + +AC_MSG_CHECKING([for --with-address-sanitizer]) +AC_ARG_WITH([address_sanitizer], + AS_HELP_STRING([--with-address-sanitizer], + [enable AddressSanitizer memory error detector, 'asan' (default is no)]), +[ +AC_MSG_RESULT([$withval]) +BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS" +LDFLAGS="-fsanitize=address $LDFLAGS" +# ASan works by controlling memory allocation, our own malloc interferes. +with_pymalloc="no" +], +[AC_MSG_RESULT([no])]) + +AC_MSG_CHECKING([for --with-memory-sanitizer]) +AC_ARG_WITH( + [memory_sanitizer], + [AS_HELP_STRING( + [--with-memory-sanitizer], + [enable MemorySanitizer allocation error detector, 'msan' (default is no)] + )], +[ +AC_MSG_RESULT([$withval]) +AX_CHECK_COMPILE_FLAG([-fsanitize=memory],[ +BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS" +LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" +],[AC_MSG_ERROR([The selected compiler doesn't support memory sanitizer])]) +# MSan works by controlling memory allocation, our own malloc interferes. +with_pymalloc="no" +], +[AC_MSG_RESULT([no])]) + +AC_MSG_CHECKING([for --with-undefined-behavior-sanitizer]) +AC_ARG_WITH( + [undefined_behavior_sanitizer], + [AS_HELP_STRING( + [--with-undefined-behavior-sanitizer], + [enable UndefinedBehaviorSanitizer undefined behaviour detector, 'ubsan' (default is no)] + )], +[ +AC_MSG_RESULT([$withval]) +BASECFLAGS="-fsanitize=undefined $BASECFLAGS" +LDFLAGS="-fsanitize=undefined $LDFLAGS" +with_ubsan="yes" +], +[ +AC_MSG_RESULT([no]) +with_ubsan="no" +]) + +AC_MSG_CHECKING([for --with-thread-sanitizer]) +AC_ARG_WITH( + [thread_sanitizer], + [AS_HELP_STRING( + [--with-thread-sanitizer], + [enable ThreadSanitizer data race detector, 'tsan' (default is no)] + )], +[ +AC_MSG_RESULT([$withval]) +BASECFLAGS="-fsanitize=thread $BASECFLAGS" +LDFLAGS="-fsanitize=thread $LDFLAGS" +with_tsan="yes" +], +[ +AC_MSG_RESULT([no]) +with_tsan="no" +]) + +# Set info about shared libraries. +AC_SUBST([SHLIB_SUFFIX]) +AC_SUBST([LDSHARED]) +AC_SUBST([LDCXXSHARED]) +AC_SUBST([BLDSHARED]) +AC_SUBST([CCSHARED]) +AC_SUBST([LINKFORSHARED]) + +# SHLIB_SUFFIX is the extension of shared libraries `(including the dot!) +# -- usually .so, .sl on HP-UX, .dll on Cygwin +AC_MSG_CHECKING([the extension of shared libraries]) +if test -z "$SHLIB_SUFFIX"; then + case $ac_sys_system in + hp*|HP*) + case `uname -m` in + ia64) SHLIB_SUFFIX=.so;; + *) SHLIB_SUFFIX=.sl;; + esac + ;; + CYGWIN*) SHLIB_SUFFIX=.dll;; + *) SHLIB_SUFFIX=.so;; + esac +fi +AC_MSG_RESULT([$SHLIB_SUFFIX]) + +# LDSHARED is the ld *command* used to create shared library +# -- "cc -G" on SunOS 5.x. +# (Shared libraries in this instance are shared modules to be loaded into +# Python, as opposed to building Python itself as a shared library.) +AC_MSG_CHECKING([LDSHARED]) +if test -z "$LDSHARED" +then + case $ac_sys_system/$ac_sys_release in + AIX*) + BLDSHARED="Modules/ld_so_aix \$(CC) -bI:Modules/python.exp" + LDSHARED="\$(LIBPL)/ld_so_aix \$(CC) -bI:\$(LIBPL)/python.exp" + ;; + SunOS/5*) + if test "$ac_cv_gcc_compat" = "yes" ; then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED='$(CC) -G' + LDCXXSHARED='$(CXX) -G' + fi ;; + hp*|HP*) + if test "$ac_cv_gcc_compat" = "yes" ; then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED='$(CC) -b' + LDCXXSHARED='$(CXX) -b' + fi ;; + Darwin/1.3*) + LDSHARED='$(CC) -bundle' + LDCXXSHARED='$(CXX) -bundle' + if test "$enable_framework" ; then + # Link against the framework. All externals should be defined. + BLDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDCXXSHARED="$LDCXXSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + else + # No framework. Ignore undefined symbols, assuming they come from Python + LDSHARED="$LDSHARED -undefined suppress" + LDCXXSHARED="$LDCXXSHARED -undefined suppress" + fi ;; + Darwin/1.4*|Darwin/5.*|Darwin/6.*) + LDSHARED='$(CC) -bundle' + LDCXXSHARED='$(CXX) -bundle' + if test "$enable_framework" ; then + # Link against the framework. All externals should be defined. + BLDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDSHARED="$LDSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LDCXXSHARED="$LDCXXSHARED "'$(PYTHONFRAMEWORKPREFIX)/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + else + # No framework, use the Python app as bundle-loader + BLDSHARED="$LDSHARED "'-bundle_loader $(BUILDPYTHON)' + LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)' + LDCXXSHARED="$LDCXXSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)' + fi ;; + Darwin/*) + # Use -undefined dynamic_lookup whenever possible (10.3 and later). + # This allows an extension to be used in any Python + + dep_target_major=`echo ${MACOSX_DEPLOYMENT_TARGET} | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + dep_target_minor=`echo ${MACOSX_DEPLOYMENT_TARGET} | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + if test ${dep_target_major} -eq 10 && \ + test ${dep_target_minor} -le 2 + then + # building for OS X 10.0 through 10.2 + AC_MSG_ERROR([MACOSX_DEPLOYMENT_TARGET too old ($MACOSX_DEPLOYMENT_TARGET), only 10.3 or later is supported]) + else + # building for OS X 10.3 and later + LDSHARED='$(CC) -bundle -undefined dynamic_lookup' + LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup' + BLDSHARED="$LDSHARED" + fi + ;; + iOS/*) + LDSHARED='$(CC) -dynamiclib -F . -framework $(PYTHONFRAMEWORK)' + LDCXXSHARED='$(CXX) -dynamiclib -F . -framework $(PYTHONFRAMEWORK)' + BLDSHARED="$LDSHARED" + ;; + Emscripten*|WASI*) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; + Linux*|GNU*|QNX*|VxWorks*|Haiku*) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; + FreeBSD*) + if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]] + then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED="ld -Bshareable" + fi;; + OpenBSD*) + if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]] + then + LDSHARED='$(CC) -shared $(CCSHARED)' + LDCXXSHARED='$(CXX) -shared $(CCSHARED)' + else + case `uname -r` in + [[01]].* | 2.[[0-7]] | 2.[[0-7]].*) + LDSHARED="ld -Bshareable ${LDFLAGS}" + ;; + *) + LDSHARED='$(CC) -shared $(CCSHARED)' + LDCXXSHARED='$(CXX) -shared $(CCSHARED)' + ;; + esac + fi;; + NetBSD*|DragonFly*) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; + OpenUNIX*|UnixWare*) + if test "$ac_cv_gcc_compat" = "yes" ; then + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared' + else + LDSHARED='$(CC) -G' + LDCXXSHARED='$(CXX) -G' + fi;; + SCO_SV*) + LDSHARED='$(CC) -Wl,-G,-Bexport' + LDCXXSHARED='$(CXX) -Wl,-G,-Bexport';; + WASI*) + AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + dnl not implemented yet + ]);; + CYGWIN*) + LDSHARED='$(CC) -shared -Wl,--enable-auto-image-base' + LDCXXSHARED='$(CXX) -shared -Wl,--enable-auto-image-base';; + *) LDSHARED="ld";; + esac +fi + +dnl Emscripten's emconfigure sets LDSHARED. Set BLDSHARED outside the +dnl test -z $LDSHARED block to configure BLDSHARED for side module support. +if test "$enable_wasm_dynamic_linking" = "yes" -a "$ac_sys_system" = "Emscripten"; then + BLDSHARED='$(CC) -shared -sSIDE_MODULE=1' +fi + +AC_MSG_RESULT([$LDSHARED]) +LDCXXSHARED=${LDCXXSHARED-$LDSHARED} + +AC_MSG_CHECKING([BLDSHARED flags]) +BLDSHARED=${BLDSHARED-$LDSHARED} +AC_MSG_RESULT([$BLDSHARED]) + +# CCSHARED are the C *flags* used to create objects to go into a shared +# library (module) -- this is only needed for a few systems +AC_MSG_CHECKING([CCSHARED]) +if test -z "$CCSHARED" +then + case $ac_sys_system/$ac_sys_release in + SunOS*) if test "$ac_cv_gcc_compat" = "yes"; + then CCSHARED="-fPIC"; + elif test `uname -p` = sparc; + then CCSHARED="-xcode=pic32"; + else CCSHARED="-Kpic"; + fi;; + hp*|HP*) if test "$ac_cv_gcc_compat" = "yes"; + then CCSHARED="-fPIC"; + else CCSHARED="+z"; + fi;; + Linux*|GNU*) CCSHARED="-fPIC";; + Emscripten*|WASI*) + AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + CCSHARED="-fPIC" + ]);; + FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) CCSHARED="-fPIC";; + Haiku*) CCSHARED="-fPIC";; + OpenUNIX*|UnixWare*) + if test "$ac_cv_gcc_compat" = "yes" + then CCSHARED="-fPIC" + else CCSHARED="-KPIC" + fi;; + SCO_SV*) + if test "$ac_cv_gcc_compat" = "yes" + then CCSHARED="-fPIC" + else CCSHARED="-Kpic -belf" + fi;; + VxWorks*) + CCSHARED="-fpic -D__SO_PICABILINUX__ -ftls-model=global-dynamic" + esac +fi +AC_MSG_RESULT([$CCSHARED]) +# LINKFORSHARED are the flags passed to the $(CC) command that links +# the python executable -- this is only needed for a few systems +AC_MSG_CHECKING([LINKFORSHARED]) +if test -z "$LINKFORSHARED" +then + case $ac_sys_system/$ac_sys_release in + AIX*) LINKFORSHARED='-Wl,-bE:Modules/python.exp -lld';; + hp*|HP*) + LINKFORSHARED="-Wl,-E -Wl,+s";; +# LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";; + Linux-android*) LINKFORSHARED="-pie -Xlinker -export-dynamic";; + Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";; + # -u libsys_s pulls in all symbols in libsys + Darwin/*|iOS/*) + LINKFORSHARED="$extra_undefs -framework CoreFoundation" + + # Issue #18075: the default maximum stack size (8MBytes) is too + # small for the default recursion limit. Increase the stack size + # to ensure that tests don't crash + stack_size="1000000" # 16 MB + if test "$with_ubsan" = "yes" + then + # Undefined behavior sanitizer requires an even deeper stack + stack_size="4000000" # 64 MB + fi + + AC_DEFINE_UNQUOTED([THREAD_STACK_SIZE], + [0x$stack_size], + [Custom thread stack size depending on chosen sanitizer runtimes.]) + + if test $ac_sys_system = "Darwin"; then + LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" + + if test "$enable_framework"; then + LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + fi + LINKFORSHARED="$LINKFORSHARED" + elif test $ac_sys_system = "iOS"; then + LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)' + fi + ;; + OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";; + SCO_SV*) LINKFORSHARED="-Wl,-Bexport";; + ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; + FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) + if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]] + then + LINKFORSHARED="-Wl,--export-dynamic" + fi;; + SunOS/5*) if test "$ac_cv_gcc_compat" = "yes"; then + if $CC -Xlinker --help 2>&1 | grep export-dynamic >/dev/null + then + LINKFORSHARED="-Xlinker --export-dynamic" + fi + fi + ;; + CYGWIN*) + if test $enable_shared = "no" + then + LINKFORSHARED='-Wl,--out-implib=$(LDLIBRARY)' + fi;; + QNX*) + # -Wl,-E causes the symbols to be added to the dynamic + # symbol table so that they can be found when a module + # is loaded. -N 2048K causes the stack size to be set + # to 2048 kilobytes so that the stack doesn't overflow + # when running test_compile.py. + LINKFORSHARED='-Wl,-E -N 2048K';; + VxWorks*) + LINKFORSHARED='-Wl,-export-dynamic';; + esac +fi +AC_MSG_RESULT([$LINKFORSHARED]) + + +AC_SUBST([CFLAGSFORSHARED]) +AC_MSG_CHECKING([CFLAGSFORSHARED]) +if test ! "$LIBRARY" = "$LDLIBRARY" +then + case $ac_sys_system in + CYGWIN*) + # Cygwin needs CCSHARED when building extension DLLs + # but not when building the interpreter DLL. + CFLAGSFORSHARED='';; + *) + CFLAGSFORSHARED='$(CCSHARED)' + esac +fi + +dnl WASM dynamic linking requires -fPIC. +AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + CFLAGSFORSHARED='$(CCSHARED)' +]) + +AC_MSG_RESULT([$CFLAGSFORSHARED]) + +# SHLIBS are libraries (except -lc and -lm) to link to the python shared +# library (with --enable-shared). +# For platforms on which shared libraries are not allowed to have unresolved +# symbols, this must be set to $(LIBS) (expanded by make). We do this even +# if it is not required, since it creates a dependency of the shared library +# to LIBS. This, in turn, means that applications linking the shared libpython +# don't need to link LIBS explicitly. The default should be only changed +# on systems where this approach causes problems. +AC_SUBST([SHLIBS]) +AC_MSG_CHECKING([SHLIBS]) +case "$ac_sys_system" in + *) + SHLIBS='$(LIBS)';; +esac +AC_MSG_RESULT([$SHLIBS]) + +dnl perf trampoline is Linux and macOS specific and requires an arch-specific +dnl trampoline in assembly. +AC_MSG_CHECKING([perf trampoline]) +PERF_TRAMPOLINE_OBJ="" +AS_CASE([$PLATFORM_TRIPLET], + [x86_64-linux-gnu], [perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_x86_64.o], + [x86_64-linux-musl], [perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_x86_64.o], + [aarch64-linux-gnu], [perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_aarch64.o], + [aarch64-linux-musl], [perf_trampoline=yes + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_aarch64.o], + [darwin], [AS_CASE([$MACOSX_DEPLOYMENT_TARGET], + [[10.[0-9]|10.1[0-1]]], [perf_trampoline=no], + [perf_trampoline=yes + if test "${enable_universalsdk}" && test "$UNIVERSAL_ARCHS" = "universal2"; then + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_universal2.o + else + case "$host_cpu" in + x86_64) + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_x86_64.o + ;; + aarch64|arm64) + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline_aarch64.o + ;; + *) + perf_trampoline=no + ;; + esac + fi] + )], + [perf_trampoline=no] +) +AC_MSG_RESULT([$perf_trampoline]) + +AS_VAR_IF([perf_trampoline], [yes], [ + AC_DEFINE([PY_HAVE_PERF_TRAMPOLINE], [1], [Define to 1 if you have the perf trampoline.]) +]) +AC_SUBST([PERF_TRAMPOLINE_OBJ]) + +# checks for libraries +AC_CHECK_LIB([sendfile], [sendfile]) +AC_CHECK_LIB([dl], [dlopen]) # Dynamic linking for SunOS/Solaris and SYSV +AC_CHECK_LIB([dld], [shl_load]) # Dynamic linking for HP-UX + +dnl Check for a working iconv() for the iconv codec. On glibc it is part of +dnl the C library; on some systems it lives in a separate libiconv. +dnl The wasm platforms (Emscripten, WASI) ship a non-conforming iconv() that +dnl does not report unencodable characters, which would make the iconv codec +dnl silently lossy, so treat iconv as unavailable there. +AC_CHECK_HEADERS([iconv.h]) +AS_CASE([$ac_sys_system], + [Emscripten|WASI], [py_have_iconv=no], + [py_have_iconv=$ac_cv_header_iconv_h]) +if test "$py_have_iconv" = yes; then + AC_CACHE_CHECK([for iconv], [ac_cv_have_iconv], [ + ac_cv_have_iconv=no + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <stdlib.h> +#include <iconv.h> + ]], [[ + iconv_t cd = iconv_open("", ""); + iconv(cd, NULL, NULL, NULL, NULL); + iconv_close(cd); + ]])], [ac_cv_have_iconv=yes], [ + py_save_LIBS="$LIBS" + LIBS="-liconv $LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <stdlib.h> +#include <iconv.h> + ]], [[ + iconv_t cd = iconv_open("", ""); + iconv(cd, NULL, NULL, NULL, NULL); + iconv_close(cd); + ]])], [ac_cv_have_iconv=-liconv]) + LIBS="$py_save_LIBS" + ]) + ]) + if test "$ac_cv_have_iconv" != no; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have a working iconv() function.]) + if test "$ac_cv_have_iconv" = -liconv; then + LIBS="-liconv $LIBS" + fi + fi +fi + + +dnl for faulthandler +AC_CHECK_HEADERS([execinfo.h link.h dlfcn.h], [ + AC_CHECK_FUNCS([backtrace dladdr1], [ + # dladdr1 requires -ldl + ac_cv_require_ldl=yes + ]) +]) + +dnl for JIT GNU backtrace unwind registration +AC_CACHE_CHECK([for libgcc frame registration functions], + [ac_cv_have_libgcc_eh_frame_registration], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +void __register_frame(const void *); +void __deregister_frame(const void *); +]], [[ +__register_frame(0); +__deregister_frame(0); +]])], + [ac_cv_have_libgcc_eh_frame_registration=yes], + [ac_cv_have_libgcc_eh_frame_registration=no]) + ]) +AS_VAR_IF([ac_cv_have_libgcc_eh_frame_registration], [yes], [ + AC_DEFINE([_Py_HAVE_LIBGCC_EH_FRAME_REGISTRATION], [1], + [Define to 1 if libgcc __register_frame and __deregister_frame are linkable.]) +]) + +dnl only add -ldl to LDFLAGS if it isn't already part of LIBS (GH-133081) +AS_VAR_IF([ac_cv_require_ldl], [yes], [ + AS_VAR_IF([ac_cv_lib_dl_dlopen], [yes], [], [ + AS_VAR_APPEND([LDFLAGS], [" -ldl"]) + ]) +]) + + +dnl check for uuid dependencies +AH_TEMPLATE([HAVE_UUID_H], [Define to 1 if you have the <uuid.h> header file.]) +AH_TEMPLATE([HAVE_UUID_UUID_H], [Define to 1 if you have the <uuid/uuid.h> header file.]) +AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE], [Define if uuid_generate_time_safe() exists.]) +AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [Define if uuid_generate_time_safe() is able to deduce a MAC address.]) +have_uuid=missing + +dnl AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 +dnl (anno 2007). FreeBSD and OpenBSD provides support in libc as well. +dnl Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet +dnl stream in big-endian byte-order +AC_CHECK_HEADERS([uuid.h], [ + AC_CHECK_FUNCS([uuid_create uuid_enc_be], [ + have_uuid=yes + ac_cv_have_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) +]) + +AS_VAR_IF([have_uuid], [missing], [ + PKG_CHECK_MODULES( + [LIBUUID], [uuid >= 2.20], + [dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011) + dnl and provides <uuid.h> assuming specific include paths are given + have_uuid=yes + ac_cv_have_uuid_generate_time_safe=yes + # The uuid.h file to include may be <uuid.h> *or* <uuid/uuid.h>. + # Since pkg-config --cflags uuid may return -I/usr/include/uuid, + # it's possible to write '#include <uuid.h>' in _uuidmodule.c, + # assuming that the compiler flags are properly updated. + # + # Ideally, we should have defined HAVE_UUID_H if and only if + # #include <uuid.h> can be written, *without* assuming extra + # include path. + ac_cv_have_uuid_h=yes + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + AC_CHECK_HEADERS([uuid/uuid.h], [ + ac_cv_have_uuid_uuid_h=yes + PY_CHECK_LIB([uuid], [uuid_generate_time], [have_uuid=yes]) + PY_CHECK_LIB([uuid], [uuid_generate_time_safe], [ + have_uuid=yes + ac_cv_have_uuid_generate_time_safe=yes + ])]) + AS_VAR_IF([have_uuid], [yes], [ + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} + ]) + ]) + ] + ) +]) + +dnl macOS has uuid/uuid.h but uuid_generate_time is in libc +AS_VAR_IF([have_uuid], [missing], [ + AC_CHECK_HEADERS([uuid/uuid.h], [ + AC_CHECK_FUNC([uuid_generate_time], [ + have_uuid=yes + ac_cv_have_uuid_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) + ]) +]) + +AS_VAR_IF([ac_cv_have_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_H], [1])]) +AS_VAR_IF([ac_cv_have_uuid_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_UUID_H], [1])]) +AS_VAR_IF([ac_cv_have_uuid_generate_time_safe], [yes], [ + AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) +]) + +# gh-124228: While the libuuid library is available on NetBSD and OpenBSD, +# it supports only UUID version 4. +# This restriction inhibits the proper generation of time-based UUIDs. +if test "$ac_sys_system" = "NetBSD" || test "$ac_sys_system" = "OpenBSD"; then + have_uuid=missing + AC_DEFINE([HAVE_UUID_H], [0]) +fi + +AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) + +# gh-132710: The UUID node is fetched by using libuuid when possible +# and cached. While the node is constant within the same process, +# different interpreters may have different values as libuuid may +# randomize the node value if the latter cannot be deduced. +# +# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC +# to indicate that libuuid is unstable and should not be relied +# upon to deduce the MAC address. +AC_DEFUN([PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC], [WITH_SAVE_ENV([ + # Be sure to add the extra include path if we used pkg-config + # as HAVE_UUID_H may be set even though <uuid.h> is only reachable + # by adding extra -I flags. + # + # If the following script does not compile, we simply assume that + # libuuid is missing. + CFLAGS="$CFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include <inttypes.h> // PRIu64 + #include <stdint.h> // uint64_t + #include <stdio.h> // fopen(), fclose() + + #ifdef HAVE_UUID_H + #include <uuid.h> + #else + #include <uuid/uuid.h> + #endif + + #define ERR 1 + int main(void) { + uuid_t uuid; // unsigned char[16] + (void)uuid_generate_time_safe(uuid); + uint64_t node = 0; + for (size_t i = 0; i < 6; i++) { + node |= (uint64_t)uuid[15 - i] << (8 * i); + } + FILE *fp = fopen("conftest.out", "w"); + if (fp == NULL) { + return ERR; + } + int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; + rc |= fclose(fp); + return rc == 0 ? 0 : ERR; + }]])], [ + AS_VAR_SET([$1], [`cat conftest.out`]) + ], [], [] + )])]) + +if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" +then + AC_MSG_CHECKING([if uuid_generate_time_safe() node value is stable]) + PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node1]) + PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node2]) + if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" + then + AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [1]) + AC_MSG_RESULT([stable]) + else + AC_MSG_RESULT([unstable]) + fi +fi + +# 'Real Time' functions on Solaris +# posix4 on Solaris 2.6 +# pthread (first!) on Linux +AC_SEARCH_LIBS([sem_init], [pthread rt posix4]) + +# check if we need libintl for locale functions +AC_CHECK_LIB([intl], [textdomain], + [AC_DEFINE([WITH_LIBINTL], [1], + [Define to 1 if libintl is needed for locale functions.]) + LIBS="-lintl $LIBS"]) + +# checks for system dependent C++ extensions support +case "$ac_sys_system" in + AIX*) AC_MSG_CHECKING([for genuine AIX C++ extensions support]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[@%:@include <load.h>]], + [[loadAndInit("", 0, "")]]) + ],[ + AC_DEFINE([AIX_GENUINE_CPLUSPLUS], [1], + [Define for AIX if your compiler is a genuine IBM xlC/xlC_r + and you want support for AIX C++ shared extension modules.]) + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + ]) +dnl The AIX_BUILDDATE is obtained from the kernel fileset - bos.mp64 +# BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag +# of the AIX system used to build/package Python executable. This tag serves +# as a baseline for bdist module packages + AC_MSG_CHECKING([for the system builddate]) + AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }') + AC_DEFINE_UNQUOTED([AIX_BUILDDATE], [$AIX_BUILDDATE], + [BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the PEP425 tag of the build system.]) + AC_MSG_RESULT([$AIX_BUILDDATE]) + ;; + *) ;; +esac + +# check for systems that require aligned memory access +AC_CACHE_CHECK([aligned memory access is required], [ac_cv_aligned_required], +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +int main(void) +{ + char s[16]; + int i, *p1, *p2; + for (i=0; i < 16; i++) + s[i] = i; + p1 = (int*)(s+1); + p2 = (int*)(s+2); + if (*p1 == *p2) + return 1; + return 0; +}]])], +[ac_cv_aligned_required=no], +[ac_cv_aligned_required=yes], +[ +# "yes" changes the hash function to FNV, which causes problems with Numba +# (https://github.com/numba/numba/blob/0.59.0/numba/cpython/hashing.py#L470). +if test "$ac_sys_system" = "Linux-android"; then + ac_cv_aligned_required=no +else + ac_cv_aligned_required=yes +fi]) +]) +if test "$ac_cv_aligned_required" = yes ; then + AC_DEFINE([HAVE_ALIGNED_REQUIRED], [1], + [Define if aligned memory access is required]) +fi + +# str, bytes and memoryview hash algorithm +AH_TEMPLATE([Py_HASH_ALGORITHM], + [Define hash algorithm for str, bytes and memoryview. + SipHash24: 1, FNV: 2, SipHash13: 3, externally defined: 0]) + +AC_MSG_CHECKING([for --with-hash-algorithm]) +dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output +AC_ARG_WITH( + [hash_algorithm], + [AS_HELP_STRING( + [--with-hash-algorithm=@<:@fnv|siphash13|siphash24@:>@], + [select hash algorithm for use in Python/pyhash.c (default is SipHash13)] + )], +[ +AC_MSG_RESULT([$withval]) +case "$withval" in + siphash13) + AC_DEFINE([Py_HASH_ALGORITHM], [3]) + ;; + siphash24) + AC_DEFINE([Py_HASH_ALGORITHM], [1]) + ;; + fnv) + AC_DEFINE([Py_HASH_ALGORITHM], [2]) + ;; + *) + AC_MSG_ERROR([unknown hash algorithm '$withval']) + ;; +esac +], +[AC_MSG_RESULT([default])]) + +validate_tzpath() { + # Checks that each element of the path is an absolute path + if test -z "$1"; then + # Empty string is allowed: it indicates no system TZPATH + return 0 + fi + + # Bad paths are those that don't start with / + dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output + if ( echo $1 | grep '\(^\|:\)\(@<:@^/@:>@\|$\)' > /dev/null); then + AC_MSG_ERROR([--with-tzpath must contain only absolute paths, not $1]) + return 1; + fi +} + +TZPATH="/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo" +AC_MSG_CHECKING([for --with-tzpath]) +AC_ARG_WITH( + [tzpath], + [AS_HELP_STRING( + [--with-tzpath=<list of absolute paths separated by pathsep>], + [Select the default time zone search path for zoneinfo.TZPATH] + )], +[ +case "$withval" in + yes) + AC_MSG_ERROR([--with-tzpath requires a value]) + ;; + *) + validate_tzpath "$withval" + TZPATH="$withval" + AC_MSG_RESULT(["$withval"]) + ;; +esac +], +[validate_tzpath "$TZPATH" + AC_MSG_RESULT(["$TZPATH"])]) +AC_SUBST([TZPATH]) + +# Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl. +AC_CHECK_LIB([nsl], [t_open], [LIBS="-lnsl $LIBS"]) # SVR4 +AC_CHECK_LIB([socket], [socket], [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets + +case $ac_sys_system/$ac_sys_release in + Haiku*) + AC_CHECK_LIB([network], [socket], [LIBS="-lnetwork $LIBS"], [], [$LIBS]) + ;; +esac + +AC_MSG_CHECKING([for --with-libs]) +AC_ARG_WITH( + [libs], + [AS_HELP_STRING( + [--with-libs='lib1 ...'], + [link against additional libs (default is no)] + )], +[ +AC_MSG_RESULT([$withval]) +LIBS="$withval $LIBS" +], +[AC_MSG_RESULT([no])]) + +# Check for use of the system expat library +AC_MSG_CHECKING([for --with-system-expat]) +AC_ARG_WITH( + [system_expat], + [AS_HELP_STRING( + [--with-system-expat], + [build pyexpat module using an installed expat library, see Doc/library/pyexpat.rst (default is no)] + )], [], [with_system_expat="no"]) + +AC_MSG_RESULT([$with_system_expat]) + +AS_VAR_IF([with_system_expat], [yes], [ + LIBEXPAT_CFLAGS=${LIBEXPAT_CFLAGS-""} + LIBEXPAT_LDFLAGS=${LIBEXPAT_LDFLAGS-"-lexpat"} + LIBEXPAT_INTERNAL= +], [ + LIBEXPAT_CFLAGS="-I\$(srcdir)/Modules/expat" + LIBEXPAT_LDFLAGS="-lm \$(LIBEXPAT_A)" + LIBEXPAT_INTERNAL="\$(LIBEXPAT_HEADERS) \$(LIBEXPAT_A)" +]) + +AC_SUBST([LIBEXPAT_CFLAGS]) +AC_SUBST([LIBEXPAT_INTERNAL]) + +dnl detect libffi +have_libffi=missing +AS_VAR_IF([ac_sys_system], [Darwin], [ + WITH_SAVE_ENV([ + CFLAGS="-I${SDKROOT}/usr/include/ffi $CFLAGS" + AC_CHECK_HEADER([ffi.h], [ + AC_CHECK_LIB([ffi], [ffi_call], [ + dnl use ffi from SDK root + have_libffi=yes + LIBFFI_CFLAGS="-I${SDKROOT}/usr/include/ffi -DUSING_APPLE_OS_LIBFFI=1" + LIBFFI_LIBS="-lffi" + ]) + ]) + ]) +]) +AS_VAR_IF([have_libffi], [missing], [ + PKG_CHECK_MODULES([LIBFFI], [libffi], [have_libffi=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LIBS="$LIBS $LIBFFI_LIBS" + AC_CHECK_HEADER([ffi.h], [ + AC_CHECK_LIB([ffi], [ffi_call], [ + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} + ], [have_libffi=no]) + ]) + ]) + ]) +]) + +AS_VAR_IF([have_libffi], [yes], [ + ctypes_malloc_closure=no + AS_CASE([$ac_sys_system], + [Darwin], [ + dnl when do we need USING_APPLE_OS_LIBFFI? + ctypes_malloc_closure=yes + ], + [iOS], [ + ctypes_malloc_closure=yes + ], + [sunos5], [AS_VAR_APPEND([LIBFFI_LIBS], [" -mimpure-text"])] + ) + AS_VAR_IF([ctypes_malloc_closure], [yes], [ + MODULE__CTYPES_MALLOC_CLOSURE=_ctypes/malloc_closure.c + AS_VAR_APPEND([LIBFFI_CFLAGS], [" -DUSING_MALLOC_CLOSURE_DOT_C=1"]) + ]) + AC_SUBST([MODULE__CTYPES_MALLOC_CLOSURE]) + + dnl HAVE_LIBDL: for dlopen, see gh-76828 + AS_VAR_IF([ac_cv_lib_dl_dlopen], [yes], [AS_VAR_APPEND([LIBFFI_LIBS], [" -ldl"])]) + + WITH_SAVE_ENV([ + CFLAGS="$CFLAGS $LIBFFI_CFLAGS" + LIBS="$LIBS $LIBFFI_LIBS" + + PY_CHECK_FUNC([ffi_prep_cif_var], [@%:@include <ffi.h>]) + PY_CHECK_FUNC([ffi_prep_closure_loc], [@%:@include <ffi.h>]) + PY_CHECK_FUNC([ffi_closure_alloc], [@%:@include <ffi.h>]) + ]) +]) + +# Check for libffi with real complex double support. +# This is a workaround, since FFI_TARGET_HAS_COMPLEX_TYPE was defined in libffi v3.2.1, +# but real support was provided only in libffi v3.3.0. +# See https://github.com/python/cpython/issues/125206 for more details. +# +AC_CACHE_CHECK([libffi has complex type support], [ac_cv_ffi_complex_double_supported], +[WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LIBS="$LIBS $LIBFFI_LIBS" +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <complex.h> +#include <ffi.h> +int z_is_expected(double complex z) +{ + const double complex expected = 1.25 - 0.5 * I; + return z == expected; +} +int main(void) +{ + double complex z = 1.25 - 0.5 * I; + ffi_type *args[1] = {&ffi_type_complex_double}; + void *values[1] = {&z}; + ffi_cif cif; + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) != FFI_OK) + { + return 2; + } + ffi_arg rc; + ffi_call(&cif, FFI_FN(z_is_expected), &rc, values); + return !rc; +} +]])], [ac_cv_ffi_complex_double_supported=yes], +[ac_cv_ffi_complex_double_supported=no], +[ac_cv_ffi_complex_double_supported=no]) +])]) +if test "$ac_cv_ffi_complex_double_supported" = "yes"; then + AC_DEFINE([_Py_FFI_SUPPORT_C_COMPLEX], [1], + [Defined if _Complex C type can be used with libffi.]) +fi + +# Check for native half-float type (_Float16). +AC_CACHE_CHECK([for _Float16 support], [ac_cv_float16_supported], +WITH_SAVE_ENV([ +CFLAGS="$CFLAGS -O0" +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <math.h> +int main(void) +{ + _Float16 val = 1.0f16; + int test = isinf(val) || isnan(val); /* basic support from libm */ + double d = 3.14; + val = d; + return test; +} +]])], [ac_cv_float16_supported=yes], +[ac_cv_float16_supported=no], +[ac_cv_float16_supported=no])])) +AS_VAR_IF([ac_cv_float16_supported], [yes], + [AC_DEFINE([HAVE_FLOAT16], [1], + [Defined if _Float16 C type is supported])]) + +dnl Check for libmpdec >= 2.5.0 +PKG_CHECK_MODULES([LIBMPDEC], [libmpdec >= 2.5.0], [have_mpdec=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBMPDEC_CFLAGS" + LIBS="$LIBS $LIBMPDEC_LIBS" + AC_CHECK_HEADER([mpdecimal.h], [ + AC_CHECK_LIB([mpdec], [mpd_version], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ + #include <mpdecimal.h> + #if MPD_VERSION_HEX < 0x02050000 + # error "mpdecimal 2.5.0 or higher required" + #endif + ], [])], + [have_mpdec=yes], + [have_mpdec=no]) + ], [have_mpdec=no]) + ], [have_mpdec=no]) + + AS_VAR_IF([have_mpdec], [yes], [ + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_LIBS=${LIBMPDEC_LIBS-"-lmpdec -lm"} + ]) + ]) +]) + +# Check whether _decimal should use a coroutine-local or thread-local context +AC_MSG_CHECKING([for --with-decimal-contextvar]) +AC_ARG_WITH( + [decimal_contextvar], + [AS_HELP_STRING( + [--with-decimal-contextvar], + [build _decimal module using a coroutine-local rather than a thread-local context (default is yes)] + )], + [], + [with_decimal_contextvar="yes"]) + +if test "$with_decimal_contextvar" != "no" +then + AC_DEFINE([WITH_DECIMAL_CONTEXTVAR], [1], + [Define if you want build the _decimal module using a coroutine-local rather than a thread-local context]) +fi + +AC_MSG_RESULT([$with_decimal_contextvar]) + +dnl detect sqlite3 from Emscripten emport +PY_CHECK_EMSCRIPTEN_PORT([LIBSQLITE3], [-sUSE_SQLITE3]) + +dnl Check for SQLite library. Use pkg-config if available. +PKG_CHECK_MODULES( + [LIBSQLITE3], [sqlite3 >= 3.15.2], [], [ + LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} + LIBSQLITE3_LIBS=${LIBSQLITE3_LIBS-"-lsqlite3"} + ] +) +AS_VAR_APPEND([LIBSQLITE3_CFLAGS], [' -I$(srcdir)/Modules/_sqlite']) + +dnl PY_CHECK_SQLITE_FUNC(FUNCTION, IF-FOUND, IF-NOT-FOUND) +AC_DEFUN([PY_CHECK_SQLITE_FUNC], [ + AC_CHECK_LIB([sqlite3], [$1], [$2], [ + m4_ifblank([$3], [have_supported_sqlite3=no], [$3]) + ]) +]) + +WITH_SAVE_ENV([ +dnl bpo-45774/GH-29507: The CPP check in AC_CHECK_HEADER can fail on FreeBSD, +dnl hence CPPFLAGS instead of CFLAGS. + CPPFLAGS="$CPPFLAGS $LIBSQLITE3_CFLAGS" + LIBS="$LIBS $LIBSQLITE3_LIBS" + + AC_CHECK_HEADER([sqlite3.h], [ + have_sqlite3=yes + + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ + #include <sqlite3.h> + #if SQLITE_VERSION_NUMBER < 3015002 + # error "SQLite 3.15.2 or higher required" + #endif + ], []) + ], [ + have_supported_sqlite3=yes + dnl Check that required functions are in place. A lot of stuff may be + dnl omitted with SQLITE_OMIT_* compile time defines. + PY_CHECK_SQLITE_FUNC([sqlite3_bind_double]) + PY_CHECK_SQLITE_FUNC([sqlite3_column_decltype]) + PY_CHECK_SQLITE_FUNC([sqlite3_column_double]) + PY_CHECK_SQLITE_FUNC([sqlite3_complete]) + PY_CHECK_SQLITE_FUNC([sqlite3_progress_handler]) + PY_CHECK_SQLITE_FUNC([sqlite3_result_double]) + PY_CHECK_SQLITE_FUNC([sqlite3_set_authorizer]) + PY_CHECK_SQLITE_FUNC([sqlite3_trace_v2], [], [ + PY_CHECK_SQLITE_FUNC([sqlite3_trace]) + ]) + PY_CHECK_SQLITE_FUNC([sqlite3_value_double]) + AC_CHECK_LIB([sqlite3], [sqlite3_load_extension], + [have_sqlite3_load_extension=yes], + [have_sqlite3_load_extension=no] + ) + AC_CHECK_LIB([sqlite3], [sqlite3_serialize], [ + AC_DEFINE( + [PY_SQLITE_HAVE_SERIALIZE], [1], + [Define if SQLite was compiled with the serialize API] + ) + ]) + ], [ + have_supported_sqlite3=no + ]) + ]) +]) + +dnl Check for support for loadable sqlite extensions +AC_MSG_CHECKING([for --enable-loadable-sqlite-extensions]) +AC_ARG_ENABLE([loadable-sqlite-extensions], + AS_HELP_STRING( + [--enable-loadable-sqlite-extensions], [ + support loadable extensions in the sqlite3 module, see + Doc/library/sqlite3.rst (default is no) + ] + ), [ + AS_VAR_IF([have_sqlite3_load_extension], [no], [ + AC_MSG_RESULT([n/a]) + AC_MSG_WARN([Your version of SQLite does not support loadable extensions]) + ], [ + AC_MSG_RESULT([yes]) + AC_DEFINE( + [PY_SQLITE_ENABLE_LOAD_EXTENSION], [1], + [Define to 1 to build the sqlite module with loadable extensions support.] + ) + ]) + ], [ + AC_MSG_RESULT([no]) + ] +) + +dnl +dnl Detect Tcl/Tk. Use pkg-config if available. +dnl +found_tcltk=no +for _QUERY in \ + "tcl >= 8.5.12 tk >= 8.5.12" \ + "tcl8.6 tk8.6" \ + "tcl86 tk86" \ + "tcl8.5 >= 8.5.12 tk8.5 >= 8.5.12" \ + "tcl85 >= 8.5.12 tk85 >= 8.5.12" \ +; do + PKG_CHECK_EXISTS([$_QUERY], [ + PKG_CHECK_MODULES([TCLTK], [$_QUERY], [found_tcltk=yes], [found_tcltk=no]) + ]) + AS_VAR_IF([found_tcltk], [yes], [break]) +done + +AS_VAR_IF([found_tcltk], [no], [ + TCLTK_CFLAGS=${TCLTK_CFLAGS-""} + TCLTK_LIBS=${TCLTK_LIBS-""} +]) + +dnl FreeBSD has an X11 dependency which is not implicitly resolved. +AS_CASE([$ac_sys_system], + [FreeBSD*], [ + PKG_CHECK_EXISTS([x11], [ + PKG_CHECK_MODULES([X11], [x11], [ + TCLTK_CFLAGS="$TCLTK_CFLAGS $X11_CFLAGS" + TCLTK_LIBS="$TCLTK_LIBS $X11_LIBS" + ]) + ]) + ] +) + +WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $TCLTK_CFLAGS" + LIBS="$LIBS $TCLTK_LIBS" + + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ + #include <tcl.h> + #include <tk.h> + #if defined(TK_HEX_VERSION) + # if TK_HEX_VERSION < 0x0805020c + # error "Tk older than 8.5.12 not supported" + # endif + #endif + #if (TCL_MAJOR_VERSION < 8) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 5)) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 5) && (TCL_RELEASE_SERIAL < 12)) + # error "Tcl older than 8.5.12 not supported" + #endif + #if (TK_MAJOR_VERSION < 8) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION < 5)) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 5) && (TK_RELEASE_SERIAL < 12)) + # error "Tk older than 8.5.12 not supported" + #endif + ], [ + Tcl_Init(NULL); + Tk_Init(NULL); + ]) + ], [ + have_tcltk=yes + dnl The X11/xlib.h file bundled in the Tk sources can cause function + dnl prototype warnings from the compiler. Since we cannot easily fix + dnl that, suppress the warnings here instead. + AS_VAR_APPEND([TCLTK_CFLAGS], [" -Wno-strict-prototypes -DWITH_APPINIT=1"]) + ], [ + have_tcltk=no + ]) +]) + +dnl check for _gdbmmodule dependencies +dnl NOTE: gdbm does not provide a pkgconf file. +AC_ARG_VAR([GDBM_CFLAGS], [C compiler flags for gdbm]) +AC_ARG_VAR([GDBM_LIBS], [additional linker flags for gdbm]) +WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $GDBM_CFLAGS" + LIBS="$LIBS $GDBM_LIBS" + AC_CHECK_HEADERS([gdbm.h], [ + AC_CHECK_LIB([gdbm], [gdbm_open], [ + have_gdbm=yes + GDBM_LIBS=${GDBM_LIBS-"-lgdbm"} + ], [have_gdbm=no]) + ], [have_gdbm=no]) +]) + +dnl check for _dbmmodule.c dependencies +dnl ndbm, gdbm_compat, libdb +AC_CHECK_HEADERS([ndbm.h], [ + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([dbm_open], [ndbm gdbm_compat]) + ]) +]) + +AC_MSG_CHECKING([for ndbm presence and linker args]) +AS_CASE([$ac_cv_search_dbm_open], + [*ndbm*|*gdbm_compat*], [ + dbm_ndbm="$ac_cv_search_dbm_open" + have_ndbm=yes + ], + [none*], [ + dbm_ndbm="" + have_ndbm=yes + ], + [no], [have_ndbm=no] +) +AC_MSG_RESULT([$have_ndbm ($dbm_ndbm)]) + +dnl "gdbm-ndbm.h" and "gdbm/ndbm.h" are both normalized to "gdbm_ndbm_h" +AC_CACHE_CHECK([for gdbm/ndbm.h], [ac_cv_header_gdbm_slash_ndbm_h], + [AC_PREPROC_IFELSE([AC_LANG_SOURCE([@%:@include <gdbm/ndbm.h>])], + [ac_cv_header_gdbm_slash_ndbm_h=yes], + [ac_cv_header_gdbm_slash_ndbm_h=no])]) +AS_VAR_IF([ac_cv_header_gdbm_slash_ndbm_h], [yes], [ + AC_DEFINE([HAVE_GDBM_NDBM_H], [1], [Define to 1 if you have the <gdbm/ndbm.h> header file.]) +]) + +AC_CACHE_CHECK([for gdbm-ndbm.h], [ac_cv_header_gdbm_dash_ndbm_h], + [AC_PREPROC_IFELSE([AC_LANG_SOURCE([@%:@include <gdbm-ndbm.h>])], + [ac_cv_header_gdbm_dash_ndbm_h=yes], + [ac_cv_header_gdbm_dash_ndbm_h=no])]) +AS_VAR_IF([ac_cv_header_gdbm_dash_ndbm_h], [yes], [ + AC_DEFINE([HAVE_GDBM_DASH_NDBM_H], [1], [Define to 1 if you have the <gdbm-ndbm.h> header file.]) +]) + +if test "$ac_cv_header_gdbm_slash_ndbm_h" = yes -o "$ac_cv_header_gdbm_dash_ndbm_h" = yes; then + AS_UNSET([ac_cv_search_dbm_open]) + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([dbm_open], [gdbm_compat], [have_gdbm_compat=yes], [have_gdbm_compat=no]) + ]) +fi + +# Check for libdb >= 5 with dbm_open() +# db.h re-defines the name of the function +AC_CHECK_HEADERS([db.h], [ + AC_CACHE_CHECK([for libdb], [ac_cv_have_libdb], [ + WITH_SAVE_ENV([ + LIBS="$LIBS -ldb" + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #define DB_DBM_HSEARCH 1 + #include <db.h> + #if DB_VERSION_MAJOR < 5 + #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." + #endif + ], [DBM *dbm = dbm_open(NULL, 0, 0)]) + ], [ac_cv_have_libdb=yes], [ac_cv_have_libdb=no]) + ]) + ]) + AS_VAR_IF([ac_cv_have_libdb], [yes], [ + AC_DEFINE([HAVE_LIBDB], [1], [Define to 1 if you have the `db' library (-ldb).]) + ]) +]) + +# Check for --with-dbmliborder +AC_MSG_CHECKING([for --with-dbmliborder]) +AC_ARG_WITH( + [dbmliborder], + [AS_HELP_STRING( + [--with-dbmliborder=db1:db2:...], + [override order to check db backends for dbm; a valid value is a colon separated string with the backend names `ndbm', `gdbm' and `bdb'.] + )], + [], [with_dbmliborder=gdbm:ndbm:bdb]) + +have_gdbm_dbmliborder=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + AS_CASE([$db], + [ndbm], [], + [gdbm], [have_gdbm_dbmliborder=yes], + [bdb], [], + [with_dbmliborder=error] + ) +done +IFS=$as_save_IFS +AS_VAR_IF([with_dbmliborder], [error], [ + AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:... (gdbm:ndbm:bdb)]) +]) +AC_MSG_RESULT([$with_dbmliborder]) + +AC_MSG_CHECKING([for _dbm module CFLAGS and LIBS]) +have_dbm=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case "$db" in + ndbm) + if test "$have_ndbm" = yes; then + DBM_CFLAGS="-DUSE_NDBM" + DBM_LIBS="$dbm_ndbm" + have_dbm=yes + break + fi + ;; + gdbm) + if test "$have_gdbm_compat" = yes; then + DBM_CFLAGS="-DUSE_GDBM_COMPAT" + DBM_LIBS="-lgdbm_compat" + have_dbm=yes + break + fi + ;; + bdb) + if test "$ac_cv_have_libdb" = yes; then + DBM_CFLAGS="-DUSE_BERKDB" + DBM_LIBS="-ldb" + have_dbm=yes + break + fi + ;; + esac +done +IFS=$as_save_IFS +AC_MSG_RESULT([$DBM_CFLAGS $DBM_LIBS]) + +# Templates for things AC_DEFINEd more than once. +# For a single AC_DEFINE, no template is needed. +AH_TEMPLATE([_REENTRANT], + [Define to force use of thread-safe errno, h_errno, and other functions]) + +if test "$ac_cv_pthread_is_default" = yes +then + # Defining _REENTRANT on system with POSIX threads should not hurt. + AC_DEFINE([_REENTRANT]) + posix_threads=yes + if test "$ac_sys_system" = "SunOS"; then + CFLAGS="$CFLAGS -D_REENTRANT" + fi +elif test "$ac_cv_kpthread" = "yes" +then + CC="$CC -Kpthread" + if test "$ac_cv_cxx_thread" = "yes"; then + CXX="$CXX -Kpthread" + fi + posix_threads=yes +elif test "$ac_cv_kthread" = "yes" +then + CC="$CC -Kthread" + if test "$ac_cv_cxx_thread" = "yes"; then + CXX="$CXX -Kthread" + fi + posix_threads=yes +elif test "$ac_cv_pthread" = "yes" +then + CC="$CC -pthread" + if test "$ac_cv_cxx_thread" = "yes"; then + CXX="$CXX -pthread" + fi + posix_threads=yes +else + if test ! -z "$withval" -a -d "$withval" + then LDFLAGS="$LDFLAGS -L$withval" + fi + + # According to the POSIX spec, a pthreads implementation must + # define _POSIX_THREADS in unistd.h. Some apparently don't + # (e.g. gnu pth with pthread emulation) + AC_MSG_CHECKING([for _POSIX_THREADS in unistd.h]) + AX_CHECK_DEFINE([unistd.h], [_POSIX_THREADS], + [unistd_defines_pthreads=yes], + [unistd_defines_pthreads=no]) + AC_MSG_RESULT([$unistd_defines_pthreads]) + + AC_DEFINE([_REENTRANT]) + # Just looking for pthread_create in libpthread is not enough: + # on HP/UX, pthread.h renames pthread_create to a different symbol name. + # So we really have to include pthread.h, and then link. + _libs=$LIBS + LIBS="$LIBS -lpthread" + AC_MSG_CHECKING([for pthread_create in -lpthread]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> + +void * start_routine (void *arg) { exit (0); }]], [[ +pthread_create (NULL, NULL, start_routine, NULL)]])],[ + AC_MSG_RESULT([yes]) + posix_threads=yes + ],[ + LIBS=$_libs + AC_CHECK_FUNC([pthread_detach], [ + posix_threads=yes + ],[ + AC_CHECK_LIB([pthreads], [pthread_create], [ + posix_threads=yes + LIBS="$LIBS -lpthreads" + ], [ + AC_CHECK_LIB([c_r], [pthread_create], [ + posix_threads=yes + LIBS="$LIBS -lc_r" + ], [ + AC_CHECK_LIB([pthread], [__pthread_create_system], [ + posix_threads=yes + LIBS="$LIBS -lpthread" + ], [ + AC_CHECK_LIB([cma], [pthread_create], [ + posix_threads=yes + LIBS="$LIBS -lcma" + ],[ + AS_CASE([$ac_sys_system], + [WASI], [posix_threads=stub], + [AC_MSG_ERROR([could not find pthreads on your system])] + ) + ])])])])])]) + + AC_CHECK_LIB([mpc], [usconfig], [ + LIBS="$LIBS -lmpc" + ]) + +fi + +if test "$posix_threads" = "yes"; then + if test "$unistd_defines_pthreads" = "no"; then + AC_DEFINE([_POSIX_THREADS], [1], + [Define if you have POSIX threads, + and your system does not define that.]) + fi + + # Bug 662787: Using semaphores causes unexplicable hangs on Solaris 8. + case $ac_sys_system/$ac_sys_release in + SunOS/5.6) AC_DEFINE([HAVE_PTHREAD_DESTRUCTOR], [1], + [Defined for Solaris 2.6 bug in pthread header.]) + ;; + SunOS/5.8) AC_DEFINE([HAVE_BROKEN_POSIX_SEMAPHORES], [1], + [Define if the Posix semaphores do not work on your system]) + ;; + AIX/*) AC_DEFINE([HAVE_BROKEN_POSIX_SEMAPHORES], [1], + [Define if the Posix semaphores do not work on your system]) + ;; + NetBSD/*) AC_DEFINE([HAVE_BROKEN_POSIX_SEMAPHORES], [1], + [Define if the Posix semaphores do not work on your system]) + ;; + esac + + AC_CACHE_CHECK([if PTHREAD_SCOPE_SYSTEM is supported], [ac_cv_pthread_system_supported], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include <stdio.h> + #include <pthread.h> + void *foo(void *parm) { + return NULL; + } + int main(void) { + pthread_attr_t attr; + pthread_t id; + if (pthread_attr_init(&attr)) return (-1); + if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) return (-1); + if (pthread_create(&id, &attr, foo, NULL)) return (-1); + if (pthread_join(id, NULL)) return (-1); + return (0); + }]])], + [ac_cv_pthread_system_supported=yes], + [ac_cv_pthread_system_supported=no], + [ac_cv_pthread_system_supported=no]) + ]) + if test "$ac_cv_pthread_system_supported" = "yes"; then + AC_DEFINE([PTHREAD_SYSTEM_SCHED_SUPPORTED], [1], + [Defined if PTHREAD_SCOPE_SYSTEM supported.]) + fi + AC_CHECK_FUNCS([pthread_sigmask], + [case $ac_sys_system in + CYGWIN*) + AC_DEFINE([HAVE_BROKEN_PTHREAD_SIGMASK], [1], + [Define if pthread_sigmask() does not work on your system.]) + ;; + esac]) + AC_CHECK_FUNCS([pthread_getcpuclockid]) +fi + +AS_VAR_IF([posix_threads], [stub], [ + AC_DEFINE([HAVE_PTHREAD_STUBS], [1], [Define if platform requires stubbed pthreads support]) +]) + +# Check for enable-ipv6 +AH_TEMPLATE([ENABLE_IPV6], [Define if --enable-ipv6 is specified]) +AC_MSG_CHECKING([if --enable-ipv6 is specified]) +AC_ARG_ENABLE([ipv6], + [AS_HELP_STRING( + [--enable-ipv6], + [enable ipv6 (with ipv4) support, see Doc/library/socket.rst (default is yes if supported)] + )], +[ case "$enableval" in + no) + AC_MSG_RESULT([no]) + ipv6=no + ;; + *) AC_MSG_RESULT([yes]) + AC_DEFINE([ENABLE_IPV6]) + ipv6=yes + ;; + esac ], + +[ +dnl the check does not work on cross compilation case... + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* AF_INET6 available check */ +#include <sys/types.h> +@%:@include <sys/socket.h>]], +[[int domain = AF_INET6;]])],[ + ipv6=yes +],[ + ipv6=no +]) + +AS_CASE([$ac_sys_system], + [WASI], [ipv6=no] +) + +AC_MSG_RESULT([$ipv6]) + +if test "$ipv6" = "yes"; then + AC_MSG_CHECKING([if RFC2553 API is available]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[#include <sys/types.h> +@%:@include <netinet/in.h>]], + [[struct sockaddr_in6 x; + x.sin6_scope_id;]]) + ],[ + AC_MSG_RESULT([yes]) + ipv6=yes + ],[ + AC_MSG_RESULT([no], [IPv6 disabled]) + ipv6=no + ]) +fi + +if test "$ipv6" = "yes"; then + AC_DEFINE([ENABLE_IPV6]) +fi +]) + +ipv6type=unknown +ipv6lib=none +ipv6trylibc=no + +if test "$ipv6" = yes -a "$cross_compiling" = no; then + for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta; + do + case $i in + inria) + dnl http://www.kame.net/ + AX_CHECK_DEFINE([netinet/in.h], [IPV6_INRIA_VERSION], [ipv6type=$i]) + ;; + kame) + dnl http://www.kame.net/ + AX_CHECK_DEFINE([netinet/in.h], [__KAME__], + [ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/local/v6/lib + ipv6trylibc=yes]) + ;; + linux-glibc) + dnl Advanced IPv6 support was added to glibc 2.1 in 1999. + AX_CHECK_DEFINE([features.h], [__GLIBC__], + [ipv6type=$i + ipv6trylibc=yes]) + ;; + linux-inet6) + dnl http://www.v6.linux.or.jp/ + if test -d /usr/inet6; then + ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/inet6/lib + BASECFLAGS="-I/usr/inet6/include $BASECFLAGS" + fi + ;; + solaris) + if test -f /etc/netconfig; then + if $GREP -q tcp6 /etc/netconfig; then + ipv6type=$i + ipv6trylibc=yes + fi + fi + ;; + toshiba) + AX_CHECK_DEFINE([sys/param.h], [_TOSHIBA_INET6], + [ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/local/v6/lib]) + ;; + v6d) + AX_CHECK_DEFINE([/usr/local/v6/include/sys/v6config.h], [__V6D__], + [ipv6type=$i + ipv6lib=v6 + ipv6libdir=/usr/local/v6/lib + BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS"]) + ;; + zeta) + AX_CHECK_DEFINE([sys/param.h], [_ZETA_MINAMI_INET6], + [ipv6type=$i + ipv6lib=inet6 + ipv6libdir=/usr/local/v6/lib]) + ;; + esac + if test "$ipv6type" != "unknown"; then + break + fi + done + AC_MSG_CHECKING([ipv6 stack type]) + AC_MSG_RESULT([$ipv6type]) +fi + +if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then + AC_MSG_CHECKING([ipv6 library]) + if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then + LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" + AC_MSG_RESULT([lib$ipv6lib]) + else + AS_VAR_IF([ipv6trylibc], [yes], [ + AC_MSG_RESULT([libc]) + ], [ + AC_MSG_ERROR([m4_normalize([ + No $ipv6lib library found; cannot continue. + You need to fetch lib$ipv6lib.a from appropriate + ipv6 kit and compile beforehand. + ])]) + ]) + fi +fi + + +AC_CACHE_CHECK([CAN_RAW_FD_FRAMES], [ac_cv_can_raw_fd_frames], [ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* CAN_RAW_FD_FRAMES available check */ +@%:@include <linux/can/raw.h>]], +[[int can_raw_fd_frames = CAN_RAW_FD_FRAMES;]])], +[ac_cv_can_raw_fd_frames=yes], +[ac_cv_can_raw_fd_frames=no]) +]) +AS_VAR_IF([ac_cv_can_raw_fd_frames], [yes], [ + AC_DEFINE([HAVE_LINUX_CAN_RAW_FD_FRAMES], [1], + [Define if compiling using Linux 3.6 or later.]) +]) + +AC_CACHE_CHECK([for CAN_RAW_JOIN_FILTERS], [ac_cv_can_raw_join_filters], [ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +@%:@include <linux/can/raw.h>]], +[[int can_raw_join_filters = CAN_RAW_JOIN_FILTERS;]])], +[ac_cv_can_raw_join_filters=yes], +[ac_cv_can_raw_join_filters=no]) +]) +AS_VAR_IF([ac_cv_can_raw_join_filters], [yes], [ + AC_DEFINE([HAVE_LINUX_CAN_RAW_JOIN_FILTERS], [1], + [Define if compiling using Linux 4.1 or later.]) +]) + +# Check for --with-doc-strings +AC_MSG_CHECKING([for --with-doc-strings]) +AC_ARG_WITH( + [doc-strings], + [AS_HELP_STRING([--with-doc-strings], [enable documentation strings (default is yes)])]) + +if test -z "$with_doc_strings" +then with_doc_strings="yes" +fi +if test "$with_doc_strings" != "no" +then + AC_DEFINE([WITH_DOC_STRINGS], [1], + [Define if you want documentation strings in extension modules]) +fi +AC_MSG_RESULT([$with_doc_strings]) + +# Check for stdatomic.h, required for mimalloc. +AC_CACHE_CHECK([for stdatomic.h], [ac_cv_header_stdatomic_h], [ +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + #include <stdatomic.h> + atomic_int int_var; + atomic_uintptr_t uintptr_var; + int main() { + atomic_store_explicit(&int_var, 5, memory_order_relaxed); + atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); + int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); + return 0; + } + ]]) +],[ac_cv_header_stdatomic_h=yes],[ac_cv_header_stdatomic_h=no]) +]) + +AS_VAR_IF([ac_cv_header_stdatomic_h], [yes], [ + AC_DEFINE(HAVE_STD_ATOMIC, 1, + [Has stdatomic.h with atomic_int and atomic_uintptr_t]) +]) + +# Check for GCC >= 4.7 and clang __atomic builtin functions +AC_CACHE_CHECK([for builtin __atomic_load_n and __atomic_store_n functions], [ac_cv_builtin_atomic], [ +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + int val; + int main() { + __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); + (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); + return 0; + } + ]]) +],[ac_cv_builtin_atomic=yes],[ac_cv_builtin_atomic=no]) +]) + +AS_VAR_IF([ac_cv_builtin_atomic], [yes], [ + AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Has builtin __atomic_load_n() and __atomic_store_n() functions]) +]) + +# Check for __builtin_shufflevector with 128-bit vector support on an +# architecture where it compiles to worthwhile native SIMD instructions. +# Used for SIMD-accelerated bytes.hex() in Python/pystrhex.c. +AC_CACHE_CHECK([for __builtin_shufflevector], [ac_cv_efficient_builtin_shufflevector], [ +AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + /* __builtin_shufflevector is available on many platforms, but 128-bit + vector code is only worthwhile on architectures with native SIMD: + x86-64 (SSE2, always available), ARM64 (NEON, always available), + or ARM32 when NEON is enabled via compiler flags (e.g. -march=native + on RPi3+). On ARM32 without NEON (e.g. armv6 builds), the compiler + has the builtin but generates slow scalar code instead. */ + #if !defined(__x86_64__) && !defined(__aarch64__) && \ + !(defined(__arm__) && defined(__ARM_NEON)) + # error "128-bit vector SIMD not worthwhile on this architecture" + #endif + typedef unsigned char v16u8 __attribute__((vector_size(16))); + ]], [[ + v16u8 a = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + v16u8 b = {16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + v16u8 c = __builtin_shufflevector(a, b, + 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23); + (void)c; + return 0; + ]]) +],[ac_cv_efficient_builtin_shufflevector=yes],[ac_cv_efficient_builtin_shufflevector=no]) +]) + +AS_VAR_IF([ac_cv_efficient_builtin_shufflevector], [yes], [ + AC_DEFINE([_Py_HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR], [1], + [Define if compiler supports __builtin_shufflevector with 128-bit + vectors AND the target architecture has native SIMD (not just API + availability)]) +]) + +# --with-mimalloc +AC_MSG_CHECKING([for --with-mimalloc]) +AC_ARG_WITH([mimalloc], + [AS_HELP_STRING([--with-mimalloc], + [build with mimalloc memory allocator (default is yes if C11 stdatomic.h is available.)])], + [], + [with_mimalloc="$ac_cv_header_stdatomic_h"] +) + +if test "$with_mimalloc" != no; then + if test "$ac_cv_header_stdatomic_h" != yes; then + # mimalloc-atomic.h wants C11 stdatomic.h on POSIX + AC_MSG_ERROR([mimalloc requires stdatomic.h, use --without-mimalloc to disable mimalloc.]) + fi + with_mimalloc=yes + AC_DEFINE([WITH_MIMALLOC], [1], [Define if you want to compile in mimalloc memory allocator.]) + AC_SUBST([MIMALLOC_HEADERS], ['$(MIMALLOC_HEADERS)']) +elif test "$disable_gil" = "yes"; then + AC_MSG_ERROR([--disable-gil requires mimalloc memory allocator (--with-mimalloc).]) +fi + +AC_MSG_RESULT([$with_mimalloc]) +AC_SUBST([INSTALL_MIMALLOC], [$with_mimalloc]) +AC_SUBST([MIMALLOC_HEADERS]) + +# Check for Python-specific malloc support +AC_MSG_CHECKING([for --with-pymalloc]) +AC_ARG_WITH( + [pymalloc], + [AS_HELP_STRING([--with-pymalloc], [enable specialized mallocs (default is yes)])]) + +if test -z "$with_pymalloc" +then + dnl default to yes except for wasm32-emscripten and wasm32-wasi. + AS_CASE([$ac_sys_system], + [Emscripten], [with_pymalloc="no"], + [WASI], [with_pymalloc="no"], + [with_pymalloc="yes"] + ) +fi +if test "$with_pymalloc" != "no" +then + AC_DEFINE([WITH_PYMALLOC], [1], + [Define if you want to compile in Python-specific mallocs]) +fi +AC_MSG_RESULT([$with_pymalloc]) + +AC_MSG_CHECKING([for --with-pymalloc-hugepages]) +AC_ARG_WITH( + [pymalloc-hugepages], + [AS_HELP_STRING([--with-pymalloc-hugepages], + [enable huge page support for pymalloc arenas (default is no)])]) +if test "$with_pymalloc_hugepages" = "yes" +then + dnl configure only runs on Unix-like systems; Windows uses MEM_LARGE_PAGES + dnl via VirtualAlloc but does not use configure. Only check MAP_HUGETLB here. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#include <sys/mman.h> + ]], [[ +int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB; +(void)flags; + ]])], + [AC_DEFINE([PYMALLOC_USE_HUGEPAGES], [1], + [Define to use huge pages for pymalloc arenas])], + [AC_MSG_WARN([--with-pymalloc-hugepages requested but MAP_HUGETLB not found]) + with_pymalloc_hugepages=no]) +fi +AC_MSG_RESULT([${with_pymalloc_hugepages:-no}]) + +# Check for --with-c-locale-coercion +AC_MSG_CHECKING([for --with-c-locale-coercion]) +AC_ARG_WITH( + [c-locale-coercion], + [AS_HELP_STRING([--with-c-locale-coercion], [enable C locale coercion to a UTF-8 based locale (default is yes)])]) + +if test -z "$with_c_locale_coercion" +then + with_c_locale_coercion="yes" +fi +if test "$with_c_locale_coercion" != "no" +then + AC_DEFINE([PY_COERCE_C_LOCALE], [1], + [Define if you want to coerce the C locale to a UTF-8 based locale]) +fi +AC_MSG_RESULT([$with_c_locale_coercion]) + +# Check for Valgrind support +AC_MSG_CHECKING([for --with-valgrind]) +AC_ARG_WITH( + [valgrind], + [AS_HELP_STRING([--with-valgrind], [enable Valgrind support (default is no)])], + [], [with_valgrind=no] +) +AC_MSG_RESULT([$with_valgrind]) +if test "$with_valgrind" != no; then + AC_CHECK_HEADER([valgrind/valgrind.h], + [AC_DEFINE([WITH_VALGRIND], 1, [Define if you want pymalloc to be disabled when running under valgrind])], + [AC_MSG_ERROR([Valgrind support requested but headers not available])] + ) + OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT" +fi + +# Check for DTrace support +AC_MSG_CHECKING([for --with-dtrace]) +AC_ARG_WITH( + [dtrace], + [AS_HELP_STRING([--with-dtrace], [enable DTrace support (default is no)])], + [], [with_dtrace=no]) +AC_MSG_RESULT([$with_dtrace]) + +AC_SUBST([DTRACE]) +AC_SUBST([DFLAGS]) +AC_SUBST([DTRACE_HEADERS]) +AC_SUBST([DTRACE_OBJS]) +DTRACE= +DTRACE_HEADERS= +DTRACE_OBJS= + +if test "$with_dtrace" = "yes" +then + AC_PATH_PROG([DTRACE], [dtrace], [not found]) + if test "$DTRACE" = "not found"; then + AC_MSG_ERROR([dtrace command not found on \$PATH]) + fi + AC_DEFINE([WITH_DTRACE], [1], + [Define if you want to compile in DTrace support]) + DTRACE_HEADERS="Include/pydtrace_probes.h" + + # On OS X, DTrace providers do not need to be explicitly compiled and + # linked into the binary. Correspondingly, dtrace(1) is missing the ELF + # generation flag '-G'. We check for presence of this flag, rather than + # hardcoding support by OS, in the interest of robustness. + # + # NetBSD DTrace requires the -x nolibs flag to avoid system library conflicts + # and uses header generation for testing instead of object generation. + AC_CACHE_CHECK([whether DTrace probes require linking], + [ac_cv_dtrace_link], [ + ac_cv_dtrace_link=no + echo 'BEGIN{}' > conftest.d + case $host in + *netbsd*) + DTRACE_TEST_FLAGS="-x nolibs -h" + ;; + *) + DTRACE_TEST_FLAGS="-G" + ;; + esac + "$DTRACE" $DFLAGS $DTRACE_TEST_FLAGS -s conftest.d -o conftest.o > /dev/null 2>&1 && \ + ac_cv_dtrace_link=yes + ]) + if test "$ac_cv_dtrace_link" = "yes"; then + DTRACE_OBJS="Python/pydtrace.o" + fi + # Set NetBSD-specific DTrace flags in DFLAGS + case $host in + *netbsd*) + DFLAGS="$DFLAGS -x nolibs" + ;; + esac +fi + +dnl Platform-specific C and header files. +PLATFORM_HEADERS= +PLATFORM_OBJS= + +AS_CASE([$ac_sys_system], + [Emscripten], [ + AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_signal.o Python/emscripten_trampoline.o Python/emscripten_trampoline_wasm.o']) + AS_VAR_IF([enable_emscripten_syscalls], [yes], [ + AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_syscalls.o']) + ]) + AS_VAR_APPEND([PLATFORM_HEADERS], [' $(srcdir)/Include/internal/pycore_emscripten_signal.h $(srcdir)/Include/internal/pycore_emscripten_trampoline.h']) + ], +) +AC_SUBST([PLATFORM_HEADERS]) +AC_SUBST([PLATFORM_OBJS]) + +# -I${DLINCLDIR} is added to the compile rule for importdl.o +AC_SUBST([DLINCLDIR]) +DLINCLDIR=. + +# the dlopen() function means we might want to use dynload_shlib.o. some +# platforms have dlopen(), but don't want to use it. +AC_CHECK_FUNCS([dlopen]) + +# Used by ctypes.util.dllist(). +AC_CHECK_FUNCS([dl_iterate_phdr]) + +# DYNLOADFILE specifies which dynload_*.o file we will use for dynamic +# loading of modules. +AC_SUBST([DYNLOADFILE]) +AC_MSG_CHECKING([DYNLOADFILE]) +if test -z "$DYNLOADFILE" +then + case $ac_sys_system/$ac_sys_release in + hp*|HP*) DYNLOADFILE="dynload_hpux.o";; + *) + # use dynload_shlib.c and dlopen() if we have it; otherwise stub + # out any dynamic loading + if test "$ac_cv_func_dlopen" = yes + then DYNLOADFILE="dynload_shlib.o" + else DYNLOADFILE="dynload_stub.o" + fi + ;; + esac +fi +AC_MSG_RESULT([$DYNLOADFILE]) +if test "$DYNLOADFILE" != "dynload_stub.o" +then + AC_DEFINE([HAVE_DYNAMIC_LOADING], [1], + [Defined when any dynamic module loading is enabled.]) +fi + +# MACHDEP_OBJS can be set to platform-specific object files needed by Python + +AC_SUBST([MACHDEP_OBJS]) +AC_MSG_CHECKING([MACHDEP_OBJS]) +if test -z "$MACHDEP_OBJS" +then + MACHDEP_OBJS=$extra_machdep_objs +else + MACHDEP_OBJS="$MACHDEP_OBJS $extra_machdep_objs" +fi +if test -z "$MACHDEP_OBJS"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$MACHDEP_OBJS]) +fi + +if test "$ac_sys_system" = "Linux-android"; then + # When these functions are used in an unprivileged process, they crash rather + # than returning an error. + blocked_funcs="chroot initgroups setegid seteuid setgid sethostname + setregid setresgid setresuid setreuid setuid" + + # These functions are unimplemented and always return an error + # (https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android13-release/public/domain.te#1044) + blocked_funcs="$blocked_funcs sem_open sem_unlink" + + # Before API level 23, when fchmodat is called with the unimplemented flag + # AT_SYMLINK_NOFOLLOW, instead of returning ENOTSUP as it should, it actually + # follows the symlink. + if test "$ANDROID_API_LEVEL" -lt 23; then + blocked_funcs="$blocked_funcs fchmodat" + fi + + for name in $blocked_funcs; do + AS_VAR_PUSHDEF([func_var], [ac_cv_func_$name]) + AS_VAR_SET([func_var], [no]) + AS_VAR_POPDEF([func_var]) + done +fi + +# checks for library functions +AC_CHECK_FUNCS([ \ + accept4 alarm bind_textdomain_codeset chmod chown clearenv \ + clock closefrom close_range confstr \ + copy_file_range ctermid dladdr dup execv explicit_bzero explicit_memset \ + faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ + fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ + gai_strerror getdents64 getegid geteuid getgid getgrent getgrgid getgrgid_r \ + getgrnam_r getgrouplist gethostname getitimer getloadavg getlogin getlogin_r \ + getpeername getpgid getpid getppid getpriority _getpty \ + getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ + getspnam gettid getuid getwd grantpt if_indextoname if_nameindex \ + if_nametoindex initgroups kill killpg lchown linkat \ + lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ + mknod mknodat mktime mmap mremap nice openat opendir pathconf pause \ + pidfd_open pidfd_getfd pidfd_send_signal pipe \ + plock poll ppoll posix_fadvise posix_fallocate posix_openpt posix_spawn posix_spawnp \ + posix_spawn_file_actions_addclosefrom_np \ + pread preadv preadv2 process_vm_readv \ + pthread_cond_timedwait_relative_np pthread_condattr_setclock pthread_init \ + pthread_kill pthread_get_name_np pthread_getname_np pthread_set_name_np \ + pthread_setname_np pthread_getattr_np \ + ptsname ptsname_r pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ + rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \ + sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ + sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \ + setitimer setlocale setpgid setpgrp setpriority setregid setresgid \ + setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \ + sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ + sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ + sysconf sysctlbyname tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ + tmpnam tmpnam_r truncate ttyname_r umask uname unlinkat unlockpt utimensat utimes vfork \ + wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \ +]) + +# os.statx uses Linux's statx function. AIX also has a function named statx, +# but it's unrelated. Check only on Linux (including Android). +AS_CASE([$ac_sys_system], + [Linux*], [AC_CHECK_FUNCS([statx])] +) + +# Force lchmod off for Linux. Linux disallows changing the mode of symbolic +# links. Some libc implementations have a stub lchmod implementation that always +# returns an error. +if test "$MACHDEP" != linux; then + AC_CHECK_FUNCS([lchmod]) +fi + +# iOS defines some system methods that can be linked (so they are +# found by configure), but either raise a compilation error (because the +# header definition prevents usage - autoconf doesn't use the headers), or +# raise an error if used at runtime. Force these symbols off. +if test "$ac_sys_system" != "iOS" ; then + AC_CHECK_FUNCS([dup3 getentropy getgroups pipe2 system]) +fi + +AC_CHECK_DECL([dirfd], + [AC_DEFINE([HAVE_DIRFD], [1], + [Define if you have the 'dirfd' function or macro.])], + [], + [@%:@include <sys/types.h> + @%:@include <dirent.h>]) + +# For some functions, having a definition is not sufficient, since +# we want to take their address. +PY_CHECK_FUNC([chroot], [@%:@include <unistd.h>]) +PY_CHECK_FUNC([link], [@%:@include <unistd.h>]) +PY_CHECK_FUNC([symlink], [@%:@include <unistd.h>]) +PY_CHECK_FUNC([fchdir], [@%:@include <unistd.h>]) +PY_CHECK_FUNC([fsync], [@%:@include <unistd.h>]) +PY_CHECK_FUNC([fdatasync], [@%:@include <unistd.h>]) + +AC_MSG_CHECKING([for --disable-epoll]) +AC_ARG_ENABLE([epoll], + [AS_HELP_STRING([--disable-epoll], [disable epoll (default is yes if supported)])], + [AS_VAR_IF([enable_epoll], [no], [disable_epoll=yes], [disable_epoll=no])], + [disable_epoll=no] +) +AC_MSG_RESULT([$disable_epoll]) +if test "$disable_epoll" = "no" +then + PY_CHECK_FUNC([epoll_create], [@%:@include <sys/epoll.h>], [HAVE_EPOLL]) + PY_CHECK_FUNC([epoll_create1], [@%:@include <sys/epoll.h>]) +fi + +PY_CHECK_FUNC([kqueue],[ +#include <sys/types.h> +#include <sys/event.h> +]) +PY_CHECK_FUNC([prlimit], [ +#include <sys/time.h> +#include <sys/resource.h> +]) + +PY_CHECK_FUNC([_dyld_shared_cache_contains_path], [@%:@include <mach-o/dyld.h>], [HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH]) + +PY_CHECK_FUNC([memfd_create], [ +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif +#ifdef HAVE_SYS_MEMFD_H +#include <sys/memfd.h> +#endif +]) + +PY_CHECK_FUNC([eventfd], [ +#ifdef HAVE_SYS_EVENTFD_H +#include <sys/eventfd.h> +#endif +]) + +PY_CHECK_FUNC([timerfd_create], [ +#ifdef HAVE_SYS_TIMERFD_H +#include <sys/timerfd.h> +#endif +], +[HAVE_TIMERFD_CREATE]) + +# On some systems (eg. FreeBSD 5), we would find a definition of the +# functions ctermid_r, setgroups in the library, but no prototype +# (e.g. because we use _XOPEN_SOURCE). See whether we can take their +# address to avoid compiler warnings and potential miscompilations +# because of the missing prototypes. + +PY_CHECK_FUNC([ctermid_r], [@%:@include <stdio.h>]) + +AC_CACHE_CHECK([for flock declaration], [ac_cv_flock_decl], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [@%:@include <sys/file.h>], + [void* p = flock] + )], + [ac_cv_flock_decl=yes], + [ac_cv_flock_decl=no] + ) +]) +dnl Linking with libbsd may be necessary on AIX for flock function. +AS_VAR_IF([ac_cv_flock_decl], [yes], + [AC_CHECK_FUNCS([flock], [], + [AC_CHECK_LIB([bsd], [flock], [FCNTL_LIBS="-lbsd"])])]) + +PY_CHECK_FUNC([getpagesize], [@%:@include <unistd.h>]) + +AC_CACHE_CHECK([for broken unsetenv], [ac_cv_broken_unsetenv], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [@%:@include <stdlib.h>], + [int res = unsetenv("DUMMY")])], + [ac_cv_broken_unsetenv=no], + [ac_cv_broken_unsetenv=yes] + ) +]) +AS_VAR_IF([ac_cv_broken_unsetenv], [yes], [ + AC_DEFINE([HAVE_BROKEN_UNSETENV], [1], + [Define if 'unsetenv' does not return an int.]) +]) + +dnl check for true +AC_CHECK_PROGS([TRUE], [true], [/bin/true]) + +dnl On some systems (e.g. Solaris), hstrerror and inet_aton are in -lresolv +dnl On others, they are in the C library, so we to take no action +AC_CHECK_LIB([c], [inet_aton], [$ac_cv_prog_TRUE], + AC_CHECK_LIB([resolv], [inet_aton], [SOCKET_LIBS="-lresolv"]) +) +AC_CHECK_LIB([c], [hstrerror], [$ac_cv_prog_TRUE], + AC_CHECK_LIB([resolv], [hstrerror], [SOCKET_LIBS="-lresolv"]) +) + +# On Tru64, chflags seems to be present, but calling it will +# exit Python +AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/stat.h> +#include <unistd.h> +int main(int argc, char *argv[]) +{ + if(chflags(argv[0], 0) != 0) + return 1; + return 0; +} +]])], +[ac_cv_have_chflags=yes], +[ac_cv_have_chflags=no], +[ac_cv_have_chflags=cross]) +]) +if test "$ac_cv_have_chflags" = cross ; then + AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"]) +fi +if test "$ac_cv_have_chflags" = yes ; then + AC_DEFINE([HAVE_CHFLAGS], [1], + [Define to 1 if you have the 'chflags' function.]) +fi + +AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/stat.h> +#include <unistd.h> +int main(int argc, char *argv[]) +{ + if(lchflags(argv[0], 0) != 0) + return 1; + return 0; +} +]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) +]) +if test "$ac_cv_have_lchflags" = cross ; then + AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"]) +fi +if test "$ac_cv_have_lchflags" = yes ; then + AC_DEFINE([HAVE_LCHFLAGS], [1], + [Define to 1 if you have the 'lchflags' function.]) +fi + +dnl Check for compression libraries +AH_TEMPLATE([HAVE_ZLIB_COPY], [Define if the zlib library has inflateCopy]) + +AC_MSG_CHECKING([for --with-zlib]) +AC_ARG_WITH( + [zlib], + [AS_HELP_STRING([--with(out)-zlib@<:@=zlib|zlib-ng|zlib-rs|no@:>@], + [select the zlib implementation to link against, or disable + zlib support (default: auto)])], + [AS_CASE([$with_zlib], + [yes|auto], [with_zlib=auto], + [zlib|zlib-ng|zlib-rs|no], [], + [AC_MSG_ERROR([proper usage is --with(out)-zlib@<:@=zlib|zlib-ng|zlib-rs|no@:>@])])], + [with_zlib=auto]) +AC_MSG_RESULT([$with_zlib]) + +dnl detect zlib from Emscripten emport +AS_CASE([$with_zlib], [auto|zlib], [PY_CHECK_EMSCRIPTEN_PORT([ZLIB], [-sUSE_ZLIB])]) + +AS_VAR_IF([with_zlib], [zlib-rs], [ + AS_VAR_SET([zlib_name], ["libz_rs"]) + AS_VAR_SET([zlib_version], ["0.6.0"]) + AS_VAR_SET([zlib_libname], ["z_rs"]) +], [ + AS_VAR_SET([zlib_name], ["zlib"]) + AS_VAR_SET([zlib_version], ["1.2.2.1"]) + AS_VAR_SET([zlib_libname], ["z"]) +]) + +AS_VAR_IF([with_zlib], [no], [have_zlib=no], [ +PKG_CHECK_MODULES([ZLIB], [$zlib_name >= $zlib_version], [ + have_zlib=yes + dnl zlib 1.2.0 (2003) added inflateCopy + AC_DEFINE([HAVE_ZLIB_COPY], [1]) +], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LIBS="$LIBS $ZLIB_LIBS" + AC_CHECK_HEADERS([zlib.h], [ + PY_CHECK_LIB([$zlib_libname], [gzread], [have_zlib=yes], [have_zlib=no]) + ], [have_zlib=no]) + AS_VAR_IF([have_zlib], [yes], [ + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} + PY_CHECK_LIB([$zlib_libname], [inflateCopy], [AC_DEFINE([HAVE_ZLIB_COPY], [1])]) + ]) + ]) +]) +]) + +AS_VAR_IF([with_zlib], [zlib-ng], [AS_VAR_IF([have_zlib], [yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + AC_CHECK_DECL([ZLIBNG_VERSION], [], + [AC_MSG_ERROR([--with-zlib=zlib-ng: the detected zlib library is not zlib-ng])], + [@%:@include <zlib.h>]) + ]) +])]) + +AS_CASE([$with_zlib], + [auto|no], [], + [AS_VAR_IF([have_zlib], [no], + [AC_MSG_ERROR([--with-zlib=$with_zlib requested but $zlib_name was not found])])]) + +dnl binascii can use zlib for optimized crc32. +AS_VAR_IF([have_zlib], [yes], [ + BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" + BINASCII_LIBS="$ZLIB_LIBS" +]) + +AC_MSG_CHECKING([for --with-bzip2]) +AC_ARG_WITH( + [bzip2], + [AS_HELP_STRING([--with(out)-bzip2@<:@=bzip2|bzip2-rs|no@:>@], + [select the bzip2 implementation to link against, or disable + bzip2 support (default: auto)])], + [AS_CASE([$with_bzip2], + [yes|auto], [with_bzip2=auto], + [bzip2|bzip2-rs|no], [], + [AC_MSG_ERROR([proper usage is --with(out)-bzip2@<:@=bzip2|bzip2-rs|no@:>@])])], + [with_bzip2=auto]) +AC_MSG_RESULT([$with_bzip2]) + +dnl detect bzip2 from Emscripten emport +AS_CASE([$with_bzip2], [auto|bzip2], [PY_CHECK_EMSCRIPTEN_PORT([BZIP2], [-sUSE_BZIP2])]) + +AS_VAR_IF([with_bzip2], [bzip2-rs], [ + AS_VAR_SET([bzip2_name], ["libbz2_rs"]) + AS_VAR_SET([bzip2_libname], ["bz2_rs"]) +], [ + AS_VAR_SET([bzip2_name], ["bzip2"]) + AS_VAR_SET([bzip2_libname], ["bz2"]) +]) + +AS_VAR_IF([with_bzip2], [no], [have_bzip2=no], [ +PKG_CHECK_MODULES([BZIP2], [$bzip2_name], [have_bzip2=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LIBS="$LIBS $BZIP2_LIBS" + AC_CHECK_HEADERS([bzlib.h], [ + AC_CHECK_LIB([$bzip2_libname], [BZ2_bzCompress], [have_bzip2=yes], [have_bzip2=no]) + ], [have_bzip2=no]) + AS_VAR_IF([have_bzip2], [yes], [ + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} + ]) + ]) +]) +]) + +AS_CASE([$with_bzip2], + [auto|no], [], + [AS_VAR_IF([have_bzip2], [no], + [AC_MSG_ERROR([--with-bzip2=$with_bzip2 requested but $bzip2_name was not found])])]) + +PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LIBS="$LIBS $LIBLZMA_LIBS" + AC_CHECK_HEADERS([lzma.h], [ + AC_CHECK_LIB([lzma], [lzma_easy_encoder], [have_liblzma=yes], [have_liblzma=no]) + ], [have_liblzma=no]) + AS_VAR_IF([have_liblzma], [yes], [ + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + ]) + ]) +]) + +dnl zstd 1.4.5 stabilised ZDICT_finalizeDictionary +PKG_CHECK_MODULES([LIBZSTD], [libzstd >= 1.4.5], [have_libzstd=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBZSTD_CFLAGS" + CFLAGS="$CFLAGS $LIBZSTD_CFLAGS" + LIBS="$LIBS $LIBZSTD_LIBS" + AC_SEARCH_LIBS([ZDICT_finalizeDictionary], [zstd], [ + AC_MSG_CHECKING([ZSTD_VERSION_NUMBER >= 1.4.5]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([@%:@include "zstd.h"], [ + #if ZSTD_VERSION_NUMBER < 10405 + # error "zstd version is too old" + #endif + ]) + ], [ + AC_MSG_RESULT([yes]) + AC_CHECK_HEADERS([zstd.h zdict.h], [have_libzstd=yes], [have_libzstd=no]) + ], [ + AC_MSG_RESULT([no]) + have_libzstd=no + ]) + ], [have_libzstd=no]) + AS_VAR_IF([have_libzstd], [yes], [ + LIBZSTD_CFLAGS=${LIBZSTD_CFLAGS-""} + LIBZSTD_LIBS=${LIBZSTD_LIBS-"-lzstd"} + ]) + ]) +]) + +dnl _remote_debugging module: optional zstd compression support +dnl The module always builds, but zstd compression is only available when libzstd is found +AS_VAR_IF([have_libzstd], [yes], [ + REMOTE_DEBUGGING_CFLAGS="-DHAVE_ZSTD $LIBZSTD_CFLAGS" + REMOTE_DEBUGGING_LIBS="$LIBZSTD_LIBS" +], [ + REMOTE_DEBUGGING_CFLAGS="" + REMOTE_DEBUGGING_LIBS="" +]) +AC_SUBST([REMOTE_DEBUGGING_CFLAGS]) +AC_SUBST([REMOTE_DEBUGGING_LIBS]) + +dnl PY_CHECK_NETDB_FUNC(FUNCTION) +AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [@%:@include <netdb.h>])]) + +PY_CHECK_NETDB_FUNC([hstrerror]) +dnl not available in WASI yet +PY_CHECK_NETDB_FUNC([getservbyname]) +PY_CHECK_NETDB_FUNC([getservbyport]) +PY_CHECK_NETDB_FUNC([gethostbyname]) +PY_CHECK_NETDB_FUNC([gethostbyaddr]) +PY_CHECK_NETDB_FUNC([getprotobyname]) + +dnl PY_CHECK_SOCKET_FUNC(FUNCTION) +AC_DEFUN([PY_CHECK_SOCKET_FUNC], [PY_CHECK_FUNC([$1], [ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +])]) + +PY_CHECK_SOCKET_FUNC([inet_aton]) +PY_CHECK_SOCKET_FUNC([inet_ntoa]) +PY_CHECK_SOCKET_FUNC([inet_pton]) +dnl not available in WASI yet +PY_CHECK_SOCKET_FUNC([getpeername]) +PY_CHECK_SOCKET_FUNC([getsockname]) +PY_CHECK_SOCKET_FUNC([accept]) +PY_CHECK_SOCKET_FUNC([bind]) +PY_CHECK_SOCKET_FUNC([connect]) +PY_CHECK_SOCKET_FUNC([listen]) +PY_CHECK_SOCKET_FUNC([recvfrom]) +PY_CHECK_SOCKET_FUNC([sendto]) +PY_CHECK_SOCKET_FUNC([setsockopt]) +PY_CHECK_SOCKET_FUNC([socket]) + +# On some systems, setgroups is in unistd.h, on others, in grp.h +PY_CHECK_FUNC([setgroups], [ +#include <unistd.h> +#ifdef HAVE_GRP_H +#include <grp.h> +#endif +]) + +AC_CHECK_DECL([MAXLOGNAME], + [AC_DEFINE([HAVE_MAXLOGNAME], [1], + [Define if you have the 'MAXLOGNAME' constant.])], + [], + [@%:@include <sys/param.h>]) + +AC_CHECK_DECLS([UT_NAMESIZE], + [AC_DEFINE([HAVE_UT_NAMESIZE], [1], + [Define if you have the 'HAVE_UT_NAMESIZE' constant.])], + [], + [@%:@include <utmp.h>]) +# musl libc redefines struct prctl_mm_map and conflicts with linux/prctl.h +AS_IF([test "$ac_cv_libc" != musl], [ +AC_CHECK_DECLS([PR_SET_VMA_ANON_NAME], + [AC_DEFINE([_Py_HAVE_PR_SET_VMA_ANON_NAME], [1], + [Define if you have the 'PR_SET_VMA_ANON_NAME' constant.])], + [], + [@%:@include <linux/prctl.h> + @%:@include <sys/prctl.h>]) +]) +# check for openpty, login_tty, and forkpty + +AC_CHECK_FUNCS([openpty], [], + [AC_CHECK_LIB([util], [openpty], + [AC_DEFINE([HAVE_OPENPTY]) LIBS="$LIBS -lutil"], + [AC_CHECK_LIB([bsd], [openpty], + [AC_DEFINE([HAVE_OPENPTY]) LIBS="$LIBS -lbsd"])])]) +AC_SEARCH_LIBS([login_tty], [util], + [AC_DEFINE([HAVE_LOGIN_TTY], [1], [Define to 1 if you have the `login_tty' function.])] +) +AC_CHECK_FUNCS([forkpty], [], + [AC_CHECK_LIB([util], [forkpty], + [AC_DEFINE([HAVE_FORKPTY]) LIBS="$LIBS -lutil"], + [AC_CHECK_LIB([bsd], [forkpty], + [AC_DEFINE([HAVE_FORKPTY]) LIBS="$LIBS -lbsd"])])]) + +# check for long file support functions +AC_CHECK_FUNCS([fseek64 fseeko fstatvfs ftell64 ftello statvfs]) + +AC_REPLACE_FUNCS([dup2]) +AC_CHECK_FUNCS([getpgrp], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([@%:@include <unistd.h>], + [getpgrp(0);])], + [AC_DEFINE([GETPGRP_HAVE_ARG], [1], + [Define if getpgrp() must be called as getpgrp(0).])], + [])]) +AC_CHECK_FUNCS([setpgrp], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([@%:@include <unistd.h>], + [setpgrp(0,0);])], + [AC_DEFINE([SETPGRP_HAVE_ARG], [1], + [Define if setpgrp() must be called as setpgrp(0, 0).])], + [])]) + +# check for namespace functions +AC_CHECK_FUNCS([setns unshare]) + +AC_CHECK_FUNCS([clock_gettime], [], [ + AC_CHECK_LIB([rt], [clock_gettime], [ + LIBS="$LIBS -lrt" + AC_DEFINE([HAVE_CLOCK_GETTIME], [1]) + AC_DEFINE([TIMEMODULE_LIB], [rt], + [Library needed by timemodule.c: librt may be needed for clock_gettime()]) + ]) +]) + +AC_CHECK_FUNCS([clock_getres], [], [ + AC_CHECK_LIB([rt], [clock_getres], [ + AC_DEFINE([HAVE_CLOCK_GETRES], [1]) + ]) +]) + +# On Android and iOS, clock_settime can be linked (so it is found by +# configure), but when used in an unprivileged process, it crashes rather than +# returning an error. Force the symbol off. +if test "$ac_sys_system" != "Linux-android" && test "$ac_sys_system" != "iOS" +then + AC_CHECK_FUNCS([clock_settime], [], [ + AC_CHECK_LIB([rt], [clock_settime], [ + AC_DEFINE([HAVE_CLOCK_SETTIME], [1]) + ]) + ]) +fi + +# On Android before API level 23, clock_nanosleep returns the wrong value when +# interrupted by a signal (https://issuetracker.google.com/issues/216495770). +if ! { test "$ac_sys_system" = "Linux-android" && + test "$ANDROID_API_LEVEL" -lt 23; }; then + AC_CHECK_FUNCS([clock_nanosleep], [], [ + AC_CHECK_LIB([rt], [clock_nanosleep], [ + AC_DEFINE([HAVE_CLOCK_NANOSLEEP], [1]) + ]) + ]) +fi + +AC_CHECK_FUNCS([nanosleep], [], [ + AC_CHECK_LIB([rt], [nanosleep], [ + AC_DEFINE([HAVE_NANOSLEEP], [1]) + ]) +]) + +AC_CACHE_CHECK([for major, minor, and makedev], [ac_cv_device_macros], [ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if defined(MAJOR_IN_MKDEV) +#include <sys/mkdev.h> +#elif defined(MAJOR_IN_SYSMACROS) +#include <sys/types.h> +#include <sys/sysmacros.h> +#else +#include <sys/types.h> +#endif +]], [[ + makedev(major(0),minor(0)); +]])],[ac_cv_device_macros=yes], [ac_cv_device_macros=no]) +]) +AS_VAR_IF([ac_cv_device_macros], [yes], [ + AC_DEFINE([HAVE_DEVICE_MACROS], [1], + [Define to 1 if you have the device macros.]) +]) + +dnl no longer used, now always defined for backwards compatibility +AC_DEFINE([SYS_SELECT_WITH_SYS_TIME], [1], + [Define if you can safely include both <sys/select.h> and <sys/time.h> + (which you can't on SCO ODT 3.0).]) + +# On OSF/1 V5.1, getaddrinfo is available, but a define +# for [no]getaddrinfo in netdb.h. +AC_CACHE_CHECK([for getaddrinfo], [ac_cv_func_getaddrinfo], [ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +]], [[getaddrinfo(NULL, NULL, NULL, NULL);]])], +[ac_cv_func_getaddrinfo=yes], +[ac_cv_func_getaddrinfo=no]) +]) + +AS_VAR_IF([ac_cv_func_getaddrinfo], [yes], [ + AC_CACHE_CHECK([getaddrinfo bug], [ac_cv_buggy_getaddrinfo], + AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +#include <stdio.h> +#include <sys/types.h> +#include <netdb.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> + +int main(void) +{ + int passive, gaierr, inet4 = 0, inet6 = 0; + struct addrinfo hints, *ai, *aitop; + char straddr[INET6_ADDRSTRLEN], strport[16]; + + for (passive = 0; passive <= 1; passive++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = passive ? AI_PASSIVE : 0; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { + (void)gai_strerror(gaierr); + goto bad; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_addr == NULL || + ai->ai_addrlen == 0 || + getnameinfo(ai->ai_addr, ai->ai_addrlen, + straddr, sizeof(straddr), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + goto bad; + } + switch (ai->ai_family) { + case AF_INET: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "0.0.0.0") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "127.0.0.1") != 0) { + goto bad; + } + } + inet4++; + break; + case AF_INET6: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "::") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "::1") != 0) { + goto bad; + } + } + inet6++; + break; + case AF_UNSPEC: + goto bad; + break; + default: + /* another family support? */ + break; + } + } + freeaddrinfo(aitop); + aitop = NULL; + } + + if (!(inet4 == 0 || inet4 == 2)) + goto bad; + if (!(inet6 == 0 || inet6 == 2)) + goto bad; + + if (aitop) + freeaddrinfo(aitop); + return 0; + + bad: + if (aitop) + freeaddrinfo(aitop); + return 1; +} +]]])], +[ac_cv_buggy_getaddrinfo=no], +[ac_cv_buggy_getaddrinfo=yes], +[ +if test "$ac_sys_system" = "Linux-android" || test "$ac_sys_system" = "iOS"; then + ac_cv_buggy_getaddrinfo="no" +elif test "${enable_ipv6+set}" = set; then + ac_cv_buggy_getaddrinfo="no -- configured with --(en|dis)able-ipv6" +else + ac_cv_buggy_getaddrinfo=yes +fi])) + +dnl if ac_cv_func_getaddrinfo +]) + +if test "$ac_cv_func_getaddrinfo" = no -o "$ac_cv_buggy_getaddrinfo" = yes +then + AS_VAR_IF([ipv6], [yes], [ + AC_MSG_ERROR([m4_normalize([ + You must get working getaddrinfo() function + or pass the "--disable-ipv6" option to configure. + ])]) + ]) +else + AC_DEFINE([HAVE_GETADDRINFO], [1], + [Define if you have the getaddrinfo function.]) +fi + +AC_CHECK_FUNCS([getnameinfo]) + +# checks for structures +AC_STRUCT_TM +AC_STRUCT_TIMEZONE +AC_CHECK_MEMBERS([struct stat.st_rdev]) +AC_CHECK_MEMBERS([struct stat.st_blksize]) +AC_CHECK_MEMBERS([struct stat.st_flags]) +AC_CHECK_MEMBERS([struct stat.st_gen]) +AC_CHECK_MEMBERS([struct stat.st_birthtime]) +AC_CHECK_MEMBERS([struct stat.st_blocks]) +AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_passwd], [], [], [[ + #include <sys/types.h> + #include <pwd.h> +]]) +# Issue #21085: In Cygwin, siginfo_t does not have si_band field. +AC_CHECK_MEMBERS([siginfo_t.si_band], [], [], [[@%:@include <signal.h>]]) + +if test "$ac_cv_func_statx" = yes; then + # Some systems have the definitions of the mask bits without having the + # corresponding members in struct statx. Check for members added after Linux + # 4.11 (when statx itself was added). + AC_CHECK_MEMBERS([struct statx.stx_mnt_id]) + AC_CHECK_MEMBERS([struct statx.stx_dio_mem_align]) + # stx_dio_offset_align was added together with stx_dio_mem_align + AC_CHECK_MEMBERS([struct statx.stx_subvol]) + AC_CHECK_MEMBERS([struct statx.stx_atomic_write_unit_min]) + # stx_atomic_write_unit_max and stx_atomic_write_segments_max were added + # together with stx_atomic_write_unit_min + AC_CHECK_MEMBERS([struct statx.stx_dio_read_offset_align]) + # stx_atomic_write_unit_max_opt was added in Linux 6.16, but is controlled by + # the STATX_WRITE_ATOMIC mask bit added in Linux 6.11, so having the mask bit + # doesn't imply having the member. + AC_CHECK_MEMBERS([struct statx.stx_atomic_write_unit_max_opt]) +fi + +AC_CACHE_CHECK([for time.h that defines altzone], [ac_cv_header_time_altzone], [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <time.h>]], [[return altzone;]])], + [ac_cv_header_time_altzone=yes], + [ac_cv_header_time_altzone=no]) + ]) +if test $ac_cv_header_time_altzone = yes; then + AC_DEFINE([HAVE_ALTZONE], [1], + [Define this if your time.h defines altzone.]) +fi + +AC_CACHE_CHECK([for addrinfo], [ac_cv_struct_addrinfo], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <netdb.h>]], [[struct addrinfo a]])], + [ac_cv_struct_addrinfo=yes], + [ac_cv_struct_addrinfo=no])) +if test $ac_cv_struct_addrinfo = yes; then + AC_DEFINE([HAVE_ADDRINFO], [1], [struct addrinfo (netdb.h)]) +fi + +AC_CACHE_CHECK([for sockaddr_storage], [ac_cv_struct_sockaddr_storage], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +# include <sys/types.h> +@%:@ include <sys/socket.h>]], [[struct sockaddr_storage s]])], + [ac_cv_struct_sockaddr_storage=yes], + [ac_cv_struct_sockaddr_storage=no])) +if test $ac_cv_struct_sockaddr_storage = yes; then + AC_DEFINE([HAVE_SOCKADDR_STORAGE], [1], + [struct sockaddr_storage (sys/socket.h)]) +fi + +AC_CACHE_CHECK([for sockaddr_alg], [ac_cv_struct_sockaddr_alg], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +# include <sys/types.h> +# include <sys/socket.h> +@%:@ include <linux/if_alg.h>]], [[struct sockaddr_alg s]])], + [ac_cv_struct_sockaddr_alg=yes], + [ac_cv_struct_sockaddr_alg=no])) +if test $ac_cv_struct_sockaddr_alg = yes; then + AC_DEFINE([HAVE_SOCKADDR_ALG], [1], + [struct sockaddr_alg (linux/if_alg.h)]) +fi + +# checks for compiler characteristics + +AC_C_CONST + +AC_CACHE_CHECK([for working signed char], [ac_cv_working_signed_char_c], [ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[signed char c;]])], + [ac_cv_working_signed_char_c=yes], [ac_cv_working_signed_char_c=no]) +]) +AS_VAR_IF([ac_cv_working_signed_char_c], [no], [ + AC_DEFINE([signed], [], [Define to empty if the keyword does not work.]) +]) + +AC_CACHE_CHECK([for prototypes], [ac_cv_function_prototypes], [ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(int x) { return 0; }]], [[return foo(10);]])], + [ac_cv_function_prototypes=yes], [ac_cv_function_prototypes=no]) +]) +AS_VAR_IF([ac_cv_function_prototypes], [yes], [ + AC_DEFINE([HAVE_PROTOTYPES], [1], + [Define if your compiler supports function prototype]) +]) + + +# check for socketpair +PY_CHECK_FUNC([socketpair], [ +#include <sys/types.h> +#include <sys/socket.h> +]) + +# check if sockaddr has sa_len member +AC_CACHE_CHECK([if sockaddr has sa_len member], [ac_cv_struct_sockaddr_sa_len], [ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> +@%:@include <sys/socket.h>]], [[struct sockaddr x; +x.sa_len = 0;]])], + [ac_cv_struct_sockaddr_sa_len=yes], [ac_cv_struct_sockaddr_sa_len=no]) +]) +AS_VAR_IF([ac_cv_struct_sockaddr_sa_len], [yes], [ + AC_DEFINE([HAVE_SOCKADDR_SA_LEN], [1], + [Define if sockaddr has sa_len member]) +]) + +# sigh -- gethostbyname_r is a mess; it can have 3, 5 or 6 arguments :-( +AH_TEMPLATE([HAVE_GETHOSTBYNAME_R], + [Define this if you have some version of gethostbyname_r()]) + +AC_CHECK_FUNC([gethostbyname_r], + [AC_DEFINE([HAVE_GETHOSTBYNAME_R]) + AC_MSG_CHECKING([gethostbyname_r with 6 args]) + OLD_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS $MY_CPPFLAGS $MY_THREAD_CPPFLAGS $MY_CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +# include <netdb.h> + ]], [[ + char *name; + struct hostent *he, *res; + char buffer[2048]; + int buflen = 2048; + int h_errnop; + + (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop) + ]])],[ + AC_DEFINE([HAVE_GETHOSTBYNAME_R]) + AC_DEFINE([HAVE_GETHOSTBYNAME_R_6_ARG], [1], + [Define this if you have the 6-arg version of gethostbyname_r().]) + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_CHECKING([gethostbyname_r with 5 args]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +# include <netdb.h> + ]], [[ + char *name; + struct hostent *he; + char buffer[2048]; + int buflen = 2048; + int h_errnop; + + (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop) + ]])], + [ + AC_DEFINE([HAVE_GETHOSTBYNAME_R]) + AC_DEFINE([HAVE_GETHOSTBYNAME_R_5_ARG], [1], + [Define this if you have the 5-arg version of gethostbyname_r().]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + AC_MSG_CHECKING([gethostbyname_r with 3 args]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +# include <netdb.h> + ]], [[ + char *name; + struct hostent *he; + struct hostent_data data; + + (void) gethostbyname_r(name, he, &data); + ]])], + [ + AC_DEFINE([HAVE_GETHOSTBYNAME_R]) + AC_DEFINE([HAVE_GETHOSTBYNAME_R_3_ARG], [1], + [Define this if you have the 3-arg version of gethostbyname_r().]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + ]) + ]) + CFLAGS=$OLD_CFLAGS +], [ + AC_CHECK_FUNCS([gethostbyname]) +]) +AC_SUBST([HAVE_GETHOSTBYNAME_R_6_ARG]) +AC_SUBST([HAVE_GETHOSTBYNAME_R_5_ARG]) +AC_SUBST([HAVE_GETHOSTBYNAME_R_3_ARG]) +AC_SUBST([HAVE_GETHOSTBYNAME_R]) +AC_SUBST([HAVE_GETHOSTBYNAME]) + +# checks for system services +# (none yet) + +# Linux requires this for correct f.p. operations +AC_CHECK_FUNC([__fpu_control], + [], + [AC_CHECK_LIB([ieee], [__fpu_control]) +]) + +# check for --with-libm=... +AC_SUBST([LIBM]) +case $ac_sys_system in +Darwin) ;; +*) LIBM=-lm +esac +AC_MSG_CHECKING([for --with-libm=STRING]) +AC_ARG_WITH([libm], + [AS_HELP_STRING([--with-libm=STRING], [override libm math library to STRING (default is system-dependent)])], +[ +if test "$withval" = no +then LIBM= + AC_MSG_RESULT([force LIBM empty]) +elif test "$withval" != yes +then LIBM=$withval + AC_MSG_RESULT([set LIBM="$withval"]) +else AC_MSG_ERROR([proper usage is --with-libm=STRING]) +fi], +[AC_MSG_RESULT([default LIBM="$LIBM"])]) + +# check for --with-libc=... +AC_SUBST([LIBC]) +AC_MSG_CHECKING([for --with-libc=STRING]) +AC_ARG_WITH([libc], + [AS_HELP_STRING([--with-libc=STRING], [override libc C library to STRING (default is system-dependent)])], +[ +if test "$withval" = no +then LIBC= + AC_MSG_RESULT([force LIBC empty]) +elif test "$withval" != yes +then LIBC=$withval + AC_MSG_RESULT([set LIBC="$withval"]) +else AC_MSG_ERROR([proper usage is --with-libc=STRING]) +fi], +[AC_MSG_RESULT([default LIBC="$LIBC"])]) + +# ************************************** +# * Check for gcc x64 inline assembler * +# ************************************** + + +AC_CACHE_CHECK([for x64 gcc inline assembler], [ac_cv_gcc_asm_for_x64], [ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + __asm__ __volatile__ ("movq %rcx, %rax"); +]])],[ac_cv_gcc_asm_for_x64=yes],[ac_cv_gcc_asm_for_x64=no]) +]) + +AS_VAR_IF([ac_cv_gcc_asm_for_x64], [yes], [ + AC_DEFINE([HAVE_GCC_ASM_FOR_X64], [1], + [Define if we can use x64 gcc inline assembler]) +]) + +# ************************************************** +# * Check for various properties of floating point * +# ************************************************** + +AX_C_FLOAT_WORDS_BIGENDIAN( + [AC_DEFINE([DOUBLE_IS_BIG_ENDIAN_IEEE754], [1], + [Define if C doubles are 64-bit IEEE 754 binary format, + stored with the most significant byte first])], + [AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1], + [Define if C doubles are 64-bit IEEE 754 binary format, + stored with the least significant byte first])], + [AC_MSG_ERROR([m4_normalize([ + Unknown float word ordering. You need to manually + preset ax_cv_c_float_words_bigendian=no (or yes) + according to your system. + ])])]) + +# The short float repr introduced in Python 3.1 requires the +# correctly-rounded string <-> double conversion functions from +# Python/dtoa.c, which in turn require that the FPU uses 53-bit +# rounding; this is a problem on x86, where the x87 FPU has a default +# rounding precision of 64 bits. For gcc/x86, we can fix this by +# using inline assembler to get and set the x87 FPU control word. + +# This inline assembler syntax works for icx and may also work for +# suncc and icc, so we try it on all platforms. + +AC_CACHE_CHECK([whether we can use gcc inline assembler to get and set x87 control word], [ac_cv_gcc_asm_for_x87], [ +AC_LINK_IFELSE( [AC_LANG_PROGRAM([[]], [[ + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); +]])],[ac_cv_gcc_asm_for_x87=yes],[ac_cv_gcc_asm_for_x87=no]) +]) +AS_VAR_IF([ac_cv_gcc_asm_for_x87], [yes], [ + AC_DEFINE([HAVE_GCC_ASM_FOR_X87], [1], + [Define if we can use gcc inline assembler to get and set x87 control word]) +]) + +AC_CACHE_CHECK([whether we can use gcc inline assembler to get and set mc68881 fpcr], [ac_cv_gcc_asm_for_mc68881], [ +AC_LINK_IFELSE( [AC_LANG_PROGRAM([[]], [[ + unsigned int fpcr; + __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm" (fpcr)); + __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm" (fpcr)); +]])],[ac_cv_gcc_asm_for_mc68881=yes],[ac_cv_gcc_asm_for_mc68881=no]) +]) +AS_VAR_IF([ac_cv_gcc_asm_for_mc68881], [yes], [ + AC_DEFINE([HAVE_GCC_ASM_FOR_MC68881], [1], + [Define if we can use gcc inline assembler to get and set mc68881 fpcr]) +]) + +# Detect whether system arithmetic is subject to x87-style double +# rounding issues. The result of this test has little meaning on non +# IEEE 754 platforms. On IEEE 754, test should return 1 if rounding +# mode is round-to-nearest and double rounding issues are present, and +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. +AC_CACHE_CHECK([for x87-style double rounding], [ac_cv_x87_double_rounding], [ +# $BASECFLAGS may affect the result +ac_save_cc="$CC" +CC="$CC $BASECFLAGS" +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdlib.h> +#include <math.h> +int main(void) { + volatile double x, y, z; + /* 1./(1-2**-53) -> 1+2**-52 (correct), 1.0 (double rounding) */ + x = 0.99999999999999989; /* 1-2**-53 */ + y = 1./x; + if (y != 1.) + exit(0); + /* 1e16+2.99999 -> 1e16+2. (correct), 1e16+4. (double rounding) */ + x = 1e16; + y = 2.99999; + z = x + y; + if (z != 1e16+4.) + exit(0); + /* both tests show evidence of double rounding */ + exit(1); +} +]])], +[ac_cv_x87_double_rounding=no], +[ac_cv_x87_double_rounding=yes], +[ac_cv_x87_double_rounding=no]) +CC="$ac_save_cc" +]) + +AS_VAR_IF([ac_cv_x87_double_rounding], [yes], [ + AC_DEFINE([X87_DOUBLE_ROUNDING], [1], + [Define if arithmetic is subject to x87-style double rounding issue]) +]) + +# ************************************ +# * Check for mathematical functions * +# ************************************ + +LIBS_SAVE=$LIBS +LIBS="$LIBS $LIBM" + +AC_CHECK_FUNCS( + [acosh asinh atanh erf erfc expm1 log1p log2], + [], + [AC_MSG_ERROR([Python requires C99 compatible libm])] +) + +AC_CHECK_FUNCS_ONCE(acospi asinpi atanpi atan2pi cospi sinpi tanpi) +LIBS=$LIBS_SAVE + +dnl For multiprocessing module, check that sem_open +dnl actually works. For FreeBSD versions <= 7.2, +dnl the kernel module that provides POSIX semaphores +dnl isn't loaded by default, so an attempt to call +dnl sem_open results in a 'Signal 12' error. +AC_CACHE_CHECK([whether POSIX semaphores are enabled], [ac_cv_posix_semaphores_enabled], + AC_RUN_IFELSE([ + AC_LANG_SOURCE([ + #include <unistd.h> + #include <fcntl.h> + #include <stdio.h> + #include <semaphore.h> + #include <sys/stat.h> + + int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + sem_unlink("/autoconf"); + return 0; + } + ]) + ], + [ac_cv_posix_semaphores_enabled=yes], + [ac_cv_posix_semaphores_enabled=no], + [ac_cv_posix_semaphores_enabled=yes]) +) +AS_VAR_IF([ac_cv_posix_semaphores_enabled], [no], [ + AC_DEFINE( + [POSIX_SEMAPHORES_NOT_ENABLED], [1], + [Define if POSIX semaphores aren't enabled on your system] + ) +]) + +dnl Multiprocessing check for broken sem_getvalue +AC_CACHE_CHECK([for broken sem_getvalue], [ac_cv_broken_sem_getvalue], + AC_RUN_IFELSE([ + AC_LANG_SOURCE([ + #include <unistd.h> + #include <fcntl.h> + #include <stdio.h> + #include <semaphore.h> + #include <sys/stat.h> + + int main(void){ + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + sem_unlink("/autocftw"); + return res==-1 ? 1 : 0; + } + ]) + ], + [ac_cv_broken_sem_getvalue=no], + [ac_cv_broken_sem_getvalue=yes], + [ac_cv_broken_sem_getvalue=yes]) +) +AS_VAR_IF([ac_cv_broken_sem_getvalue], [yes], [ + AC_DEFINE( + [HAVE_BROKEN_SEM_GETVALUE], [1], + [define to 1 if your sem_getvalue is broken.] + ) +]) + +AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[@%:@include <dlfcn.h>]]) + +# determine what size digit to use for Python's longs +AC_MSG_CHECKING([digit size for Python's longs]) +AC_ARG_ENABLE([big-digits], +AS_HELP_STRING([--enable-big-digits@<:@=15|30@:>@],[use big digits (30 or 15 bits) for Python longs (default is 30)]]), +[case $enable_big_digits in +yes) + enable_big_digits=30 ;; +no) + enable_big_digits=15 ;; +[15|30]) + ;; +*) + AC_MSG_ERROR([bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30]) ;; +esac +AC_MSG_RESULT([$enable_big_digits]) +AC_DEFINE_UNQUOTED([PYLONG_BITS_IN_DIGIT], [$enable_big_digits], + [Define as the preferred size in bits of long digits]) +], +[AC_MSG_RESULT([no value specified])]) + +# check for wchar.h +AC_CHECK_HEADER([wchar.h], [ + AC_DEFINE([HAVE_WCHAR_H], [1], + [Define if the compiler provides a wchar.h header file.]) + wchar_h="yes" +], +wchar_h="no" +) + +# determine wchar_t size +if test "$wchar_h" = yes +then + AC_CHECK_SIZEOF([wchar_t], [4], [m4_normalize([ + #include <wchar.h> + ])]) +fi + +# check whether wchar_t is signed or not +if test "$wchar_h" = yes +then + # check whether wchar_t is signed or not + AC_CACHE_CHECK([whether wchar_t is signed], [ac_cv_wchar_t_signed], [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include <wchar.h> + int main() + { + /* Success: exit code 0 */ + return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1); + } + ]])], + [ac_cv_wchar_t_signed=yes], + [ac_cv_wchar_t_signed=no], + [ac_cv_wchar_t_signed=yes])]) +fi + +AC_MSG_CHECKING([whether wchar_t is usable]) +# wchar_t is only usable if it maps to an unsigned type +if test "$ac_cv_sizeof_wchar_t" -ge 2 \ + -a "$ac_cv_wchar_t_signed" = "no" +then + AC_DEFINE([HAVE_USABLE_WCHAR_T], [1], + [Define if you have a useable wchar_t type defined in wchar.h; useable + means wchar_t must be an unsigned type with at least 16 bits. (see + Include/unicodeobject.h).]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +case $ac_sys_system/$ac_sys_release in +SunOS/*) + if test -f /etc/os-release; then + OS_NAME=$(awk -F= '/^NAME=/ {print substr($2,2,length($2)-2)}' /etc/os-release) + if test "x$OS_NAME" = "xOracle Solaris"; then + # bpo-43667: In Oracle Solaris, the internal form of wchar_t in + # non-Unicode locales is not Unicode and hence cannot be used directly. + # https://docs.oracle.com/cd/E37838_01/html/E61053/gmwke.html + AC_DEFINE([HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION], [1], + [Define if the internal form of wchar_t in non-Unicode locales + is not Unicode.]) + fi + fi + ;; +esac + +# check for endianness +AC_C_BIGENDIAN + +# ABI version string for Python extension modules. This appears between the +# periods in shared library file names, e.g. foo.<SOABI>.so. It is calculated +# from the following attributes which affect the ABI of this Python build (in +# this order): +# +# * The Python implementation (always 'cpython-' for us) +# * The major and minor version numbers +# * --disable-gil (adds a 't') +# * --with-pydebug (adds a 'd') +# +# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, +# would get a shared library ABI version tag of 'cpython-32dmu' and shared +# libraries would be named 'foo.cpython-32dmu.so'. +# +# In Python 3.2 and older, --with-wide-unicode added a 'u' flag. +# In Python 3.7 and older, --with-pymalloc added a 'm' flag. +AC_SUBST([SOABI]) +AC_MSG_CHECKING([ABIFLAGS]) +AC_MSG_RESULT([$ABIFLAGS]) +AC_MSG_CHECKING([SOABI]) +SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${SOABI_PLATFORM:+-$SOABI_PLATFORM} +AC_MSG_RESULT([$SOABI]) + +# Release build, debug build (Py_DEBUG), and trace refs build (Py_TRACE_REFS) +# are ABI compatible +if test "$Py_DEBUG" = 'true'; then + # Similar to SOABI but remove "d" flag from ABIFLAGS + AC_SUBST([ALT_SOABI]) + ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${SOABI_PLATFORM:+-$SOABI_PLATFORM} + AC_DEFINE_UNQUOTED([ALT_SOABI], ["${ALT_SOABI}"], + [Alternative SOABI used in debug build to load C extensions built in release mode]) +fi + +AC_SUBST([EXT_SUFFIX]) +EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} + +AC_MSG_CHECKING([LDVERSION]) +LDVERSION='$(VERSION)$(ABIFLAGS)' +AC_MSG_RESULT([$LDVERSION]) + +# Configure the flags and dependencies used when compiling shared modules. +AC_SUBST([MODULE_DEPS_SHARED]) +AC_SUBST([LIBPYTHON]) +MODULE_DEPS_SHARED='$(MODULE_DEPS_STATIC) $(EXPORTSYMS)' + +# On most platforms, extension modules aren't linked against libpython, so +# LIBPYTHON must be empty. +LIBPYTHON='' + +# On Android and Cygwin the shared libraries must be linked with libpython. +# LIBPYTHON is used by python-config, python3.pc, the commands for building the +# stdlib's own extension modules, and external package build systems via +# sysconfig, so its value must be suitable for all those contexts. +if test "$PY_ENABLE_SHARED" = "1" && ( test -n "$ANDROID_API_LEVEL" || test "$MACHDEP" = "cygwin"); then + MODULE_DEPS_SHARED="$MODULE_DEPS_SHARED \$(LDLIBRARY)" + LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" +fi + +# On iOS the shared libraries must be linked with the Python framework +if test "$ac_sys_system" = "iOS"; then + MODULE_DEPS_SHARED="$MODULE_DEPS_SHARED \$(PYTHONFRAMEWORKDIR)/\$(PYTHONFRAMEWORK)" +fi + +# Check for --with-platlibdir +# /usr/$PLATLIBDIR/python$(VERSION)$(ABI_THREAD) +AC_SUBST([PLATLIBDIR]) +PLATLIBDIR="lib" # XXX: We should probably calculate the defauly from libdir, if defined. +AC_MSG_CHECKING([for --with-platlibdir]) +AC_ARG_WITH( + [platlibdir], + [AS_HELP_STRING( + [--with-platlibdir=DIRNAME], + [Python library directory name (default is "lib")] + )], +[ +# ignore 3 options: +# --with-platlibdir +# --with-platlibdir= +# --without-platlibdir +if test -n "$withval" -a "$withval" != yes -a "$withval" != no +then + AC_MSG_RESULT([yes]) + PLATLIBDIR="$withval" +else + AC_MSG_RESULT([no]) +fi], +[AC_MSG_RESULT([no])]) + +AC_SUBST([LIBDEST]) +AC_SUBST([BINLIBDEST]) +LIBDEST='${prefix}/${PLATLIBDIR}/python$(VERSION)$(ABI_THREAD)' +BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)$(ABI_THREAD)' + +dnl define LIBPL after ABIFLAGS and LDVERSION is defined. +AC_SUBST([PY_ENABLE_SHARED]) +if test x$PLATFORM_TRIPLET = x; then + LIBPL='$(LIBDEST)'"/config-${LDVERSION}" +else + LIBPL='$(LIBDEST)'"/config-${LDVERSION}-${PLATFORM_TRIPLET}" +fi +AC_SUBST([LIBPL]) + +# Check for --with-wheel-pkg-dir=PATH +AC_SUBST([WHEEL_PKG_DIR]) +WHEEL_PKG_DIR="" +AC_MSG_CHECKING([for --with-wheel-pkg-dir]) +AC_ARG_WITH( + [wheel-pkg-dir], + [AS_HELP_STRING( + [--with-wheel-pkg-dir=PATH], + [Directory of wheel packages used by ensurepip (default: none)] + )], +[ +if test -n "$withval"; then + AC_MSG_RESULT([yes]) + WHEEL_PKG_DIR="$withval" +else + AC_MSG_RESULT([no]) +fi], +[AC_MSG_RESULT([no])]) + +# Check whether right shifting a negative integer extends the sign bit +# or fills with zeros (like the Cray J90, according to Tim Peters). +AC_CACHE_CHECK([whether right shift extends the sign bit], [ac_cv_rshift_extends_sign], [ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +int main(void) +{ + return (((-1)>>3 == -1) ? 0 : 1); +} +]])], +[ac_cv_rshift_extends_sign=yes], +[ac_cv_rshift_extends_sign=no], +[ac_cv_rshift_extends_sign=yes])]) +if test "$ac_cv_rshift_extends_sign" = no +then + AC_DEFINE([SIGNED_RIGHT_SHIFT_ZERO_FILLS], [1], + [Define if i>>j for signed int i does not extend the sign bit + when i < 0]) +fi + +# check for getc_unlocked and related locking functions +AC_CACHE_CHECK([for getc_unlocked() and friends], [ac_cv_have_getc_unlocked], [ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <stdio.h>]], [[ + FILE *f = fopen("/dev/null", "r"); + flockfile(f); + getc_unlocked(f); + funlockfile(f); +]])],[ac_cv_have_getc_unlocked=yes],[ac_cv_have_getc_unlocked=no])]) +if test "$ac_cv_have_getc_unlocked" = yes +then + AC_DEFINE([HAVE_GETC_UNLOCKED], [1], + [Define this if you have flockfile(), getc_unlocked(), and funlockfile()]) +fi + +dnl Check for libreadline and libedit +dnl - libreadline provides "readline/readline.h" header and "libreadline" +dnl shared library. pkg-config file is readline.pc +dnl - libedit provides "editline/readline.h" header and "libedit" shared +dnl library. pkg-config file ins libedit.pc +dnl - editline is not supported ("readline.h" and "libeditline" shared library) +dnl +dnl NOTE: In the past we checked if readline needs an additional termcap +dnl library (tinfo ncursesw ncurses termcap). We now assume that libreadline +dnl or readline.pc provide correct linker information. + +AH_TEMPLATE([WITH_EDITLINE], [Define to build the readline module against libedit.]) + +AC_ARG_WITH( + [readline], + [AS_HELP_STRING([--with(out)-readline@<:@=editline|readline|no@:>@], + [use libedit for backend or disable readline module])], + [ + AS_CASE([$with_readline], + [editline|edit], [with_readline=edit], + [yes|readline], [with_readline=readline], + [no], [], + [AC_MSG_ERROR([proper usage is --with(out)-readline@<:@=editline|readline|no@:>@])] + ) + ], + [with_readline=readline] +) + +AS_VAR_IF([with_readline], [readline], [ + PKG_CHECK_MODULES([LIBREADLINE], [readline], [ + LIBREADLINE=readline + READLINE_CFLAGS=$LIBREADLINE_CFLAGS + READLINE_LIBS=$LIBREADLINE_LIBS + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LIBS="$LIBS $LIBREADLINE_LIBS" + AC_CHECK_HEADERS([readline/readline.h], [ + AC_CHECK_LIB([readline], [readline], [ + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + ], [with_readline=no]) + ], [with_readline=no]) + ]) + ]) +]) + +AS_VAR_IF([with_readline], [edit], [ + PKG_CHECK_MODULES([LIBEDIT], [libedit], [ + AC_DEFINE([WITH_EDITLINE], [1]) + LIBREADLINE=edit + READLINE_CFLAGS=$LIBEDIT_CFLAGS + READLINE_LIBS=$LIBEDIT_LIBS + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LIBS="$LIBS $LIBEDIT_LIBS" + AC_CHECK_HEADERS([editline/readline.h], [ + AC_CHECK_LIB([edit], [readline], [ + LIBREADLINE=edit + AC_DEFINE([WITH_EDITLINE], [1]) + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + ], [with_readline=no]) + ], [with_readline=no]) + ]) + ]) +]) + +dnl pyconfig.h defines _XOPEN_SOURCE=700 +READLINE_CFLAGS=$(echo $READLINE_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +AC_MSG_CHECKING([how to link readline]) +AS_VAR_IF([with_readline], [no], [ + AC_MSG_RESULT([no]) +], [ + AC_MSG_RESULT([$with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)]) + + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS" + LIBS="$LIBS $READLINE_LIBS" + LIBS_SAVE=$LIBS + + m4_define([readline_includes], [ + #include <stdio.h> /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include <editline/readline.h> + #else + # include <readline/readline.h> + # include <readline/history.h> + #endif + ]) + + # check for readline 2.2 + AC_CHECK_DECL([rl_completion_append_character], [ + AC_DEFINE([HAVE_RL_COMPLETION_APPEND_CHARACTER], [1], [Define if you have readline 2.2]) + ], [], [readline_includes]) + + AC_CHECK_DECL([rl_completion_suppress_append], [ + AC_DEFINE([HAVE_RL_COMPLETION_SUPPRESS_APPEND], [1], [Define if you have rl_completion_suppress_append]) + ], [], [readline_includes]) + + # check for readline 4.0 + AC_CACHE_CHECK([for rl_pre_input_hook in -l$LIBREADLINE], [ac_cv_readline_rl_pre_input_hook], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_pre_input_hook])], + [ac_cv_readline_rl_pre_input_hook=yes], [ac_cv_readline_rl_pre_input_hook=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_pre_input_hook], [yes], [ + AC_DEFINE([HAVE_RL_PRE_INPUT_HOOK], [1], [Define if you have readline 4.0]) + ]) + + # also in 4.0 + AC_CACHE_CHECK([for rl_completion_display_matches_hook in -l$LIBREADLINE], [ac_cv_readline_rl_completion_display_matches_hook], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_display_matches_hook])], + [ac_cv_readline_rl_completion_display_matches_hook=yes], [ac_cv_readline_rl_completion_display_matches_hook=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_completion_display_matches_hook], [yes], [ + AC_DEFINE([HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK], [1], [Define if you have readline 4.0]) + ]) + + # also in 4.0, but not in editline + AC_CACHE_CHECK([for rl_resize_terminal in -l$LIBREADLINE], [ac_cv_readline_rl_resize_terminal], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_resize_terminal])], + [ac_cv_readline_rl_resize_terminal=yes], [ac_cv_readline_rl_resize_terminal=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_resize_terminal], [yes], [ + AC_DEFINE([HAVE_RL_RESIZE_TERMINAL], [1], [Define if you have readline 4.0]) + ]) + + # rl_change_environment is in readline 6.3, but not in editline + AC_CACHE_CHECK([for rl_change_environment in -l$LIBREADLINE], [ac_cv_readline_rl_change_environment], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [int x = rl_change_environment])], + [ac_cv_readline_rl_change_environment=yes], [ac_cv_readline_rl_change_environment=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_change_environment], [yes], [ + AC_DEFINE([HAVE_RL_CHANGE_ENVIRONMENT], [1], [Define if you have readline 6.3]) + ]) + + # check for readline 4.2 + AC_CACHE_CHECK([for rl_completion_matches in -l$LIBREADLINE], [ac_cv_readline_rl_completion_matches], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_matches])], + [ac_cv_readline_rl_completion_matches=yes], [ac_cv_readline_rl_completion_matches=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_completion_matches], [yes], [ + AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], [1], [Define if you have readline 4.2]) + ]) + + # also in readline 4.2 + AC_CHECK_DECL([rl_catch_signals], [ + AC_DEFINE([HAVE_RL_CATCH_SIGNAL], [1], [Define if you can turn off readline's signal handling.]) + ], [], [readline_includes]) + + AC_CACHE_CHECK([for append_history in -l$LIBREADLINE], [ac_cv_readline_append_history], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = append_history])], + [ac_cv_readline_append_history=yes], [ac_cv_readline_append_history=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_append_history], [yes], [ + AC_DEFINE([HAVE_RL_APPEND_HISTORY], [1], [Define if readline supports append_history]) + ]) + + # in readline as well as newer editline (April 2023) + AC_CHECK_TYPES([rl_compdisp_func_t], [], [], [readline_includes]) + + # Some editline versions declare rl_startup_hook as taking no args, others + # declare it as taking 2. + AC_CACHE_CHECK([if rl_startup_hook takes arguments], [ac_cv_readline_rl_startup_hook_takes_args], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([readline_includes] + [extern int test_hook_func(const char *text, int state);], + [rl_startup_hook=test_hook_func;])], + [ac_cv_readline_rl_startup_hook_takes_args=yes], + [ac_cv_readline_rl_startup_hook_takes_args=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_startup_hook_takes_args], [yes], [ + AC_DEFINE([Py_RL_STARTUP_HOOK_TAKES_ARGS], [1], [Define if rl_startup_hook takes arguments]) + ]) + + m4_undefine([readline_includes]) + ])dnl WITH_SAVE_ENV() +]) + +AC_CACHE_CHECK([for broken nice()], [ac_cv_broken_nice], [ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdlib.h> +#include <unistd.h> +int main(void) +{ + int val1 = nice(1); + if (val1 != -1 && val1 == nice(2)) + exit(0); + exit(1); +} +]])], +[ac_cv_broken_nice=yes], +[ac_cv_broken_nice=no], +[ac_cv_broken_nice=no])]) +if test "$ac_cv_broken_nice" = yes +then + AC_DEFINE([HAVE_BROKEN_NICE], [1], + [Define if nice() returns success/failure instead of the new priority.]) +fi + +AC_CACHE_CHECK([for broken poll()], [ac_cv_broken_poll], +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <poll.h> +#include <unistd.h> + +int main(void) +{ + struct pollfd poll_struct = { 42, POLLIN|POLLPRI|POLLOUT, 0 }; + int poll_test; + + close (42); + + poll_test = poll(&poll_struct, 1, 0); + if (poll_test < 0) + return 0; + else if (poll_test == 0 && poll_struct.revents != POLLNVAL) + return 0; + else + return 1; +} +]])], +[ac_cv_broken_poll=yes], +[ac_cv_broken_poll=no], +[ac_cv_broken_poll=no])) +if test "$ac_cv_broken_poll" = yes +then + AC_DEFINE([HAVE_BROKEN_POLL], [1], + [Define if poll() sets errno on invalid file descriptors.]) +fi + +# check tzset(3) exists and works like we expect it to +AC_CACHE_CHECK([for working tzset()], [ac_cv_working_tzset], [ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdlib.h> +#include <time.h> +#include <string.h> + +#if HAVE_TZNAME +extern char *tzname[]; +#endif + +int main(void) +{ + /* Note that we need to ensure that not only does tzset(3) + do 'something' with localtime, but it works as documented + in the library reference and as expected by the test suite. + This includes making sure that tzname is set properly if + tm->tm_zone does not exist since it is the alternative way + of getting timezone info. + + Red Hat 6.2 doesn't understand the southern hemisphere + after New Year's Day. + */ + + time_t groundhogday = 1044144000; /* GMT-based */ + time_t midyear = groundhogday + (365 * 24 * 3600 / 2); + + putenv("TZ=UTC+0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 0) + exit(1); +#if HAVE_TZNAME + /* For UTC, tzname[1] is sometimes "", sometimes " " */ + if (strcmp(tzname[0], "UTC") || + (tzname[1][0] != 0 && tzname[1][0] != ' ')) + exit(1); +#endif + + putenv("TZ=EST+5EDT,M4.1.0,M10.5.0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 19) + exit(1); +#if HAVE_TZNAME + if (strcmp(tzname[0], "EST") || strcmp(tzname[1], "EDT")) + exit(1); +#endif + + putenv("TZ=AEST-10AEDT-11,M10.5.0,M3.5.0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 11) + exit(1); +#if HAVE_TZNAME + if (strcmp(tzname[0], "AEST") || strcmp(tzname[1], "AEDT")) + exit(1); +#endif + +#if HAVE_STRUCT_TM_TM_ZONE + if (strcmp(localtime(&groundhogday)->tm_zone, "AEDT")) + exit(1); + if (strcmp(localtime(&midyear)->tm_zone, "AEST")) + exit(1); +#endif + + exit(0); +} +]])], +[ac_cv_working_tzset=yes], +[ac_cv_working_tzset=no], +[ac_cv_working_tzset=no])]) +if test "$ac_cv_working_tzset" = yes +then + AC_DEFINE([HAVE_WORKING_TZSET], [1], + [Define if tzset() actually switches the local timezone in a meaningful way.]) +fi + +# Look for subsecond timestamps in struct stat +AC_CACHE_CHECK([for tv_nsec in struct stat], [ac_cv_stat_tv_nsec], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <sys/stat.h>]], [[ +struct stat st; +st.st_mtim.tv_nsec = 1; +]])], +[ac_cv_stat_tv_nsec=yes], +[ac_cv_stat_tv_nsec=no])) +if test "$ac_cv_stat_tv_nsec" = yes +then + AC_DEFINE([HAVE_STAT_TV_NSEC], [1], + [Define if you have struct stat.st_mtim.tv_nsec]) +fi + +# Look for BSD style subsecond timestamps in struct stat +AC_CACHE_CHECK([for tv_nsec2 in struct stat], [ac_cv_stat_tv_nsec2], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <sys/stat.h>]], [[ +struct stat st; +st.st_mtimespec.tv_nsec = 1; +]])], +[ac_cv_stat_tv_nsec2=yes], +[ac_cv_stat_tv_nsec2=no])) +if test "$ac_cv_stat_tv_nsec2" = yes +then + AC_DEFINE([HAVE_STAT_TV_NSEC2], [1], + [Define if you have struct stat.st_mtimensec]) +fi + +dnl check for ncursesw/ncurses and panelw/panel +dnl have_curses=[no, yes] +dnl have_panel=[no, yes] +have_curses=no +have_panel=no + +dnl Select the curses backend, or disable the curses and _curses_panel modules. +dnl "auto" (the default) prefers ncursesw and falls back to ncurses, both via +dnl pkg-config. "curses" links the system's native curses (e.g. on NetBSD or +dnl Solaris), which has no pkg-config file and is never chosen by "auto". +AC_MSG_CHECKING([for --with-curses]) +AC_ARG_WITH( + [curses], + [AS_HELP_STRING([--with(out)-curses@<:@=ncursesw|ncurses|curses|no@:>@], + [select the curses backend for the curses and _curses_panel + modules, or disable them (default: auto)])], + [AS_CASE([$with_curses], + [yes|auto], [with_curses=auto], + [ncursesw|ncurses|curses|no], [], + [AC_MSG_ERROR([proper usage is --with(out)-curses@<:@=ncursesw|ncurses|curses|no@:>@])])], + [with_curses=auto]) +AC_MSG_RESULT([$with_curses]) + +dnl PY_CHECK_CURSES(LIBCURSES, LIBPANEL) +dnl Sets 'have_curses' and 'have_panel'. +dnl For the PKG_CHECK_MODULES() calls, we can safely reuse the first variable +dnl here, since we're only calling the macro a second time if the first call +dnl fails. +AC_DEFUN([PY_CHECK_CURSES], [dnl +AS_VAR_PUSHDEF([curses_var], [m4_toupper([$1])]) +AS_VAR_PUSHDEF([panel_var], [m4_toupper([$2])]) +PKG_CHECK_MODULES([CURSES], [$1], + [AC_DEFINE([HAVE_]curses_var, [1], [Define if you have the '$1' library]) + AS_VAR_SET([have_curses], [yes]) + PKG_CHECK_MODULES([PANEL], [$2], + [AC_DEFINE([HAVE_]panel_var, [1], [Define if you have the '$2' library]) + AS_VAR_SET([have_panel], [yes])], + [dnl pkgsrc renames the ncurses panel to "gnupanel" so it does not clash + dnl with a system libpanel; it Requires the same ncurses, so it matches. + PKG_CHECK_MODULES([PANEL], [gnupanel], + [AS_VAR_SET([have_panel], [yes])], + [AS_VAR_SET([have_panel], [no])])])], + [AS_VAR_SET([have_curses], [no])]) +AS_VAR_POPDEF([curses_var]) +AS_VAR_POPDEF([panel_var])]) + +# Detect the selected backend. ncursesw/ncurses are found via pkg-config; +# native curses has no .pc file and is left to the header/link probes below. +# curses_libs/panel_libs drive the AC_SEARCH_LIBS fallback; for "no" they are +# empty so nothing links and have_curses stays "no". +AS_CASE([$with_curses], + [ncursesw], [PY_CHECK_CURSES([ncursesw], [panelw]) + curses_libs="ncursesw"; panel_libs="panelw gnupanel"], + [ncurses], [PY_CHECK_CURSES([ncurses], [panel]) + curses_libs="ncurses"; panel_libs="panel gnupanel"], + [curses], [curses_libs="curses"; panel_libs="panel"], + [no], [curses_libs=""; panel_libs=""], + [dnl auto: prefer ncursesw, fall back to ncurses; never native curses. + PY_CHECK_CURSES([ncursesw], [panelw]) + AS_VAR_IF([have_curses], [no], [PY_CHECK_CURSES([ncurses], [panel])]) + curses_libs="ncursesw ncurses"; panel_libs="panelw panel gnupanel"]) + +WITH_SAVE_ENV([ + # Make sure we've got the header defines. For the native "curses" backend, + # probe only the plain headers: a system may also have ncurses headers (e.g. + # ncurses/curses.h), and picking those while linking the native library mixes + # incompatible declarations (e.g. tparm()) with the native <term.h>. + AS_VAR_APPEND([CPPFLAGS], [" $CURSES_CFLAGS $PANEL_CFLAGS"]) + AS_VAR_IF([with_curses], [curses], + [AC_CHECK_HEADERS([curses.h panel.h])], + [AC_CHECK_HEADERS(m4_normalize([ + ncursesw/curses.h ncursesw/ncurses.h ncursesw/panel.h + ncurses/curses.h ncurses/ncurses.h ncurses/panel.h + curses.h ncurses.h panel.h + ]))]) + + # Check that we're able to link with crucial curses/panel functions. This + # also serves as a fallback in case pkg-config failed. Extension modules are + # not linked with LIBS, so exclude it to get the required libraries. + LIBS="$CURSES_LIBS $PANEL_LIBS" + AC_SEARCH_LIBS([initscr], [$curses_libs], + [AS_VAR_IF([have_curses], [no], + [AS_VAR_SET([have_curses], [yes]) + CURSES_LIBS=${CURSES_LIBS-"$ac_cv_search_initscr"}])], + [AS_VAR_SET([have_curses], [no])]) + AC_SEARCH_LIBS([update_panels], [$panel_libs], + [AS_VAR_IF([have_panel], [no], + [AS_VAR_SET([have_panel], [yes]) + PANEL_LIBS=${PANEL_LIBS-"$ac_cv_search_update_panels"}])], + [AS_VAR_SET([have_panel], [no])]) + +dnl Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque +dnl structs since version 5.7. If the macro is defined as zero before including +dnl [n]curses.h, ncurses will expose fields of the structs regardless of the +dnl configuration. +AC_DEFUN([_CURSES_INCLUDES],dnl +[ +#define NCURSES_OPAQUE 0 +#if defined(HAVE_NCURSESW_NCURSES_H) +# include <ncursesw/ncurses.h> +#elif defined(HAVE_NCURSESW_CURSES_H) +# include <ncursesw/curses.h> +#elif defined(HAVE_NCURSES_NCURSES_H) +# include <ncurses/ncurses.h> +#elif defined(HAVE_NCURSES_CURSES_H) +# include <ncurses/curses.h> +#elif defined(HAVE_NCURSES_H) +# include <ncurses.h> +#elif defined(HAVE_CURSES_H) +# include <curses.h> +#endif +]) + +AS_IF([test "$have_curses" != "no"], [ +dnl remove _XOPEN_SOURCE macro from curses cflags. pyconfig.h sets +dnl the macro to 700. +CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +AS_VAR_IF([ac_sys_system], [Darwin], [ + dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. + dnl System-supplied ncurses combines libncurses/libpanel and supports wide + dnl characters, so we can use it like ncursesw. + dnl If a locally-supplied version of libncursesw is found, we will use that. + dnl There should also be a libpanelw. + dnl _XOPEN_SOURCE defines are usually excluded for macOS, but we need + dnl _XOPEN_SOURCE_EXTENDED here for ncurses wide char support. + + AS_VAR_APPEND([CURSES_CFLAGS], [" -D_XOPEN_SOURCE_EXTENDED=1"]) +]) + +dnl pyconfig.h defines _XOPEN_SOURCE=700 +PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +dnl A curses that is not named "ncursesw" can still be wide-character capable: +dnl the system curses of NetBSD, or an ncurses built with --enable-widec that +dnl keeps the plain name (pkgsrc, macOS). Probe for the wide API and, if +dnl present, build the module wide by defining HAVE_NCURSESW. The "ncursesw" +dnl backend already defines it, so only the other backends are probed. +AS_CASE([$with_curses], [ncursesw|no], [], [ + dnl Use the adjusted CURSES_CFLAGS (e.g. macOS's -D_XOPEN_SOURCE_EXTENDED) + dnl so the wide-character declarations are visible to the probe. This runs + dnl inside an outer WITH_SAVE_ENV, whose single CPPFLAGS save slot is not + dnl reentrant, so save and restore CPPFLAGS with a dedicated variable here. + save_curses_cppflags=$CPPFLAGS + AS_VAR_APPEND([CPPFLAGS], [" $CURSES_CFLAGS"]) + AC_CACHE_CHECK([whether curses supports wide characters], + [ac_cv_curses_wide], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM([_CURSES_INCLUDES], [[ + cchar_t wcval; + setcchar(&wcval, L"x", A_NORMAL, 0, NULL); + add_wch(&wcval); + ]])], + [ac_cv_curses_wide=yes], + [ac_cv_curses_wide=no])]) + CPPFLAGS=$save_curses_cppflags + dnl HAVE_NCURSESW marks the wide (cchar_t) curses API; its template comes + dnl from the ncursesw pkg-config check above, so no description here. + AS_VAR_IF([ac_cv_curses_wide], [yes], [AC_DEFINE([HAVE_NCURSESW], [1])]) +]) + +# On Solaris, term.h requires curses.h +AC_CHECK_HEADERS([term.h], [], [], _CURSES_INCLUDES) + +# On HP/UX 11.0, mvwdelch is a block with a return statement +AC_CACHE_CHECK([whether mvwdelch is an expression], [ac_cv_mvwdelch_is_expression], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM(_CURSES_INCLUDES, [[ + int rtn; + rtn = mvwdelch(0,0,0); +]])], +[ac_cv_mvwdelch_is_expression=yes], +[ac_cv_mvwdelch_is_expression=no])) + +if test "$ac_cv_mvwdelch_is_expression" = yes +then + AC_DEFINE([MVWDELCH_IS_EXPRESSION], [1], + [Define if mvwdelch in curses.h is an expression.]) +fi + +AC_CACHE_CHECK([whether WINDOW has _flags], [ac_cv_window_has_flags], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM(_CURSES_INCLUDES, [[ + WINDOW *w; + w->_flags = 0; +]])], +[ac_cv_window_has_flags=yes], +[ac_cv_window_has_flags=no])) + + +if test "$ac_cv_window_has_flags" = yes +then + AC_DEFINE([WINDOW_HAS_FLAGS], [1], + [Define if WINDOW in curses.h offers a field _flags.]) +fi + +dnl PY_CHECK_CURSES_FUNC(FUNCTION) +AC_DEFUN([PY_CHECK_CURSES_FUNC], +[ AS_VAR_PUSHDEF([py_var], [ac_cv_lib_curses_$1]) + AS_VAR_PUSHDEF([py_define], [HAVE_CURSES_]m4_toupper($1)) + AC_CACHE_CHECK( + [for curses function $1], + [py_var], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM(_CURSES_INCLUDES, [ + #ifndef $1 + void *x=$1 + #endif + ])], + [AS_VAR_SET([py_var], [yes])], + [AS_VAR_SET([py_var], [no])])] + ) + AS_VAR_IF( + [py_var], + [yes], + [AC_DEFINE([py_define], [1], [Define if you have the '$1' function.])]) + AS_VAR_POPDEF([py_var]) + AS_VAR_POPDEF([py_define]) +]) + +dnl PY_CHECK_CURSES_VAR(VARIABLE) +dnl Like PY_CHECK_CURSES_FUNC, but for an integer variable (or macro), such as +dnl ESCDELAY, which a function probe cannot detect. +AC_DEFUN([PY_CHECK_CURSES_VAR], +[ AS_VAR_PUSHDEF([py_var], [ac_cv_lib_curses_$1]) + AS_VAR_PUSHDEF([py_define], [HAVE_CURSES_]m4_toupper($1)) + AC_CACHE_CHECK( + [for curses variable $1], + [py_var], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM(_CURSES_INCLUDES, [ + int x = $1; (void)x; + ])], + [AS_VAR_SET([py_var], [yes])], + [AS_VAR_SET([py_var], [no])])] + ) + AS_VAR_IF( + [py_var], + [yes], + [AC_DEFINE([py_define], [1], [Define if you have the '$1' variable.])]) + AS_VAR_POPDEF([py_var]) + AS_VAR_POPDEF([py_define]) +]) + +PY_CHECK_CURSES_FUNC([is_pad]) +PY_CHECK_CURSES_FUNC([is_term_resized]) +PY_CHECK_CURSES_FUNC([resize_term]) +PY_CHECK_CURSES_FUNC([resizeterm]) +PY_CHECK_CURSES_FUNC([immedok]) +PY_CHECK_CURSES_FUNC([syncok]) +PY_CHECK_CURSES_FUNC([wchgat]) +PY_CHECK_CURSES_FUNC([filter]) +PY_CHECK_CURSES_FUNC([nofilter]) +PY_CHECK_CURSES_FUNC([has_key]) +PY_CHECK_CURSES_FUNC([has_mouse]) +PY_CHECK_CURSES_FUNC([is_keypad]) +PY_CHECK_CURSES_FUNC([is_leaveok]) +PY_CHECK_CURSES_FUNC([typeahead]) +PY_CHECK_CURSES_FUNC([use_env]) +PY_CHECK_CURSES_FUNC([new_prescr]) +PY_CHECK_CURSES_FUNC([use_screen]) +PY_CHECK_CURSES_FUNC([use_window]) +PY_CHECK_CURSES_FUNC([key_defined]) +PY_CHECK_CURSES_FUNC([term_attrs]) +PY_CHECK_CURSES_FUNC([define_key]) +PY_CHECK_CURSES_FUNC([keyok]) +PY_CHECK_CURSES_FUNC([set_escdelay]) +PY_CHECK_CURSES_FUNC([set_tabsize]) +dnl The X/Open attr_t and soft-label attribute functions are absent on old +dnl SVr4 curses (e.g. illumos). +PY_CHECK_CURSES_FUNC([wattr_get]) +PY_CHECK_CURSES_FUNC([wattr_set]) +PY_CHECK_CURSES_FUNC([wattr_on]) +PY_CHECK_CURSES_FUNC([wattr_off]) +PY_CHECK_CURSES_FUNC([wcolor_set]) +PY_CHECK_CURSES_FUNC([slk_attr_on]) +PY_CHECK_CURSES_FUNC([slk_attr_off]) +PY_CHECK_CURSES_FUNC([slk_attr_set]) +PY_CHECK_CURSES_FUNC([slk_color]) +PY_CHECK_CURSES_VAR([ESCDELAY]) +PY_CHECK_CURSES_VAR([TABSIZE]) + +dnl Probe for the X/Open getmouse(MEVENT *) signature specifically: PDCurses +dnl declares an incompatible getmouse(void) unless built for the ncurses mouse API. +AC_CACHE_CHECK([for ncurses-style curses function getmouse], + [ac_cv_lib_curses_getmouse], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM(_CURSES_INCLUDES, [MEVENT event; (void)getmouse(&event);])], + [ac_cv_lib_curses_getmouse=yes], + [ac_cv_lib_curses_getmouse=no])]) +AS_VAR_IF([ac_cv_lib_curses_getmouse], [yes], + [AC_DEFINE([HAVE_CURSES_GETMOUSE], [1], + [Define if you have the 'getmouse' function with the X/Open signature.])]) + +dnl scr_dump gates scr_dump/scr_restore/scr_init; scr_set is separate, since +dnl old SVr4 curses (e.g. illumos) has the former but not scr_set. +PY_CHECK_CURSES_FUNC([scr_dump]) +PY_CHECK_CURSES_FUNC([scr_set]) +CPPFLAGS=$ac_save_cppflags +])dnl have_curses != no +])dnl save env + +AC_MSG_NOTICE([checking for device files]) + +dnl NOTE: Inform user how to proceed with files when cross compiling. +dnl Some cross-compile builds are predictable; they won't ever +dnl have /dev/ptmx or /dev/ptc, so we can set them explicitly. +if test "$ac_sys_system" = "Linux-android" || test "$ac_sys_system" = "iOS"; then + ac_cv_file__dev_ptmx=no + ac_cv_file__dev_ptc=no +else + if test "x$cross_compiling" = xyes; then + if test "${ac_cv_file__dev_ptmx+set}" != set; then + AC_MSG_CHECKING([for /dev/ptmx]) + AC_MSG_RESULT([not set]) + AC_MSG_ERROR([set ac_cv_file__dev_ptmx to yes/no in your CONFIG_SITE file when cross compiling]) + fi + if test "${ac_cv_file__dev_ptc+set}" != set; then + AC_MSG_CHECKING([for /dev/ptc]) + AC_MSG_RESULT([not set]) + AC_MSG_ERROR([set ac_cv_file__dev_ptc to yes/no in your CONFIG_SITE file when cross compiling]) + fi + fi + + AC_CHECK_FILE([/dev/ptmx], [], []) + if test "x$ac_cv_file__dev_ptmx" = xyes; then + AC_DEFINE([HAVE_DEV_PTMX], [1], + [Define to 1 if you have the /dev/ptmx device file.]) + fi + AC_CHECK_FILE([/dev/ptc], [], []) + if test "x$ac_cv_file__dev_ptc" = xyes; then + AC_DEFINE([HAVE_DEV_PTC], [1], + [Define to 1 if you have the /dev/ptc device file.]) + fi +fi + +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + +AC_CHECK_TYPES([socklen_t], [], + [AC_DEFINE([socklen_t], [int], + [Define to 'int' if <sys/socket.h> does not define.])], [ +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +]) + +AC_CACHE_CHECK([for broken mbstowcs], [ac_cv_broken_mbstowcs], +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +int main(void) { + size_t len = -1; + const char *str = "text"; + len = mbstowcs(NULL, str, 0); + return (len != 4); +} +]])], +[ac_cv_broken_mbstowcs=no], +[ac_cv_broken_mbstowcs=yes], +[ac_cv_broken_mbstowcs=no])) +if test "$ac_cv_broken_mbstowcs" = yes +then + AC_DEFINE([HAVE_BROKEN_MBSTOWCS], [1], + [Define if mbstowcs(NULL, "text", 0) does not return the number of + wide chars that would be converted.]) +fi + +# Check for --with-computed-gotos +AC_MSG_CHECKING([for --with-computed-gotos]) +AC_ARG_WITH( + [computed-gotos], + [AS_HELP_STRING( + [--with-computed-gotos], + [enable computed gotos in evaluation loop (enabled by default on supported compilers)] + )], +[ +if test "$withval" = yes +then + AC_DEFINE([USE_COMPUTED_GOTOS], [1], + [Define if you want to use computed gotos in ceval.c.]) + AC_MSG_RESULT([yes]) +fi +if test "$withval" = no +then + AC_DEFINE([USE_COMPUTED_GOTOS], [0], + [Define if you want to use computed gotos in ceval.c.]) + AC_MSG_RESULT([no]) +fi +], +[AC_MSG_RESULT([no value specified])]) + +AC_CACHE_CHECK([whether $CC supports computed gotos], [ac_cv_computed_gotos], +AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +int main(int argc, char **argv) +{ + static void *targets[1] = { &&LABEL1 }; + goto LABEL2; +LABEL1: + return 0; +LABEL2: + goto *targets[0]; + return 1; +} +]]])], +[ac_cv_computed_gotos=yes], +[ac_cv_computed_gotos=no], +[if test "${with_computed_gotos+set}" = set; then + ac_cv_computed_gotos="$with_computed_gotos -- configured --with(out)-computed-gotos" + else + ac_cv_computed_gotos=no + fi])) +case "$ac_cv_computed_gotos" in yes*) + AC_DEFINE([HAVE_COMPUTED_GOTOS], [1], + [Define if the C compiler supports computed gotos.]) +esac + +# Check for --with-tail-call-interp +AC_MSG_CHECKING([for --with-tail-call-interp]) +AC_ARG_WITH( + [tail-call-interp], + [AS_HELP_STRING( + [--with-tail-call-interp], + [enable tail-calling interpreter in evaluation loop and rest of CPython] + )], +[ +if test "$withval" = yes +then + AC_DEFINE([_Py_TAIL_CALL_INTERP], [1], + [Define if you want to use tail-calling interpreters in CPython.]) + AC_MSG_RESULT([yes]) +fi +if test "$withval" = no +then + AC_DEFINE([_Py_TAIL_CALL_INTERP], [0], + [Define if you want to use tail-calling interpreters in CPython.]) + AC_MSG_RESULT([no]) +fi +], +[AC_MSG_RESULT([no value specified])]) + +# Check for --with-remote-debug +AC_MSG_CHECKING([for --with-remote-debug]) +AC_ARG_WITH( + [remote-debug], + [AS_HELP_STRING( + [--with-remote-debug], + [enable remote debugging support (default is yes)])], + [], + [with_remote_debug=yes]) + +if test "$with_remote_debug" = yes; then + AC_DEFINE([Py_REMOTE_DEBUG], [1], + [Define if you want to enable remote debugging support.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + + +case $ac_sys_system in +AIX*) + AC_DEFINE([HAVE_BROKEN_PIPE_BUF], [1], + [Define if the system reports an invalid PIPE_BUF value.]) ;; +esac + + +AC_SUBST([THREADHEADERS]) + +for h in `(cd $srcdir;echo Python/thread_*.h)` +do + THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" +done + +AC_SUBST([SRCDIRS]) +SRCDIRS="\ + Modules \ + Modules/_ctypes \ + Modules/_decimal \ + Modules/_hacl \ + Modules/_io \ + Modules/_multiprocessing \ + Modules/_remote_debugging \ + Modules/_sqlite \ + Modules/_sre \ + Modules/_testcapi \ + Modules/_testinternalcapi \ + Modules/_testlimitedcapi \ + Modules/_xxtestfuzz \ + Modules/_zstd \ + Modules/cjkcodecs \ + Modules/expat \ + Objects \ + Objects/mimalloc \ + Objects/mimalloc/prim \ + Parser \ + Parser/tokenizer \ + Parser/lexer \ + Programs \ + Python \ + Python/frozen_modules" +AC_MSG_CHECKING([for build directories]) +for dir in $SRCDIRS; do + if test ! -d $dir; then + mkdir $dir + fi +done +AC_MSG_RESULT([done]) + +# Availability of -O2: +AC_CACHE_CHECK([for -O2], [ac_cv_compile_o2], [ +saved_cflags="$CFLAGS" +CFLAGS="-O2" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ac_cv_compile_o2=yes], [ac_cv_compile_o2=no]) +CFLAGS="$saved_cflags" +]) + +# _FORTIFY_SOURCE wrappers for memmove and bcopy are incorrect: +# http://sourceware.org/ml/libc-alpha/2010-12/msg00009.html +AC_MSG_CHECKING([for glibc _FORTIFY_SOURCE/memmove bug]) +saved_cflags="$CFLAGS" +CFLAGS="-O2 -D_FORTIFY_SOURCE=2" +if test "$ac_cv_compile_o2" = no; then + CFLAGS="" +fi +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +void foo(void *p, void *q) { memmove(p, q, 19); } +int main(void) { + char a[32] = "123456789000000000"; + foo(&a[9], a); + if (strcmp(a, "123456789123456789000000000") != 0) + return 1; + foo(a, &a[9]); + if (strcmp(a, "123456789000000000") != 0) + return 1; + return 0; +} +]])], +[have_glibc_memmove_bug=no], +[have_glibc_memmove_bug=yes], +[have_glibc_memmove_bug=undefined]) +CFLAGS="$saved_cflags" +AC_MSG_RESULT([$have_glibc_memmove_bug]) +if test "$have_glibc_memmove_bug" = yes; then + AC_DEFINE([HAVE_GLIBC_MEMMOVE_BUG], [1], + [Define if glibc has incorrect _FORTIFY_SOURCE wrappers + for memmove and bcopy.]) +fi + +AC_MSG_CHECKING([if we need to manually block large inlining in ceval.c]) +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +int main(void) { +// See gh-148284: Clang 22 seems to have interactions with inlining +// and the stackref buffer which cause 40 kB of stack usage on x86-64 +// in buggy versions of _PyEval_EvalFrameDefault() in computed goto +// interpreter. The normal usage seen is normally 1-2 kB. +#if defined(__clang__) && (__clang_major__ == 22) + return 1; +#else + return 0; +#endif +} +]])], +[block_huge_inlining_in_ceval=no], +[block_huge_inlining_in_ceval=yes], +[block_huge_inlining_in_ceval=undefined]) +AC_MSG_RESULT([$block_huge_inlining_in_ceval]) + +if test "$block_huge_inlining_in_ceval" = yes && test "$ac_cv_computed_gotos" = yes; then + # gh-148284: Suppress inlining of functions whose stack size exceeds + # 512 bytes. This number should be tuned to follow the C stack + # consumption in _PyEval_EvalFrameDefault() on computed goto + # interpreter. + CFLAGS_CEVAL="$CFLAGS_CEVAL -finline-max-stacksize=512" +fi +AC_SUBST([CFLAGS_CEVAL]) + +if test "$ac_cv_gcc_asm_for_x87" = yes; then + # Some versions of gcc miscompile inline asm: + # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46491 + # http://gcc.gnu.org/ml/gcc/2010-11/msg00366.html + case $ac_cv_cc_name in + gcc) + AC_MSG_CHECKING([for gcc ipa-pure-const bug]) + saved_cflags="$CFLAGS" + CFLAGS="-O2" + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + __attribute__((noinline)) int + foo(int *p) { + int r; + asm ( "movl \$6, (%1)\n\t" + "xorl %0, %0\n\t" + : "=r" (r) : "r" (p) : "memory" + ); + return r; + } + int main(void) { + int p = 8; + if ((foo(&p) ? : p) != 6) + return 1; + return 0; + } + ]])], + [have_ipa_pure_const_bug=no], + [have_ipa_pure_const_bug=yes], + [have_ipa_pure_const_bug=undefined]) + CFLAGS="$saved_cflags" + AC_MSG_RESULT([$have_ipa_pure_const_bug]) + if test "$have_ipa_pure_const_bug" = yes; then + AC_DEFINE([HAVE_IPA_PURE_CONST_BUG], [1], + [Define if gcc has the ipa-pure-const bug.]) + fi + ;; + esac +fi + +# ensurepip option +AC_MSG_CHECKING([for ensurepip]) +AC_ARG_WITH([ensurepip], + [AS_HELP_STRING([--with-ensurepip@<:@=install|upgrade|no@:>@], + ["install" or "upgrade" using bundled pip (default is upgrade)])], + [], + [ + AS_CASE([$ac_sys_system], + [Emscripten], [with_ensurepip=no], + [WASI], [with_ensurepip=no], + [iOS], [with_ensurepip=no], + [with_ensurepip=upgrade] + ) + ]) +AS_CASE([$with_ensurepip], + [yes|upgrade],[ENSUREPIP=upgrade], + [install],[ENSUREPIP=install], + [no],[ENSUREPIP=no], + [AC_MSG_ERROR([--with-ensurepip=upgrade|install|no])]) +AC_MSG_RESULT([$ENSUREPIP]) +AC_SUBST([ENSUREPIP]) + +# check if the dirent structure of a d_type field and DT_UNKNOWN is defined +AC_CACHE_CHECK([if the dirent structure of a d_type field], [ac_cv_dirent_d_type], [ +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + #include <dirent.h> + + int main(void) { + struct dirent entry; + return entry.d_type == DT_UNKNOWN; + } + ]]) +],[ac_cv_dirent_d_type=yes],[ac_cv_dirent_d_type=no]) +]) + +AS_VAR_IF([ac_cv_dirent_d_type], [yes], [ + AC_DEFINE([HAVE_DIRENT_D_TYPE], [1], + [Define to 1 if the dirent structure has a d_type field]) +]) + +# check if the Linux getrandom() syscall is available +AC_CACHE_CHECK([for the Linux getrandom() syscall], [ac_cv_getrandom_syscall], [ +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + #include <stddef.h> + #include <unistd.h> + #include <sys/syscall.h> + #include <linux/random.h> + + int main(void) { + char buffer[1]; + const size_t buflen = sizeof(buffer); + const int flags = GRND_NONBLOCK; + /* ignore the result, Python checks for ENOSYS and EAGAIN at runtime */ + (void)syscall(SYS_getrandom, buffer, buflen, flags); + return 0; + } + ]]) +],[ac_cv_getrandom_syscall=yes],[ac_cv_getrandom_syscall=no]) +]) + +AS_VAR_IF([ac_cv_getrandom_syscall], [yes], [ + AC_DEFINE([HAVE_GETRANDOM_SYSCALL], [1], + [Define to 1 if the Linux getrandom() syscall is available]) +]) + +# check if the getrandom() function is available +# the test was written for the Solaris function of <sys/random.h> +AC_CACHE_CHECK([for the getrandom() function], [ac_cv_func_getrandom], [ +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + #include <stddef.h> + #include <sys/random.h> + + int main(void) { + char buffer[1]; + const size_t buflen = sizeof(buffer); + const int flags = 0; + /* ignore the result, Python checks for ENOSYS at runtime */ + (void)getrandom(buffer, buflen, flags); + return 0; + } + ]]) +],[ac_cv_func_getrandom=yes],[ac_cv_func_getrandom=no]) +]) + +AS_VAR_IF([ac_cv_func_getrandom], [yes], [ + AC_DEFINE([HAVE_GETRANDOM], [1], + [Define to 1 if the getrandom() function is available]) +]) + +# checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c +# shm_* may only be available if linking against librt +POSIXSHMEM_CFLAGS='-I$(srcdir)/Modules/_multiprocessing' +WITH_SAVE_ENV([ + AC_SEARCH_LIBS([shm_open], [rt]) + AS_VAR_IF([ac_cv_search_shm_open], [-lrt], [POSIXSHMEM_LIBS="-lrt"]) + + dnl Temporarily override ac_includes_default for AC_CHECK_FUNCS below. + _SAVE_VAR([ac_includes_default]) + ac_includes_default="\ + ${ac_includes_default} + #ifndef __cplusplus + # ifdef HAVE_SYS_MMAN_H + # include <sys/mman.h> + # endif + #endif + " + AC_CHECK_FUNCS([shm_open shm_unlink], [have_posix_shmem=yes], [have_posix_shmem=no]) + _RESTORE_VAR([ac_includes_default]) +]) + +# Check for usable OpenSSL +AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no]) + +# rpath to libssl and libcrypto +AS_VAR_IF([GNULD], [yes], [ + rpath_arg="-Wl,--enable-new-dtags,-rpath=" +], [ + if test "$ac_sys_system" = "Darwin" + then + rpath_arg="-Wl,-rpath," + else + rpath_arg="-Wl,-rpath=" + fi +]) + +AC_MSG_CHECKING([for --with-openssl-rpath]) +AC_ARG_WITH([openssl-rpath], + AS_HELP_STRING([--with-openssl-rpath=@<:@DIR|auto|no@:>@], + [Set runtime library directory (rpath) for OpenSSL libraries, + no (default): don't set rpath, + auto: auto-detect rpath from --with-openssl and pkg-config, + DIR: set an explicit rpath + ]), + [], + [with_openssl_rpath=no] +) +AS_CASE([$with_openssl_rpath], + [auto|yes], [ + OPENSSL_RPATH=auto + dnl look for linker directories + for arg in "$OPENSSL_LDFLAGS"; do + AS_CASE([$arg], + [-L*], [OPENSSL_LDFLAGS_RPATH="$OPENSSL_LDFLAGS_RPATH ${rpath_arg}$(echo $arg | cut -c3-)"] + ) + done + ], + [no], [OPENSSL_RPATH=], + [AS_IF( + [test -d "$with_openssl_rpath"], + [ + OPENSSL_RPATH="$with_openssl_rpath" + OPENSSL_LDFLAGS_RPATH="${rpath_arg}$with_openssl_rpath" + ], + AC_MSG_ERROR([--with-openssl-rpath "$with_openssl_rpath" is not a directory])) + ] +) +AC_MSG_RESULT([$OPENSSL_RPATH]) + +# This static linking is NOT OFFICIALLY SUPPORTED and not advertised. +# Requires static OpenSSL build with position-independent code. Some features +# like DSO engines or external OSSL providers don't work. Only tested with GCC +# and clang on X86_64. +AS_VAR_IF([PY_UNSUPPORTED_OPENSSL_BUILD], [static], [ + AC_MSG_CHECKING([for unsupported static openssl build]) + new_OPENSSL_LIBS= + for arg in $OPENSSL_LIBS; do + AS_CASE([$arg], + [-l*], [ + libname=$(echo $arg | cut -c3-) + new_OPENSSL_LIBS="$new_OPENSSL_LIBS -l:lib${libname}.a -Wl,--exclude-libs,lib${libname}.a" + ], + [new_OPENSSL_LIBS="$new_OPENSSL_LIBS $arg"] + ) + done + dnl include libz for OpenSSL build flavors with compression support + OPENSSL_LIBS="$new_OPENSSL_LIBS $ZLIB_LIBS" + AC_MSG_RESULT([$OPENSSL_LIBS]) +]) + +dnl AX_CHECK_OPENSSL does not export libcrypto-only libs +LIBCRYPTO_LIBS= +for arg in $OPENSSL_LIBS; do + AS_CASE([$arg], + [-l*ssl*|-Wl*ssl*], [], + [LIBCRYPTO_LIBS="$LIBCRYPTO_LIBS $arg"] + ) +done + +# check if OpenSSL libraries work as expected +WITH_SAVE_ENV([ + LIBS="$LIBS $OPENSSL_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + AC_CACHE_CHECK([whether OpenSSL provides required ssl module APIs], [ac_cv_working_openssl_ssl], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include <openssl/opensslv.h> + #include <openssl/ssl.h> + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + static void keylog_cb(const SSL *ssl, const char *line) {} + ], [ + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + SSL_CTX_set_keylog_callback(ctx, keylog_cb); + SSL *ssl = SSL_new(ctx); + X509_VERIFY_PARAM *param = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set1_host(param, "python.org", 0); + SSL_free(ssl); + SSL_CTX_free(ctx); + ])], [ac_cv_working_openssl_ssl=yes], [ac_cv_working_openssl_ssl=no]) + ]) +]) + +WITH_SAVE_ENV([ + LIBS="$LIBS $LIBCRYPTO_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + AC_CACHE_CHECK([whether OpenSSL provides required hashlib module APIs], [ac_cv_working_openssl_hashlib], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include <openssl/opensslv.h> + #include <openssl/evp.h> + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + ], [ + OBJ_nid2sn(NID_md5); + OBJ_nid2sn(NID_sha1); + OBJ_nid2sn(NID_sha512); + OBJ_nid2sn(NID_sha3_512); + EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0); + ])], [ac_cv_working_openssl_hashlib=yes], [ac_cv_working_openssl_hashlib=no]) + ]) +]) + +# ssl module default cipher suite string +AH_TEMPLATE([PY_SSL_DEFAULT_CIPHERS], + [Default cipher suites list for ssl module. + 1: Python's preferred selection, 2: leave OpenSSL defaults untouched, 0: custom string]) +AH_TEMPLATE([PY_SSL_DEFAULT_CIPHER_STRING], + [Cipher suite string for PY_SSL_DEFAULT_CIPHERS=0] +) + +AC_MSG_CHECKING([for --with-ssl-default-suites]) +AC_ARG_WITH( + [ssl-default-suites], + [AS_HELP_STRING( + [--with-ssl-default-suites=@<:@python|openssl|STRING@:>@], + [override default cipher suites string, + python: use Python's preferred selection (default), + openssl: leave OpenSSL's defaults untouched, + STRING: use a custom string, + python and STRING also set TLS 1.2 as minimum TLS version] + )], +[ +AC_MSG_RESULT([$withval]) +case "$withval" in + python) + AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [1]) + ;; + openssl) + AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [2]) + ;; + *) + AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [0]) + AC_DEFINE_UNQUOTED([PY_SSL_DEFAULT_CIPHER_STRING], ["$withval"]) + ;; +esac +], +[ +AC_MSG_RESULT([python]) +AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [1]) +]) + +# builtin hash modules +default_hashlib_hashes="md5,sha1,sha2,sha3,blake2" +AC_MSG_CHECKING([for --with-builtin-hashlib-hashes]) +AC_ARG_WITH( + [builtin-hashlib-hashes], + [AS_HELP_STRING( + [--with-builtin-hashlib-hashes=md5,sha1,sha2,sha3,blake2], + [builtin hash modules, md5, sha1, sha2, sha3 (with shake), blake2] + )], +[ + AS_CASE([$with_builtin_hashlib_hashes], + [yes], [with_builtin_hashlib_hashes=$default_hashlib_hashes], + [no], [with_builtin_hashlib_hashes=""] + ) +], [with_builtin_hashlib_hashes=$default_hashlib_hashes]) + +AC_MSG_RESULT([$with_builtin_hashlib_hashes]) +AC_DEFINE_UNQUOTED([PY_BUILTIN_HASHLIB_HASHES], + ["$with_builtin_hashlib_hashes"], + [enabled builtin hash modules]) + +as_save_IFS=$IFS +IFS=, +for builtin_hash in $with_builtin_hashlib_hashes; do + AS_CASE([$builtin_hash], + [md5], [with_builtin_md5=yes], + [sha1], [with_builtin_sha1=yes], + [sha2], [with_builtin_sha2=yes], + [sha3], [with_builtin_sha3=yes], + [blake2], [with_builtin_blake2=yes] + ) +done +IFS=$as_save_IFS + +# Check whether to disable test modules. Once set, setup.py will not build +# test extension modules and "make install" will not install test suites. +AC_MSG_CHECKING([for --disable-test-modules]) +AC_ARG_ENABLE([test-modules], + [AS_HELP_STRING([--disable-test-modules], [don't build nor install test modules])], [ + AS_VAR_IF([enable_test_modules], [yes], [TEST_MODULES=yes], [TEST_MODULES=no]) +], [TEST_MODULES=yes]) +AC_MSG_RESULT([$TEST_MODULES]) +AC_SUBST([TEST_MODULES]) + +# Check for --with-build-details-suffix +BUILD_DETAILS=build-details.json +AC_ARG_WITH([build-details-suffix], + [AS_HELP_STRING( + [--with-build-details-suffix=], + [rename build-details.json to permit multiple colocated Python installs; optionally specify a custom suffix (default: no)] + )], + [ + AC_MSG_CHECKING([for --with-build-details-suffix]) + AS_VAR_IF( + [with_build_details_suffix], [no], + [AC_MSG_ERROR([invalid --with-build-details-suffix option: expected custom suffix or "yes", not "no"])] + ) + AS_VAR_IF( + [with_build_details_suffix], [yes], [ + colocated_install=yes + threading_suffix="" + if [[ "$ABI_THREAD" = "t" ]]; then + threading_suffix=-free-threading + fi + debug_suffix="" + if [[ "$Py_DEBUG" = "true" ]]; then + debug_suffix=-debug + fi + BUILD_DETAILS=build-details.$MULTIARCH$threading_suffix$debug_suffix.json + ], [ + BUILD_DETAILS=build-details.$with_build_details_suffix.json + ] + ) + ] +) +AC_MSG_RESULT([$with_build_details_suffix]) +AC_SUBST([BUILD_DETAILS], [$BUILD_DETAILS]) + +# gh-109054: Check if -latomic is needed to get <pyatomic.h> atomic functions. +# On Linux aarch64, GCC may require programs and libraries to be linked +# explicitly to libatomic. Call _Py_atomic_or_uint64() which may require +# libatomic __atomic_fetch_or_8(), or not, depending on the C compiler and the +# compiler flags. +# +# gh-112779: On RISC-V, GCC 12 and earlier require libatomic support for 1-byte +# and 2-byte operations, but not for 8-byte operations. +# +# Avoid #include <Python.h> or #include <pyport.h>. The <Python.h> header +# requires <pyconfig.h> header which is only written below by AC_OUTPUT below. +# If the check is done after AC_OUTPUT, modifying LIBS has no effect +# anymore. <pyport.h> cannot be included alone, it's designed to be included +# by <Python.h>: it expects other includes and macros to be defined. +_SAVE_VAR([CPPFLAGS]) +CPPFLAGS="${BASECPPFLAGS} -I. -I${srcdir}/Include ${CPPFLAGS}" + +AC_CACHE_CHECK([whether libatomic is needed by <pyatomic.h>], + [ac_cv_libatomic_needed], +[AC_LINK_IFELSE([AC_LANG_SOURCE([[ +// pyatomic.h needs uint64_t and Py_ssize_t types +#include <stdint.h> // int64_t, intptr_t +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> // ssize_t +#endif +// Code adapted from Include/pyport.h +#if HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef intptr_t Py_ssize_t; +#else +# error "unable to define Py_ssize_t" +#endif + +#include "pyatomic.h" + +int main() +{ + uint64_t value; + _Py_atomic_store_uint64(&value, 2); + if (_Py_atomic_or_uint64(&value, 8) != 2) { + return 1; // error + } + if (_Py_atomic_load_uint64(&value) != 10) { + return 1; // error + } + uint8_t byte = 0xb8; + if (_Py_atomic_or_uint8(&byte, 0x2d) != 0xb8) { + return 1; // error + } + if (_Py_atomic_load_uint8(&byte) != 0xbd) { + return 1; // error + } + return 0; // all good +} +]])], + [ac_cv_libatomic_needed=no], dnl build and link succeeded + [ac_cv_libatomic_needed=yes]) dnl build and link failed +]) + +AS_VAR_IF([ac_cv_libatomic_needed], [yes], + [LIBS="${LIBS} -latomic" + LIBATOMIC=${LIBATOMIC-"-latomic"}]) +_RESTORE_VAR([CPPFLAGS]) + + +# gh-59705: Maximum length in bytes of a thread name +case "$ac_sys_system" in + Linux*) _PYTHREAD_NAME_MAXLEN=15;; # Linux and Android + SunOS*) _PYTHREAD_NAME_MAXLEN=31;; + NetBSD*) _PYTHREAD_NAME_MAXLEN=15;; # gh-131268 + Darwin) _PYTHREAD_NAME_MAXLEN=63;; + iOS) _PYTHREAD_NAME_MAXLEN=63;; + FreeBSD*) _PYTHREAD_NAME_MAXLEN=19;; # gh-131268 + OpenBSD*) _PYTHREAD_NAME_MAXLEN=23;; # gh-131268 + CYGWIN*) _PYTHREAD_NAME_MAXLEN=16;; + *) _PYTHREAD_NAME_MAXLEN=;; +esac +if test -n "$_PYTHREAD_NAME_MAXLEN"; then + AC_DEFINE_UNQUOTED([_PYTHREAD_NAME_MAXLEN], [$_PYTHREAD_NAME_MAXLEN], + [Maximum length in bytes of a thread name]) +fi +AC_SUBST([_PYTHREAD_NAME_MAXLEN]) + + +# stdlib +AC_DEFUN([PY_STDLIB_MOD_SET_NA], [ + m4_foreach([mod], [$@], [ + AS_VAR_SET([py_cv_module_]mod, [n/a])]) +]) + +# stdlib not available +dnl Modules that are not available on some platforms +AS_CASE([$ac_sys_system], + [AIX], [PY_STDLIB_MOD_SET_NA([_scproxy])], + [VxWorks*], [PY_STDLIB_MOD_SET_NA([_scproxy], [termios], [grp])], + dnl The _scproxy module is available on macOS + [Darwin], [], + [iOS], [ + dnl subprocess and multiprocessing are not supported (no fork syscall). + dnl curses and tkinter user interface are not available. + dnl gdbm and nis aren't available + dnl Stub implementations are provided for pwd, grp etc APIs + PY_STDLIB_MOD_SET_NA( + [_curses], + [_curses_panel], + [_gdbm], + [_multiprocessing], + [_posixshmem], + [_posixsubprocess], + [_scproxy], + [_tkinter], + [grp], + [nis], + [readline], + [pwd], + [spwd], + [syslog], + ) + ], + [CYGWIN*], [PY_STDLIB_MOD_SET_NA([_scproxy])], + [QNX*], [PY_STDLIB_MOD_SET_NA([_scproxy])], + [FreeBSD*], [PY_STDLIB_MOD_SET_NA([_scproxy])], + [Emscripten], [ + dnl subprocess and multiprocessing are not supported (no fork syscall). + dnl curses and tkinter user interface are not available. + dnl dbm and gdbm aren't available, too. + dnl pwd, grp APIs, and resource functions (get/setrusage) are stubs. + PY_STDLIB_MOD_SET_NA( + [_curses], + [_curses_panel], + [_dbm], + [_gdbm], + [_multiprocessing], + [_posixshmem], + [_posixsubprocess], + [_scproxy], + [_tkinter], + [_interpreters], + [_interpchannels], + [_interpqueues], + [grp], + [pwd], + [resource], + [syslog], + ) + dnl fcntl, readline, and termios are not particularly useful in browsers. + PY_STDLIB_MOD_SET_NA( + [readline], + ) + ], + [WASI], [ + dnl subprocess and multiprocessing are not supported (no fork syscall). + dnl curses and tkinter user interface are not available. + dnl dbm and gdbm aren't available, too. + dnl pwd, grp APIs, and resource functions (get/setrusage) are stubs. + PY_STDLIB_MOD_SET_NA( + [_curses], + [_curses_panel], + [_dbm], + [_gdbm], + [_multiprocessing], + [_posixshmem], + [_posixsubprocess], + [_scproxy], + [_tkinter], + [_interpreters], + [_interpchannels], + [_interpqueues], + [grp], + [pwd], + [resource], + [syslog], + ) + dnl WASI SDK 15.0 does not support file locking, mmap, and more. + dnl Test modules that must be compiled as shared libraries are not supported + dnl (see Modules/Setup.stdlib.in). + PY_STDLIB_MOD_SET_NA( + [_ctypes_test], + [_remote_debugging], + [_testimportmultiple], + [_testmultiphase], + [_testsinglephase], + [fcntl], + [mmap], + [termios], + [xxlimited], + [xxlimited_35], + [xxlimited_3_13], + ) + ], + [PY_STDLIB_MOD_SET_NA([_scproxy])] +) + +dnl AC_MSG_NOTICE([m4_set_list([_PY_STDLIB_MOD_SET_NA])]) + +dnl Default value for Modules/Setup.stdlib build type +AS_CASE([$host_cpu], + [wasm32|wasm64], [MODULE_BUILDTYPE=static], + [MODULE_BUILDTYPE=${MODULE_BUILDTYPE:-shared}] +) +AC_SUBST([MODULE_BUILDTYPE]) + +dnl _MODULE_BLOCK_ADD([VAR], [VALUE]) +dnl internal: adds $1=quote($2) to MODULE_BLOCK +AC_DEFUN([_MODULE_BLOCK_ADD], [AS_VAR_APPEND([MODULE_BLOCK], ["$1=_AS_QUOTE([$2])$as_nl"])]) +MODULE_BLOCK= + +dnl Check for stdlib extension modules +dnl PY_STDLIB_MOD([NAME], [ENABLED-TEST], [SUPPORTED-TEST], [CFLAGS], [LDFLAGS]) +dnl sets MODULE_$NAME_STATE based on PY_STDLIB_MOD_SET_NA(), ENABLED-TEST, +dnl and SUPPORTED_TEST. ENABLED-TEST and SUPPORTED-TEST default to true if +dnl empty. +dnl n/a: marked unavailable on platform by PY_STDLIB_MOD_SET_NA() +dnl yes: enabled and supported +dnl missing: enabled and not supported +dnl disabled: not enabled +dnl sets MODULE_$NAME_CFLAGS and MODULE_$NAME_LDFLAGS +AC_DEFUN([PY_STDLIB_MOD], [ + AC_MSG_CHECKING([for stdlib extension module $1]) + m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl + m4_pushdef([modstate], [py_cv_module_$1])dnl + dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA() + AS_IF([test "$modstate" != "n/a"], [ + AS_IF([m4_ifblank([$2], [true], [$2])], + [AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])], + [modstate=disabled]) + ]) + _MODULE_BLOCK_ADD(modcond[_STATE], [$modstate]) + AS_VAR_IF([modstate], [yes], [ + m4_ifblank([$4], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_CFLAGS], [$4])]) + m4_ifblank([$5], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_LDFLAGS], [$5])]) + ]) + AM_CONDITIONAL(modcond, [test "$modstate" = yes]) + AC_MSG_RESULT([$modstate]) + m4_popdef([modcond])dnl + m4_popdef([modstate])dnl +]) + +dnl Define simple stdlib extension module +dnl Always enable unless the module is disabled by PY_STDLIB_MOD_SET_NA +dnl PY_STDLIB_MOD_SIMPLE([NAME], [CFLAGS], [LDFLAGS]) +dnl cflags and ldflags are optional +AC_DEFUN([PY_STDLIB_MOD_SIMPLE], [ + m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl + m4_pushdef([modstate], [py_cv_module_$1])dnl + dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA() + AS_IF([test "$modstate" != "n/a"], [modstate=yes]) + AM_CONDITIONAL(modcond, [test "$modstate" = yes]) + _MODULE_BLOCK_ADD(modcond[_STATE], [$modstate]) + AS_VAR_IF([modstate], [yes], [ + m4_ifblank([$2], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_CFLAGS], [$2])]) + m4_ifblank([$3], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_LDFLAGS], [$3])]) + ]) + m4_popdef([modcond])dnl + m4_popdef([modstate])dnl +]) + +dnl static modules in Modules/Setup.bootstrap +PY_STDLIB_MOD_SIMPLE([_io], [-I\$(srcdir)/Modules/_io], []) +PY_STDLIB_MOD_SIMPLE([time], [], [$TIMEMODULE_LIB]) + +dnl always enabled extension modules +PY_STDLIB_MOD_SIMPLE([array]) +PY_STDLIB_MOD_SIMPLE([_math_integer]) +PY_STDLIB_MOD_SIMPLE([_asyncio]) +PY_STDLIB_MOD_SIMPLE([_bisect]) +PY_STDLIB_MOD_SIMPLE([_csv]) +PY_STDLIB_MOD_SIMPLE([_heapq]) +PY_STDLIB_MOD_SIMPLE([_json]) +PY_STDLIB_MOD_SIMPLE([_lsprof]) +PY_STDLIB_MOD_SIMPLE([_pickle]) +PY_STDLIB_MOD_SIMPLE([_posixsubprocess]) +PY_STDLIB_MOD_SIMPLE([_queue]) +PY_STDLIB_MOD_SIMPLE([_random]) +PY_STDLIB_MOD_SIMPLE([_remote_debugging], [$REMOTE_DEBUGGING_CFLAGS], [$REMOTE_DEBUGGING_LIBS]) +PY_STDLIB_MOD_SIMPLE([select]) +PY_STDLIB_MOD_SIMPLE([_struct]) +PY_STDLIB_MOD_SIMPLE([_types]) +PY_STDLIB_MOD_SIMPLE([_typing]) +PY_STDLIB_MOD_SIMPLE([_interpreters]) +PY_STDLIB_MOD_SIMPLE([_interpchannels]) +PY_STDLIB_MOD_SIMPLE([_interpqueues]) +PY_STDLIB_MOD_SIMPLE([_zoneinfo]) + +dnl multiprocessing modules +PY_STDLIB_MOD([_multiprocessing], + [], [test "$ac_cv_func_sem_unlink" = "yes"], + [-I\$(srcdir)/Modules/_multiprocessing]) +PY_STDLIB_MOD([_posixshmem], + [], [test "$have_posix_shmem" = "yes"], + [$POSIXSHMEM_CFLAGS], [$POSIXSHMEM_LIBS]) + +dnl needs libm +PY_STDLIB_MOD_SIMPLE([_statistics], [], [$LIBM]) +PY_STDLIB_MOD_SIMPLE([cmath], [], [$LIBM]) +PY_STDLIB_MOD_SIMPLE([math], [], [$LIBM]) + +dnl needs libm and on some platforms librt +PY_STDLIB_MOD_SIMPLE([_datetime], [], [$TIMEMODULE_LIB $LIBM]) + +dnl modules with some unix dependencies +PY_STDLIB_MOD([fcntl], + [], [test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"], + [], [$FCNTL_LIBS]) +PY_STDLIB_MOD([mmap], + [], [test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"]) +PY_STDLIB_MOD([_socket], + [], m4_flatten([test "$ac_cv_header_sys_socket_h" = "yes" + -a "$ac_cv_header_sys_types_h" = "yes" + -a "$ac_cv_header_netinet_in_h" = "yes"]), [], [$SOCKET_LIBS]) + +dnl platform specific extensions +PY_STDLIB_MOD([grp], [], + [test "$ac_cv_func_getgrent" = "yes" && + { test "$ac_cv_func_getgrgid" = "yes" || test "$ac_cv_func_getgrgid_r" = "yes"; }]) +PY_STDLIB_MOD([pwd], [], [test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes]) +PY_STDLIB_MOD([resource], [], [test "$ac_cv_header_sys_resource_h" = yes]) +PY_STDLIB_MOD([_scproxy], + [test "$ac_sys_system" = "Darwin"], [], + [], [-framework SystemConfiguration -framework CoreFoundation]) +PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes]) +PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes]) + +dnl _elementtree loads libexpat via CAPI hook in pyexpat +PY_STDLIB_MOD([pyexpat], + [], [test "$ac_cv_header_sys_time_h" = "yes"], + [$LIBEXPAT_CFLAGS], [$LIBEXPAT_LDFLAGS]) +PY_STDLIB_MOD([_elementtree], [], [], [$LIBEXPAT_CFLAGS], []) +PY_STDLIB_MOD_SIMPLE([_codecs_cn]) +PY_STDLIB_MOD_SIMPLE([_codecs_hk]) +PY_STDLIB_MOD_SIMPLE([_codecs_iso2022]) +PY_STDLIB_MOD_SIMPLE([_codecs_jp]) +PY_STDLIB_MOD_SIMPLE([_codecs_kr]) +PY_STDLIB_MOD_SIMPLE([_codecs_tw]) +PY_STDLIB_MOD_SIMPLE([_multibytecodec]) +PY_STDLIB_MOD_SIMPLE([unicodedata]) + +############################################################################### +# HACL* compilation and linking configuration (contact: @picnixz) +# +# Used by the HACL*-based implementations of cryptographic primitives. +# +# CPython provides a vendored copy of a subset of the HACL* project used +# to build extension modules of cryptographic primitives. On WASI, HACL* +# sources must be statically linked with the extension modules; on other +# platforms, the extension modules may assume that HACL* has been compiled +# as a shared library. +# +# Example for MD5: +# +# * Compile Modules/_hacl/Hacl_Hash_MD5.c into Modules/_hacl/Hacl_Hash_MD5.o. +# * Decide whether the object files are to be passed to the linker (emulate +# a shared library without having to install it) or if we need to create +# a static library for WASI. The following summarizes the values taken by +# the MODULE_<NAME>_LDFLAGS variable depending on the linkage type: +# - shared: MODULE__MD5_LDFLAGS is set to LIBHACL_MD5_OBJS +# - static: MODULE__MD5_LDFLAGS is set to Modules/_hacl/libHacl_Hash_MD5.a +# * Compile Modules/md5module.c into Modules/md5module.o. +# * Link Modules/md5module.o using $(MODULE__MD5_LDFLAGS) +# and get Modules/_md5$(EXT_SUFFIX). +# +# LIBHACL_FLAG_I: '-I' flags passed to $(CC) for HACL* and HACL*-based modules +# LIBHACL_FLAG_D: '-D' flags passed to $(CC) for HACL* and HACL*-based modules +# LIBHACL_CFLAGS: compiler flags passed for HACL* and HACL*-based modules +# LIBHACL_LDFLAGS: linker flags passed for HACL* and HACL*-based modules +LIBHACL_FLAG_I='-I$(srcdir)/Modules/_hacl -I$(srcdir)/Modules/_hacl/include' +LIBHACL_FLAG_D='-D_BSD_SOURCE -D_DEFAULT_SOURCE' +case "$ac_sys_system" in + Linux*) + if test "$ac_cv_func_explicit_bzero" = "no"; then + LIBHACL_FLAG_D="${LIBHACL_FLAG_D} -DLINUX_NO_EXPLICIT_BZERO" + fi + ;; +esac +LIBHACL_CFLAGS="${LIBHACL_FLAG_I} ${LIBHACL_FLAG_D} \$(PY_STDMODULE_CFLAGS) \$(CCSHARED)" +AC_SUBST([LIBHACL_CFLAGS]) +LIBHACL_LDFLAGS= # for now, no specific linker flags are needed +AC_SUBST([LIBHACL_LDFLAGS]) + +dnl Check if universal2 HACL* implementation should be used. +if test "$UNIVERSAL_ARCHS" = "universal2" -o \ + \( "$build_cpu" = "aarch64" -a "$build_vendor" = "apple" \) +then + use_hacl_universal2_impl=yes +else + use_hacl_universal2_impl=no +fi + +# The SIMD files use aligned_alloc, which is not available on older versions of +# Android. +# The *mmintrin.h headers are x86-family-specific, so can't be used on WASI. +if test "$ac_sys_system" != "Linux-android" -a "$ac_sys_system" != "WASI" || \ + { test -n "$ANDROID_API_LEVEL" && test "$ANDROID_API_LEVEL" -ge 28; } +then + dnl This can be extended here to detect e.g. Power8, which HACL* should also support. + AX_CHECK_COMPILE_FLAG([-msse -msse2 -msse3 -msse4.1 -msse4.2],[ + [LIBHACL_SIMD128_FLAGS="-msse -msse2 -msse3 -msse4.1 -msse4.2"] + + AC_DEFINE([_Py_HACL_CAN_COMPILE_VEC128], [1], [ + HACL* library can compile SIMD128 implementations]) + + # macOS universal2 builds *support* the -msse etc flags because they're + # available on x86_64. However, performance of the HACL SIMD128 implementation + # isn't great, so it's disabled on ARM64. + AC_MSG_CHECKING([for HACL* SIMD128 implementation]) + if test "$use_hacl_universal2_impl" = "yes"; then + [LIBHACL_BLAKE2_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.o"] + AC_MSG_RESULT([universal2]) + else + [LIBHACL_BLAKE2_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o"] + AC_MSG_RESULT([standard]) + fi + + ], [], [-Werror]) +fi +AC_SUBST([LIBHACL_SIMD128_FLAGS]) +AC_SUBST([LIBHACL_BLAKE2_SIMD128_OBJS]) + +# The SIMD files use aligned_alloc, which is not available on older versions of +# Android. +# The *mmintrin.h headers are x86-family-specific, so can't be used on WASI. +# +# Although AVX support is not guaranteed on Android +# (https://developer.android.com/ndk/guides/abis#86-64), this is safe because we do a +# runtime CPUID check. +if test "$ac_sys_system" != "Linux-android" -a "$ac_sys_system" != "WASI" || \ + { test -n "$ANDROID_API_LEVEL" && test "$ANDROID_API_LEVEL" -ge 28; } +then + AX_CHECK_COMPILE_FLAG([-mavx2],[ + [LIBHACL_SIMD256_FLAGS="-mavx2"] + AC_DEFINE([_Py_HACL_CAN_COMPILE_VEC256], [1], [ + HACL* library can compile SIMD256 implementations]) + + # macOS universal2 builds *support* the -mavx2 compiler flag because it's + # available on x86_64; but the HACL SIMD256 build then fails because the + # implementation requires symbols that aren't available on ARM64. Use a + # wrapped implementation if we're building for universal2. + AC_MSG_CHECKING([for HACL* SIMD256 implementation]) + if test "$use_hacl_universal2_impl" = "yes"; then + [LIBHACL_BLAKE2_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.o"] + AC_MSG_RESULT([universal2]) + else + [LIBHACL_BLAKE2_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o"] + AC_MSG_RESULT([standard]) + fi + ], [], [-Werror]) +fi +AC_SUBST([LIBHACL_SIMD256_FLAGS]) +AC_SUBST([LIBHACL_BLAKE2_SIMD256_OBJS]) +### end(HACL* configuration) + +############################################################################### +# HACL*-based cryptographic primitives + +AC_MSG_CHECKING([for HACL* library linking type]) +if test "$ac_sys_system" = "WASI" || test "$MODULE_BUILDTYPE" = "static"; then + LIBHACL_LDEPS_LIBTYPE=STATIC + AC_MSG_RESULT([static]) +else + LIBHACL_LDEPS_LIBTYPE=SHARED + AC_MSG_RESULT([shared]) +fi +# Used to complete the "MODULE_<NAME>_LDEPS" Makefile variable. +# The LDEPS variable is a Makefile rule prerequisite. +AC_SUBST([LIBHACL_LDEPS_LIBTYPE]) + +dnl PY_HACL_CREATE_MODULE([COMPONENT], [EXTNAME], [ENABLED-TEST]) +dnl The COMPONENT is the name of the HACL* component being built in uppercase. +dnl Corresponding Makefile variables are named as LIBHACL_<COMPONENT>_*. +dnl The EXTNAME is the name of the extension module being built. +AC_DEFUN([PY_HACL_CREATE_MODULE], [ + AS_VAR_PUSHDEF([v], [[LIBHACL_][$1][_LDFLAGS]]) + AS_VAR_SET([v], [[LIBHACL_][$1][_LIB_${LIBHACL_LDEPS_LIBTYPE}]]) + PY_STDLIB_MOD([$2], [$3], [], [$LIBHACL_CFLAGS], [\$($v)]) + AS_VAR_POPDEF([v]) +]) + +dnl By default we always compile these even when OpenSSL is available +dnl (see bpo-14693). The modules are small. +PY_HACL_CREATE_MODULE([MD5], [_md5], [test "$with_builtin_md5" = yes]) +PY_HACL_CREATE_MODULE([SHA1], [_sha1], [test "$with_builtin_sha1" = yes]) +PY_HACL_CREATE_MODULE([SHA2], [_sha2], [test "$with_builtin_sha2" = yes]) +PY_HACL_CREATE_MODULE([SHA3], [_sha3], [test "$with_builtin_sha3" = yes]) +PY_HACL_CREATE_MODULE([BLAKE2], [_blake2], [test "$with_builtin_blake2" = yes]) + +dnl HMAC builtin library does not need OpenSSL for now. In the future +dnl we might want to rely on OpenSSL EVP/NID interface or implement +dnl our own for algorithm resolution. +dnl +dnl For Emscripten, we disable HACL* HMAC as it is tricky to make it work. +dnl See https://github.com/python/cpython/issues/133042. +PY_HACL_CREATE_MODULE([HMAC], [_hmac], [test "$ac_sys_system" != "Emscripten"]) +### end(cryptographic primitives) + +PY_STDLIB_MOD([_ctypes], + [], [test "$have_libffi" = yes], + [$NO_STRICT_OVERFLOW_CFLAGS $LIBFFI_CFLAGS], [$LIBFFI_LIBS]) +PY_STDLIB_MOD([_curses], + [], [test "$have_curses" = "yes"], + [$CURSES_CFLAGS], [$CURSES_LIBS] +) +PY_STDLIB_MOD([_curses_panel], + [], [test "$have_curses" = "yes" && test "$have_panel" = "yes"], + [$PANEL_CFLAGS $CURSES_CFLAGS], [$PANEL_LIBS $CURSES_LIBS] +) +PY_STDLIB_MOD([_decimal], + [], [test "$have_mpdec" = "yes"], + [$LIBMPDEC_CFLAGS], [$LIBMPDEC_LIBS]) + +AS_IF([test "$have_mpdec" = "no"], + [AC_MSG_WARN([m4_normalize([ + no system libmpdec found; falling back to pure-Python version + for the decimal module])])]) + +PY_STDLIB_MOD([_dbm], + [test -n "$with_dbmliborder"], [test "$have_dbm" != "no"], + [$DBM_CFLAGS], [$DBM_LIBS]) +PY_STDLIB_MOD([_gdbm], + [test "$have_gdbm_dbmliborder" = yes], [test "$have_gdbm" = yes], + [$GDBM_CFLAGS], [$GDBM_LIBS]) + PY_STDLIB_MOD([readline], + [], [test "$with_readline" != "no"], + [$READLINE_CFLAGS], [$READLINE_LIBS]) +PY_STDLIB_MOD([_sqlite3], + [test "$have_sqlite3" = "yes"], + [test "$have_supported_sqlite3" = "yes"], + [$LIBSQLITE3_CFLAGS], [$LIBSQLITE3_LIBS]) +PY_STDLIB_MOD([_tkinter], + [], [test "$have_tcltk" = "yes"], + [$TCLTK_CFLAGS], [$TCLTK_LIBS]) +PY_STDLIB_MOD([_uuid], + [], [test "$have_uuid" = "yes"], + [$LIBUUID_CFLAGS], [$LIBUUID_LIBS]) + +dnl compression libs +PY_STDLIB_MOD([zlib], [], [test "$have_zlib" = yes], + [$ZLIB_CFLAGS], [$ZLIB_LIBS]) +dnl binascii can use zlib for optimized crc32. +PY_STDLIB_MOD_SIMPLE([binascii], [$BINASCII_CFLAGS], [$BINASCII_LIBS]) +PY_STDLIB_MOD([_bz2], [], [test "$have_bzip2" = yes], + [$BZIP2_CFLAGS], [$BZIP2_LIBS]) +PY_STDLIB_MOD([_lzma], [], [test "$have_liblzma" = yes], + [$LIBLZMA_CFLAGS], [$LIBLZMA_LIBS]) +PY_STDLIB_MOD([_zstd], [], [test "$have_libzstd" = yes], + [$LIBZSTD_CFLAGS], [$LIBZSTD_LIBS]) + +dnl OpenSSL bindings +PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes], + [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS]) +PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], + [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) + +dnl test modules +AS_CASE([$ac_sys_system], + # On FreeBSD, _testcapi.get_process_memory_usage() calls kvm_openfiles() + # and so needs libkvm. + [FreeBSD*], [LIBKVM="-lkvm"] +) +PY_STDLIB_MOD([_testcapi], + [test "$TEST_MODULES" = yes], + dnl Modules/_testcapi needs -latomic for 32bit AIX build + [], [], [$LIBATOMIC $LIBKVM]) +PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testclinic_limited], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testlimitedcapi], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testbuffer], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([_testsinglephase], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxsubtype], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_xxtestfuzz], [test "$TEST_MODULES" = yes]) +dnl Check have_libffi so _ctypes_test is only built if _ctypes is built. +dnl _ctypes_test doesn't use libffi directly. +PY_STDLIB_MOD([_ctypes_test], + [test "$TEST_MODULES" = yes], [test "$have_libffi" = yes -a "$ac_cv_func_dlopen" = yes], + [], [$LIBM]) + +dnl Limited API template modules. +dnl Emscripten does not support shared libraries yet. +PY_STDLIB_MOD([xxlimited], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxlimited_35], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxlimited_3_13], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) + +# Determine JIT stencils header files based on target platform +JIT_STENCILS_H="" +JIT_SHIM_O="" +JIT_SHIM_BUILD_O="" +AS_VAR_IF([jit_flags], + [], + [], + [if test "${enable_universalsdk}" && test "$UNIVERSAL_ARCHS" = "universal2"; then + JIT_STENCILS_H="jit_stencils-aarch64-apple-darwin.h jit_stencils-x86_64-apple-darwin.h" + JIT_SHIM_O="jit_shim-universal2-apple-darwin.o" + JIT_SHIM_BUILD_O="jit_shim-aarch64-apple-darwin.o jit_shim-x86_64-apple-darwin.o" + else + case "$host" in + aarch64-apple-darwin*) + JIT_STENCILS_H="jit_stencils-aarch64-apple-darwin.h" + JIT_SHIM_O="jit_shim-aarch64-apple-darwin.o" + ;; + x86_64-apple-darwin*) + JIT_STENCILS_H="jit_stencils-x86_64-apple-darwin.h" + JIT_SHIM_O="jit_shim-x86_64-apple-darwin.o" + ;; + aarch64-pc-windows-msvc) + JIT_STENCILS_H="jit_stencils-aarch64-pc-windows-msvc.h" + JIT_SHIM_O="jit_shim-aarch64-pc-windows-msvc.o" + ;; + i686-pc-windows-msvc) + JIT_STENCILS_H="jit_stencils-i686-pc-windows-msvc.h" + JIT_SHIM_O="jit_shim-i686-pc-windows-msvc.o" + ;; + x86_64-pc-windows-msvc) + JIT_STENCILS_H="jit_stencils-x86_64-pc-windows-msvc.h" + JIT_SHIM_O="jit_shim-x86_64-pc-windows-msvc.o" + ;; + aarch64-*-linux-gnu) + JIT_STENCILS_H="jit_stencils-aarch64-unknown-linux-gnu.h" + JIT_SHIM_O="jit_shim-aarch64-unknown-linux-gnu.o" + ;; + x86_64-*-linux-gnu) + JIT_STENCILS_H="jit_stencils-x86_64-unknown-linux-gnu.h" + JIT_SHIM_O="jit_shim-x86_64-unknown-linux-gnu.o" + ;; + esac + JIT_SHIM_BUILD_O="$JIT_SHIM_O" + fi]) + +AC_SUBST([JIT_STENCILS_H]) +AC_SUBST([JIT_SHIM_O]) +AC_SUBST([JIT_SHIM_BUILD_O]) + +# substitute multiline block, must come after last PY_STDLIB_MOD() +AC_SUBST([MODULE_BLOCK]) + +# generate output files +AC_CONFIG_FILES(m4_normalize([ + Makefile.pre + Misc/python.pc + Misc/python-embed.pc + Misc/python-config.sh +])) +AC_CONFIG_FILES(m4_normalize([ + Modules/Setup.bootstrap + Modules/Setup.stdlib +])) +AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) +# Generate files like pyconfig.h +AC_OUTPUT + +AC_MSG_NOTICE([creating Modules/Setup.local]) +if test ! -f Modules/Setup.local +then + echo "# Edit this file for local setup changes" >Modules/Setup.local +fi + +AC_MSG_NOTICE([creating Makefile]) +$SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ + -s Modules \ + Modules/Setup.local Modules/Setup.stdlib Modules/Setup.bootstrap $srcdir/Modules/Setup +if test $? -ne 0; then + AC_MSG_ERROR([makesetup failed]) +fi + +mv config.c Modules + +if test -z "$PKG_CONFIG"; then + AC_MSG_WARN([pkg-config is missing. Some dependencies may not be detected correctly.]) +fi + +if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then + AC_MSG_NOTICE([ + +If you want a release build with all stable optimizations active (PGO, etc), +please run ./configure --enable-optimizations +]) +fi + +AS_VAR_IF([PY_SUPPORT_TIER], [0], [AC_MSG_WARN([ + +Platform "$host" with compiler "$ac_cv_cc_name" is not supported by the +CPython core team, see https://peps.python.org/pep-0011/ for more information. +])]) + +if test "$ac_cv_header_stdatomic_h" != "yes"; then + AC_MSG_NOTICE(m4_normalize([ + Your compiler or platform does have a working C11 stdatomic.h. A future + version of Python may require stdatomic.h. + ])) +fi diff --git a/stdlib/kvlang/reference/python/cpython/install-sh b/stdlib/kvlang/reference/python/cpython/install-sh new file mode 100755 index 00000000..7c56c9c0 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2023-11-23.18; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Report bugs to <bug-automake@gnu.org>. +GNU Automake home page: <https://www.gnu.org/software/automake/>. +General help using GNU software: <https://www.gnu.org/gethelp/>." + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/stdlib/kvlang/reference/python/cpython/pyconfig.h.in b/stdlib/kvlang/reference/python/cpython/pyconfig.h.in new file mode 100644 index 00000000..e798a061 --- /dev/null +++ b/stdlib/kvlang/reference/python/cpython/pyconfig.h.in @@ -0,0 +1,2291 @@ +/* pyconfig.h.in. Generated from configure.ac by autoheader. */ + + +#ifndef Py_PYCONFIG_H +#define Py_PYCONFIG_H + + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the PEP425 tag of the + build system. */ +#undef AIX_BUILDDATE + +/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want + support for AIX C++ shared extension modules. */ +#undef AIX_GENUINE_CPLUSPLUS + +/* The normal alignment of 'long', in bytes. */ +#undef ALIGNOF_LONG + +/* The normal alignment of 'max_align_t', in bytes. */ +#undef ALIGNOF_MAX_ALIGN_T + +/* The normal alignment of 'size_t', in bytes. */ +#undef ALIGNOF_SIZE_T + +/* Alternative SOABI used in debug build to load C extensions built in release + mode */ +#undef ALT_SOABI + +/* The Android API level. */ +#undef ANDROID_API_LEVEL + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most + significant byte first */ +#undef DOUBLE_IS_BIG_ENDIAN_IEEE754 + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 + +/* Define if --enable-ipv6 is specified */ +#undef ENABLE_IPV6 + +/* Define if getpgrp() must be called as getpgrp(0). */ +#undef GETPGRP_HAVE_ARG + +/* Define if you have the 'accept' function. */ +#undef HAVE_ACCEPT + +/* Define to 1 if you have the 'accept4' function. */ +#undef HAVE_ACCEPT4 + +/* Define to 1 if you have the 'acosh' function. */ +#undef HAVE_ACOSH + +/* Define to 1 if you have the 'acospi' function. */ +#undef HAVE_ACOSPI + +/* struct addrinfo (netdb.h) */ +#undef HAVE_ADDRINFO + +/* Define to 1 if you have the 'alarm' function. */ +#undef HAVE_ALARM + +/* Define if aligned memory access is required */ +#undef HAVE_ALIGNED_REQUIRED + +/* Define to 1 if you have the <alloca.h> header file. */ +#undef HAVE_ALLOCA_H + +/* Define this if your time.h defines altzone. */ +#undef HAVE_ALTZONE + +/* Define to 1 if you have the 'asinh' function. */ +#undef HAVE_ASINH + +/* Define to 1 if you have the 'asinpi' function. */ +#undef HAVE_ASINPI + +/* Define to 1 if you have the <asm/types.h> header file. */ +#undef HAVE_ASM_TYPES_H + +/* Define to 1 if you have the 'atan2pi' function. */ +#undef HAVE_ATAN2PI + +/* Define to 1 if you have the 'atanh' function. */ +#undef HAVE_ATANH + +/* Define to 1 if you have the 'atanpi' function. */ +#undef HAVE_ATANPI + +/* Define to 1 if you have the 'backtrace' function. */ +#undef HAVE_BACKTRACE + +/* Define if you have the 'bind' function. */ +#undef HAVE_BIND + +/* Define to 1 if you have the 'bind_textdomain_codeset' function. */ +#undef HAVE_BIND_TEXTDOMAIN_CODESET + +/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */ +#undef HAVE_BLUETOOTH_BLUETOOTH_H + +/* Define to 1 if you have the <bluetooth.h> header file. */ +#undef HAVE_BLUETOOTH_H + +/* Define if mbstowcs(NULL, "text", 0) does not return the number of wide + chars that would be converted. */ +#undef HAVE_BROKEN_MBSTOWCS + +/* Define if nice() returns success/failure instead of the new priority. */ +#undef HAVE_BROKEN_NICE + +/* Define if the system reports an invalid PIPE_BUF value. */ +#undef HAVE_BROKEN_PIPE_BUF + +/* Define if poll() sets errno on invalid file descriptors. */ +#undef HAVE_BROKEN_POLL + +/* Define if the Posix semaphores do not work on your system */ +#undef HAVE_BROKEN_POSIX_SEMAPHORES + +/* Define if pthread_sigmask() does not work on your system. */ +#undef HAVE_BROKEN_PTHREAD_SIGMASK + +/* define to 1 if your sem_getvalue is broken. */ +#undef HAVE_BROKEN_SEM_GETVALUE + +/* Define if 'unsetenv' does not return an int. */ +#undef HAVE_BROKEN_UNSETENV + +/* Has builtin __atomic_load_n() and __atomic_store_n() functions */ +#undef HAVE_BUILTIN_ATOMIC + +/* Define to 1 if you have the <bzlib.h> header file. */ +#undef HAVE_BZLIB_H + +/* Define to 1 if you have the 'chflags' function. */ +#undef HAVE_CHFLAGS + +/* Define to 1 if you have the 'chmod' function. */ +#undef HAVE_CHMOD + +/* Define to 1 if you have the 'chown' function. */ +#undef HAVE_CHOWN + +/* Define if you have the 'chroot' function. */ +#undef HAVE_CHROOT + +/* Define to 1 if you have the 'clearenv' function. */ +#undef HAVE_CLEARENV + +/* Define to 1 if you have the 'clock' function. */ +#undef HAVE_CLOCK + +/* Define to 1 if you have the 'clock_getres' function. */ +#undef HAVE_CLOCK_GETRES + +/* Define to 1 if you have the 'clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the 'clock_nanosleep' function. */ +#undef HAVE_CLOCK_NANOSLEEP + +/* Define to 1 if you have the 'clock_settime' function. */ +#undef HAVE_CLOCK_SETTIME + +/* Define to 1 if the system has the type 'clock_t'. */ +#undef HAVE_CLOCK_T + +/* Define to 1 if you have the 'closefrom' function. */ +#undef HAVE_CLOSEFROM + +/* Define to 1 if you have the 'close_range' function. */ +#undef HAVE_CLOSE_RANGE + +/* Define if the C compiler supports computed gotos. */ +#undef HAVE_COMPUTED_GOTOS + +/* Define to 1 if you have the 'confstr' function. */ +#undef HAVE_CONFSTR + +/* Define to 1 if you have the <conio.h> header file. */ +#undef HAVE_CONIO_H + +/* Define if you have the 'connect' function. */ +#undef HAVE_CONNECT + +/* Define to 1 if you have the 'copy_file_range' function. */ +#undef HAVE_COPY_FILE_RANGE + +/* Define to 1 if you have the 'cospi' function. */ +#undef HAVE_COSPI + +/* Define to 1 if you have the 'ctermid' function. */ +#undef HAVE_CTERMID + +/* Define if you have the 'ctermid_r' function. */ +#undef HAVE_CTERMID_R + +/* Define if you have the 'define_key' function. */ +#undef HAVE_CURSES_DEFINE_KEY + +/* Define if you have the 'ESCDELAY' variable. */ +#undef HAVE_CURSES_ESCDELAY + +/* Define if you have the 'filter' function. */ +#undef HAVE_CURSES_FILTER + +/* Define if you have the 'getmouse' function with the X/Open signature. */ +#undef HAVE_CURSES_GETMOUSE + +/* Define to 1 if you have the <curses.h> header file. */ +#undef HAVE_CURSES_H + +/* Define if you have the 'has_key' function. */ +#undef HAVE_CURSES_HAS_KEY + +/* Define if you have the 'has_mouse' function. */ +#undef HAVE_CURSES_HAS_MOUSE + +/* Define if you have the 'immedok' function. */ +#undef HAVE_CURSES_IMMEDOK + +/* Define if you have the 'is_keypad' function. */ +#undef HAVE_CURSES_IS_KEYPAD + +/* Define if you have the 'is_leaveok' function. */ +#undef HAVE_CURSES_IS_LEAVEOK + +/* Define if you have the 'is_pad' function. */ +#undef HAVE_CURSES_IS_PAD + +/* Define if you have the 'is_term_resized' function. */ +#undef HAVE_CURSES_IS_TERM_RESIZED + +/* Define if you have the 'keyok' function. */ +#undef HAVE_CURSES_KEYOK + +/* Define if you have the 'key_defined' function. */ +#undef HAVE_CURSES_KEY_DEFINED + +/* Define if you have the 'new_prescr' function. */ +#undef HAVE_CURSES_NEW_PRESCR + +/* Define if you have the 'nofilter' function. */ +#undef HAVE_CURSES_NOFILTER + +/* Define if you have the 'resizeterm' function. */ +#undef HAVE_CURSES_RESIZETERM + +/* Define if you have the 'resize_term' function. */ +#undef HAVE_CURSES_RESIZE_TERM + +/* Define if you have the 'scr_dump' function. */ +#undef HAVE_CURSES_SCR_DUMP + +/* Define if you have the 'scr_set' function. */ +#undef HAVE_CURSES_SCR_SET + +/* Define if you have the 'set_escdelay' function. */ +#undef HAVE_CURSES_SET_ESCDELAY + +/* Define if you have the 'set_tabsize' function. */ +#undef HAVE_CURSES_SET_TABSIZE + +/* Define if you have the 'slk_attr_off' function. */ +#undef HAVE_CURSES_SLK_ATTR_OFF + +/* Define if you have the 'slk_attr_on' function. */ +#undef HAVE_CURSES_SLK_ATTR_ON + +/* Define if you have the 'slk_attr_set' function. */ +#undef HAVE_CURSES_SLK_ATTR_SET + +/* Define if you have the 'slk_color' function. */ +#undef HAVE_CURSES_SLK_COLOR + +/* Define if you have the 'syncok' function. */ +#undef HAVE_CURSES_SYNCOK + +/* Define if you have the 'TABSIZE' variable. */ +#undef HAVE_CURSES_TABSIZE + +/* Define if you have the 'term_attrs' function. */ +#undef HAVE_CURSES_TERM_ATTRS + +/* Define if you have the 'typeahead' function. */ +#undef HAVE_CURSES_TYPEAHEAD + +/* Define if you have the 'use_env' function. */ +#undef HAVE_CURSES_USE_ENV + +/* Define if you have the 'use_screen' function. */ +#undef HAVE_CURSES_USE_SCREEN + +/* Define if you have the 'use_window' function. */ +#undef HAVE_CURSES_USE_WINDOW + +/* Define if you have the 'wattr_get' function. */ +#undef HAVE_CURSES_WATTR_GET + +/* Define if you have the 'wattr_off' function. */ +#undef HAVE_CURSES_WATTR_OFF + +/* Define if you have the 'wattr_on' function. */ +#undef HAVE_CURSES_WATTR_ON + +/* Define if you have the 'wattr_set' function. */ +#undef HAVE_CURSES_WATTR_SET + +/* Define if you have the 'wchgat' function. */ +#undef HAVE_CURSES_WCHGAT + +/* Define if you have the 'wcolor_set' function. */ +#undef HAVE_CURSES_WCOLOR_SET + +/* Define to 1 if you have the <db.h> header file. */ +#undef HAVE_DB_H + +/* Define to 1 if you have the declaration of 'PR_SET_VMA_ANON_NAME', and to 0 + if you don't. */ +#undef HAVE_DECL_PR_SET_VMA_ANON_NAME + +/* Define to 1 if you have the declaration of 'RTLD_DEEPBIND', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_DEEPBIND + +/* Define to 1 if you have the declaration of 'RTLD_GLOBAL', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_GLOBAL + +/* Define to 1 if you have the declaration of 'RTLD_LAZY', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_LAZY + +/* Define to 1 if you have the declaration of 'RTLD_LOCAL', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_LOCAL + +/* Define to 1 if you have the declaration of 'RTLD_MEMBER', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_MEMBER + +/* Define to 1 if you have the declaration of 'RTLD_NODELETE', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_NODELETE + +/* Define to 1 if you have the declaration of 'RTLD_NOLOAD', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_NOLOAD + +/* Define to 1 if you have the declaration of 'RTLD_NOW', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_NOW + +/* Define to 1 if you have the declaration of 'tzname', and to 0 if you don't. + */ +#undef HAVE_DECL_TZNAME + +/* Define to 1 if you have the declaration of 'UT_NAMESIZE', and to 0 if you + don't. */ +#undef HAVE_DECL_UT_NAMESIZE + +/* Define to 1 if you have the device macros. */ +#undef HAVE_DEVICE_MACROS + +/* Define to 1 if you have the /dev/ptc device file. */ +#undef HAVE_DEV_PTC + +/* Define to 1 if you have the /dev/ptmx device file. */ +#undef HAVE_DEV_PTMX + +/* Define to 1 if you have the <direct.h> header file. */ +#undef HAVE_DIRECT_H + +/* Define to 1 if the dirent structure has a d_type field */ +#undef HAVE_DIRENT_D_TYPE + +/* Define to 1 if you have the <dirent.h> header file, and it defines 'DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define if you have the 'dirfd' function or macro. */ +#undef HAVE_DIRFD + +/* Define to 1 if you have the 'dladdr' function. */ +#undef HAVE_DLADDR + +/* Define to 1 if you have the 'dladdr1' function. */ +#undef HAVE_DLADDR1 + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the 'dlopen' function. */ +#undef HAVE_DLOPEN + +/* Define to 1 if you have the 'dl_iterate_phdr' function. */ +#undef HAVE_DL_ITERATE_PHDR + +/* Define to 1 if you have the 'dup' function. */ +#undef HAVE_DUP + +/* Define to 1 if you have the 'dup2' function. */ +#undef HAVE_DUP2 + +/* Define to 1 if you have the 'dup3' function. */ +#undef HAVE_DUP3 + +/* Define if you have the '_dyld_shared_cache_contains_path' function. */ +#undef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH + +/* Defined when any dynamic module loading is enabled. */ +#undef HAVE_DYNAMIC_LOADING + +/* Define to 1 if you have the <editline/readline.h> header file. */ +#undef HAVE_EDITLINE_READLINE_H + +/* Define to 1 if you have the <endian.h> header file. */ +#undef HAVE_ENDIAN_H + +/* Define if you have the 'epoll_create' function. */ +#undef HAVE_EPOLL + +/* Define if you have the 'epoll_create1' function. */ +#undef HAVE_EPOLL_CREATE1 + +/* Define to 1 if you have the 'erf' function. */ +#undef HAVE_ERF + +/* Define to 1 if you have the 'erfc' function. */ +#undef HAVE_ERFC + +/* Define to 1 if you have the <errno.h> header file. */ +#undef HAVE_ERRNO_H + +/* Define if you have the 'eventfd' function. */ +#undef HAVE_EVENTFD + +/* Define to 1 if you have the <execinfo.h> header file. */ +#undef HAVE_EXECINFO_H + +/* Define to 1 if you have the 'execv' function. */ +#undef HAVE_EXECV + +/* Define to 1 if you have the 'explicit_bzero' function. */ +#undef HAVE_EXPLICIT_BZERO + +/* Define to 1 if you have the 'explicit_memset' function. */ +#undef HAVE_EXPLICIT_MEMSET + +/* Define to 1 if you have the 'expm1' function. */ +#undef HAVE_EXPM1 + +/* Define to 1 if you have the 'faccessat' function. */ +#undef HAVE_FACCESSAT + +/* Define if you have the 'fchdir' function. */ +#undef HAVE_FCHDIR + +/* Define to 1 if you have the 'fchmod' function. */ +#undef HAVE_FCHMOD + +/* Define to 1 if you have the 'fchmodat' function. */ +#undef HAVE_FCHMODAT + +/* Define to 1 if you have the 'fchown' function. */ +#undef HAVE_FCHOWN + +/* Define to 1 if you have the 'fchownat' function. */ +#undef HAVE_FCHOWNAT + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the 'fdatasync' function. */ +#undef HAVE_FDATASYNC + +/* Define to 1 if you have the 'fdopendir' function. */ +#undef HAVE_FDOPENDIR + +/* Define to 1 if you have the 'fdwalk' function. */ +#undef HAVE_FDWALK + +/* Define to 1 if you have the 'fexecve' function. */ +#undef HAVE_FEXECVE + +/* Define if you have the 'ffi_closure_alloc' function. */ +#undef HAVE_FFI_CLOSURE_ALLOC + +/* Define if you have the 'ffi_prep_cif_var' function. */ +#undef HAVE_FFI_PREP_CIF_VAR + +/* Define if you have the 'ffi_prep_closure_loc' function. */ +#undef HAVE_FFI_PREP_CLOSURE_LOC + +/* Defined if _Float16 C type is supported */ +#undef HAVE_FLOAT16 + +/* Define to 1 if you have the 'flock' function. */ +#undef HAVE_FLOCK + +/* Define to 1 if you have the 'fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the 'fork1' function. */ +#undef HAVE_FORK1 + +/* Define to 1 if you have the 'forkpty' function. */ +#undef HAVE_FORKPTY + +/* Define to 1 if you have the 'fpathconf' function. */ +#undef HAVE_FPATHCONF + +/* Define to 1 if you have the 'fseek64' function. */ +#undef HAVE_FSEEK64 + +/* Define to 1 if you have the 'fseeko' function. */ +#undef HAVE_FSEEKO + +/* Define to 1 if you have the 'fstatat' function. */ +#undef HAVE_FSTATAT + +/* Define to 1 if you have the 'fstatvfs' function. */ +#undef HAVE_FSTATVFS + +/* Define if you have the 'fsync' function. */ +#undef HAVE_FSYNC + +/* Define to 1 if you have the 'ftell64' function. */ +#undef HAVE_FTELL64 + +/* Define to 1 if you have the 'ftello' function. */ +#undef HAVE_FTELLO + +/* Define to 1 if you have the 'ftime' function. */ +#undef HAVE_FTIME + +/* Define to 1 if you have the 'ftruncate' function. */ +#undef HAVE_FTRUNCATE + +/* Define to 1 if you have the 'futimens' function. */ +#undef HAVE_FUTIMENS + +/* Define to 1 if you have the 'futimes' function. */ +#undef HAVE_FUTIMES + +/* Define to 1 if you have the 'futimesat' function. */ +#undef HAVE_FUTIMESAT + +/* Define to 1 if you have the 'gai_strerror' function. */ +#undef HAVE_GAI_STRERROR + +/* Define if we can use gcc inline assembler to get and set mc68881 fpcr */ +#undef HAVE_GCC_ASM_FOR_MC68881 + +/* Define if we can use x64 gcc inline assembler */ +#undef HAVE_GCC_ASM_FOR_X64 + +/* Define if we can use gcc inline assembler to get and set x87 control word + */ +#undef HAVE_GCC_ASM_FOR_X87 + +/* Define if your compiler provides __uint128_t */ +#undef HAVE_GCC_UINT128_T + +/* Define to 1 if you have the <gdbm-ndbm.h> header file. */ +#undef HAVE_GDBM_DASH_NDBM_H + +/* Define to 1 if you have the <gdbm.h> header file. */ +#undef HAVE_GDBM_H + +/* Define to 1 if you have the <gdbm/ndbm.h> header file. */ +#undef HAVE_GDBM_NDBM_H + +/* Define if you have the getaddrinfo function. */ +#undef HAVE_GETADDRINFO + +/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ +#undef HAVE_GETC_UNLOCKED + +/* Define to 1 if you have the 'getdents64' function. */ +#undef HAVE_GETDENTS64 + +/* Define to 1 if you have the 'getegid' function. */ +#undef HAVE_GETEGID + +/* Define to 1 if you have the 'getentropy' function. */ +#undef HAVE_GETENTROPY + +/* Define to 1 if you have the 'geteuid' function. */ +#undef HAVE_GETEUID + +/* Define to 1 if you have the 'getgid' function. */ +#undef HAVE_GETGID + +/* Define to 1 if you have the 'getgrent' function. */ +#undef HAVE_GETGRENT + +/* Define to 1 if you have the 'getgrgid' function. */ +#undef HAVE_GETGRGID + +/* Define to 1 if you have the 'getgrgid_r' function. */ +#undef HAVE_GETGRGID_R + +/* Define to 1 if you have the 'getgrnam_r' function. */ +#undef HAVE_GETGRNAM_R + +/* Define to 1 if you have the 'getgrouplist' function. */ +#undef HAVE_GETGROUPLIST + +/* Define to 1 if you have the 'getgroups' function. */ +#undef HAVE_GETGROUPS + +/* Define if you have the 'gethostbyaddr' function. */ +#undef HAVE_GETHOSTBYADDR + +/* Define to 1 if you have the 'gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define this if you have some version of gethostbyname_r() */ +#undef HAVE_GETHOSTBYNAME_R + +/* Define this if you have the 3-arg version of gethostbyname_r(). */ +#undef HAVE_GETHOSTBYNAME_R_3_ARG + +/* Define this if you have the 5-arg version of gethostbyname_r(). */ +#undef HAVE_GETHOSTBYNAME_R_5_ARG + +/* Define this if you have the 6-arg version of gethostbyname_r(). */ +#undef HAVE_GETHOSTBYNAME_R_6_ARG + +/* Define to 1 if you have the 'gethostname' function. */ +#undef HAVE_GETHOSTNAME + +/* Define to 1 if you have the 'getitimer' function. */ +#undef HAVE_GETITIMER + +/* Define to 1 if you have the 'getloadavg' function. */ +#undef HAVE_GETLOADAVG + +/* Define to 1 if you have the 'getlogin' function. */ +#undef HAVE_GETLOGIN + +/* Define to 1 if you have the 'getlogin_r' function. */ +#undef HAVE_GETLOGIN_R + +/* Define to 1 if you have the 'getnameinfo' function. */ +#undef HAVE_GETNAMEINFO + +/* Define if you have the 'getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the 'getpeername' function. */ +#undef HAVE_GETPEERNAME + +/* Define to 1 if you have the 'getpgid' function. */ +#undef HAVE_GETPGID + +/* Define to 1 if you have the 'getpgrp' function. */ +#undef HAVE_GETPGRP + +/* Define to 1 if you have the 'getpid' function. */ +#undef HAVE_GETPID + +/* Define to 1 if you have the 'getppid' function. */ +#undef HAVE_GETPPID + +/* Define to 1 if you have the 'getpriority' function. */ +#undef HAVE_GETPRIORITY + +/* Define if you have the 'getprotobyname' function. */ +#undef HAVE_GETPROTOBYNAME + +/* Define to 1 if you have the 'getpwent' function. */ +#undef HAVE_GETPWENT + +/* Define to 1 if you have the 'getpwnam_r' function. */ +#undef HAVE_GETPWNAM_R + +/* Define to 1 if you have the 'getpwuid' function. */ +#undef HAVE_GETPWUID + +/* Define to 1 if you have the 'getpwuid_r' function. */ +#undef HAVE_GETPWUID_R + +/* Define to 1 if the getrandom() function is available */ +#undef HAVE_GETRANDOM + +/* Define to 1 if the Linux getrandom() syscall is available */ +#undef HAVE_GETRANDOM_SYSCALL + +/* Define to 1 if you have the 'getresgid' function. */ +#undef HAVE_GETRESGID + +/* Define to 1 if you have the 'getresuid' function. */ +#undef HAVE_GETRESUID + +/* Define to 1 if you have the 'getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define if you have the 'getservbyname' function. */ +#undef HAVE_GETSERVBYNAME + +/* Define if you have the 'getservbyport' function. */ +#undef HAVE_GETSERVBYPORT + +/* Define to 1 if you have the 'getsid' function. */ +#undef HAVE_GETSID + +/* Define if you have the 'getsockname' function. */ +#undef HAVE_GETSOCKNAME + +/* Define to 1 if you have the 'getspent' function. */ +#undef HAVE_GETSPENT + +/* Define to 1 if you have the 'getspnam' function. */ +#undef HAVE_GETSPNAM + +/* Define to 1 if you have the 'gettid' function. */ +#undef HAVE_GETTID + +/* Define to 1 if you have the 'getuid' function. */ +#undef HAVE_GETUID + +/* Define to 1 if you have the 'getwd' function. */ +#undef HAVE_GETWD + +/* Define if glibc has incorrect _FORTIFY_SOURCE wrappers for memmove and + bcopy. */ +#undef HAVE_GLIBC_MEMMOVE_BUG + +/* Define to 1 if you have the 'grantpt' function. */ +#undef HAVE_GRANTPT + +/* Define to 1 if you have the <grp.h> header file. */ +#undef HAVE_GRP_H + +/* Define if you have the 'hstrerror' function. */ +#undef HAVE_HSTRERROR + +/* Define this if you have le64toh() */ +#undef HAVE_HTOLE64 + +/* Define if you have a working iconv() function. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the <iconv.h> header file. */ +#undef HAVE_ICONV_H + +/* Define to 1 if you have the 'if_indextoname' function. */ +#undef HAVE_IF_INDEXTONAME + +/* Define to 1 if you have the 'if_nameindex' function. */ +#undef HAVE_IF_NAMEINDEX + +/* Define to 1 if you have the 'if_nametoindex' function. */ +#undef HAVE_IF_NAMETOINDEX + +/* Define if you have the 'inet_aton' function. */ +#undef HAVE_INET_ATON + +/* Define if you have the 'inet_ntoa' function. */ +#undef HAVE_INET_NTOA + +/* Define if you have the 'inet_pton' function. */ +#undef HAVE_INET_PTON + +/* Define to 1 if you have the 'initgroups' function. */ +#undef HAVE_INITGROUPS + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <io.h> header file. */ +#undef HAVE_IO_H + +/* Define if gcc has the ipa-pure-const bug. */ +#undef HAVE_IPA_PURE_CONST_BUG + +/* Define to 1 if you have the 'kill' function. */ +#undef HAVE_KILL + +/* Define to 1 if you have the 'killpg' function. */ +#undef HAVE_KILLPG + +/* Define if you have the 'kqueue' function. */ +#undef HAVE_KQUEUE + +/* Define to 1 if you have the <langinfo.h> header file. */ +#undef HAVE_LANGINFO_H + +/* Defined to enable large file support when an off_t is bigger than a long + and long long is at least as big as an off_t. You may need to add some + flags for configuration and compilation to enable this mode. (For Solaris + and Linux, the necessary defines are already defined.) */ +#undef HAVE_LARGEFILE_SUPPORT + +/* Define to 1 if you have the 'lchflags' function. */ +#undef HAVE_LCHFLAGS + +/* Define to 1 if you have the 'lchmod' function. */ +#undef HAVE_LCHMOD + +/* Define to 1 if you have the 'lchown' function. */ +#undef HAVE_LCHOWN + +/* Define to 1 if you have the `db' library (-ldb). */ +#undef HAVE_LIBDB + +/* Define to 1 if you have the 'dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the 'dld' library (-ldld). */ +#undef HAVE_LIBDLD + +/* Define to 1 if you have the 'ieee' library (-lieee). */ +#undef HAVE_LIBIEEE + +/* Define to 1 if you have the <libintl.h> header file. */ +#undef HAVE_LIBINTL_H + +/* Define to 1 if you have the 'sendfile' library (-lsendfile). */ +#undef HAVE_LIBSENDFILE + +/* Define to 1 if you have the 'sqlite3' library (-lsqlite3). */ +#undef HAVE_LIBSQLITE3 + +/* Define to 1 if you have the <libutil.h> header file. */ +#undef HAVE_LIBUTIL_H + +/* Define if you have the 'link' function. */ +#undef HAVE_LINK + +/* Define to 1 if you have the 'linkat' function. */ +#undef HAVE_LINKAT + +/* Define to 1 if you have the <link.h> header file. */ +#undef HAVE_LINK_H + +/* Define to 1 if you have the <linux/auxvec.h> header file. */ +#undef HAVE_LINUX_AUXVEC_H + +/* Define to 1 if you have the <linux/can/bcm.h> header file. */ +#undef HAVE_LINUX_CAN_BCM_H + +/* Define to 1 if you have the <linux/can.h> header file. */ +#undef HAVE_LINUX_CAN_H + +/* Define to 1 if you have the <linux/can/isotp.h> header file. */ +#undef HAVE_LINUX_CAN_ISOTP_H + +/* Define to 1 if you have the <linux/can/j1939.h> header file. */ +#undef HAVE_LINUX_CAN_J1939_H + +/* Define if compiling using Linux 3.6 or later. */ +#undef HAVE_LINUX_CAN_RAW_FD_FRAMES + +/* Define to 1 if you have the <linux/can/raw.h> header file. */ +#undef HAVE_LINUX_CAN_RAW_H + +/* Define if compiling using Linux 4.1 or later. */ +#undef HAVE_LINUX_CAN_RAW_JOIN_FILTERS + +/* Define to 1 if you have the <linux/fs.h> header file. */ +#undef HAVE_LINUX_FS_H + +/* Define to 1 if you have the <linux/limits.h> header file. */ +#undef HAVE_LINUX_LIMITS_H + +/* Define to 1 if you have the <linux/memfd.h> header file. */ +#undef HAVE_LINUX_MEMFD_H + +/* Define to 1 if you have the <linux/netfilter_ipv4.h> header file. */ +#undef HAVE_LINUX_NETFILTER_IPV4_H + +/* Define to 1 if you have the <linux/netlink.h> header file. */ +#undef HAVE_LINUX_NETLINK_H + +/* Define to 1 if you have the <linux/qrtr.h> header file. */ +#undef HAVE_LINUX_QRTR_H + +/* Define to 1 if you have the <linux/random.h> header file. */ +#undef HAVE_LINUX_RANDOM_H + +/* Define to 1 if you have the <linux/sched.h> header file. */ +#undef HAVE_LINUX_SCHED_H + +/* Define to 1 if you have the <linux/soundcard.h> header file. */ +#undef HAVE_LINUX_SOUNDCARD_H + +/* Define to 1 if you have the <linux/tipc.h> header file. */ +#undef HAVE_LINUX_TIPC_H + +/* Define to 1 if you have the <linux/vm_sockets.h> header file. */ +#undef HAVE_LINUX_VM_SOCKETS_H + +/* Define to 1 if you have the <linux/wait.h> header file. */ +#undef HAVE_LINUX_WAIT_H + +/* Define if you have the 'listen' function. */ +#undef HAVE_LISTEN + +/* Define to 1 if you have the 'lockf' function. */ +#undef HAVE_LOCKF + +/* Define to 1 if you have the 'log1p' function. */ +#undef HAVE_LOG1P + +/* Define to 1 if you have the 'log2' function. */ +#undef HAVE_LOG2 + +/* Define to 1 if you have the `login_tty' function. */ +#undef HAVE_LOGIN_TTY + +/* Define to 1 if the system has the type 'long double'. */ +#undef HAVE_LONG_DOUBLE + +/* Define to 1 if you have the 'lstat' function. */ +#undef HAVE_LSTAT + +/* Define to 1 if you have the 'lutimes' function. */ +#undef HAVE_LUTIMES + +/* Define to 1 if you have the <lzma.h> header file. */ +#undef HAVE_LZMA_H + +/* Define to 1 if you have the 'madvise' function. */ +#undef HAVE_MADVISE + +/* Define this if you have the makedev macro. */ +#undef HAVE_MAKEDEV + +/* Define if you have the 'MAXLOGNAME' constant. */ +#undef HAVE_MAXLOGNAME + +/* Define to 1 if you have the 'mbrtowc' function. */ +#undef HAVE_MBRTOWC + +/* Define if you have the 'memfd_create' function. */ +#undef HAVE_MEMFD_CREATE + +/* Define to 1 if you have the 'memrchr' function. */ +#undef HAVE_MEMRCHR + +/* Define to 1 if you have the <minix/config.h> header file. */ +#undef HAVE_MINIX_CONFIG_H + +/* Define to 1 if you have the 'mkdirat' function. */ +#undef HAVE_MKDIRAT + +/* Define to 1 if you have the 'mkfifo' function. */ +#undef HAVE_MKFIFO + +/* Define to 1 if you have the 'mkfifoat' function. */ +#undef HAVE_MKFIFOAT + +/* Define to 1 if you have the 'mknod' function. */ +#undef HAVE_MKNOD + +/* Define to 1 if you have the 'mknodat' function. */ +#undef HAVE_MKNODAT + +/* Define to 1 if you have the 'mktime' function. */ +#undef HAVE_MKTIME + +/* Define to 1 if you have the 'mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the 'mremap' function. */ +#undef HAVE_MREMAP + +/* Define to 1 if you have the 'nanosleep' function. */ +#undef HAVE_NANOSLEEP + +/* Define if you have the 'ncurses' library */ +#undef HAVE_NCURSES + +/* Define if you have the 'ncursesw' library */ +#undef HAVE_NCURSESW + +/* Define to 1 if you have the <ncursesw/curses.h> header file. */ +#undef HAVE_NCURSESW_CURSES_H + +/* Define to 1 if you have the <ncursesw/ncurses.h> header file. */ +#undef HAVE_NCURSESW_NCURSES_H + +/* Define to 1 if you have the <ncursesw/panel.h> header file. */ +#undef HAVE_NCURSESW_PANEL_H + +/* Define to 1 if you have the <ncurses/curses.h> header file. */ +#undef HAVE_NCURSES_CURSES_H + +/* Define to 1 if you have the <ncurses.h> header file. */ +#undef HAVE_NCURSES_H + +/* Define to 1 if you have the <ncurses/ncurses.h> header file. */ +#undef HAVE_NCURSES_NCURSES_H + +/* Define to 1 if you have the <ncurses/panel.h> header file. */ +#undef HAVE_NCURSES_PANEL_H + +/* Define to 1 if you have the <ndbm.h> header file. */ +#undef HAVE_NDBM_H + +/* Define to 1 if you have the <ndir.h> header file, and it defines 'DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the <netcan/can.h> header file. */ +#undef HAVE_NETCAN_CAN_H + +/* Define to 1 if you have the <netdb.h> header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the <netlink/netlink.h> header file. */ +#undef HAVE_NETLINK_NETLINK_H + +/* Define to 1 if you have the <netpacket/packet.h> header file. */ +#undef HAVE_NETPACKET_PACKET_H + +/* Define to 1 if you have the <net/ethernet.h> header file. */ +#undef HAVE_NET_ETHERNET_H + +/* Define to 1 if you have the <net/if.h> header file. */ +#undef HAVE_NET_IF_H + +/* Define to 1 if you have the 'nice' function. */ +#undef HAVE_NICE + +/* Define if the internal form of wchar_t in non-Unicode locales is not + Unicode. */ +#undef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION + +/* Define to 1 if you have the 'openat' function. */ +#undef HAVE_OPENAT + +/* Define to 1 if you have the 'opendir' function. */ +#undef HAVE_OPENDIR + +/* Define to 1 if you have the 'openpty' function. */ +#undef HAVE_OPENPTY + +/* Define if you have the 'panel' library */ +#undef HAVE_PANEL + +/* Define if you have the 'panelw' library */ +#undef HAVE_PANELW + +/* Define to 1 if you have the <panel.h> header file. */ +#undef HAVE_PANEL_H + +/* Define to 1 if you have the 'pathconf' function. */ +#undef HAVE_PATHCONF + +/* Define to 1 if you have the 'pause' function. */ +#undef HAVE_PAUSE + +/* Define to 1 if you have the 'pidfd_getfd' function. */ +#undef HAVE_PIDFD_GETFD + +/* Define to 1 if you have the 'pidfd_open' function. */ +#undef HAVE_PIDFD_OPEN + +/* Define to 1 if you have the 'pidfd_send_signal' function. */ +#undef HAVE_PIDFD_SEND_SIGNAL + +/* Define to 1 if you have the 'pipe' function. */ +#undef HAVE_PIPE + +/* Define to 1 if you have the 'pipe2' function. */ +#undef HAVE_PIPE2 + +/* Define to 1 if you have the 'plock' function. */ +#undef HAVE_PLOCK + +/* Define to 1 if you have the 'poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the <poll.h> header file. */ +#undef HAVE_POLL_H + +/* Define to 1 if you have the 'posix_fadvise' function. */ +#undef HAVE_POSIX_FADVISE + +/* Define to 1 if you have the 'posix_fallocate' function. */ +#undef HAVE_POSIX_FALLOCATE + +/* Define to 1 if you have the 'posix_openpt' function. */ +#undef HAVE_POSIX_OPENPT + +/* Define to 1 if you have the 'posix_spawn' function. */ +#undef HAVE_POSIX_SPAWN + +/* Define to 1 if you have the 'posix_spawnp' function. */ +#undef HAVE_POSIX_SPAWNP + +/* Define to 1 if you have the 'posix_spawn_file_actions_addclosefrom_np' + function. */ +#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP + +/* Define to 1 if you have the 'ppoll' function. */ +#undef HAVE_PPOLL + +/* Define to 1 if you have the 'pread' function. */ +#undef HAVE_PREAD + +/* Define to 1 if you have the 'preadv' function. */ +#undef HAVE_PREADV + +/* Define to 1 if you have the 'preadv2' function. */ +#undef HAVE_PREADV2 + +/* Define if you have the 'prlimit' function. */ +#undef HAVE_PRLIMIT + +/* Define to 1 if you have the <process.h> header file. */ +#undef HAVE_PROCESS_H + +/* Define to 1 if you have the 'process_vm_readv' function. */ +#undef HAVE_PROCESS_VM_READV + +/* Define if your compiler supports function prototype */ +#undef HAVE_PROTOTYPES + +/* Define to 1 if you have the 'pthread_condattr_setclock' function. */ +#undef HAVE_PTHREAD_CONDATTR_SETCLOCK + +/* Define to 1 if you have the 'pthread_cond_timedwait_relative_np' function. + */ +#undef HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP + +/* Defined for Solaris 2.6 bug in pthread header. */ +#undef HAVE_PTHREAD_DESTRUCTOR + +/* Define to 1 if you have the 'pthread_getattr_np' function. */ +#undef HAVE_PTHREAD_GETATTR_NP + +/* Define to 1 if you have the 'pthread_getcpuclockid' function. */ +#undef HAVE_PTHREAD_GETCPUCLOCKID + +/* Define to 1 if you have the 'pthread_getname_np' function. */ +#undef HAVE_PTHREAD_GETNAME_NP + +/* Define to 1 if you have the 'pthread_get_name_np' function. */ +#undef HAVE_PTHREAD_GET_NAME_NP + +/* Define to 1 if you have the <pthread.h> header file. */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if you have the 'pthread_init' function. */ +#undef HAVE_PTHREAD_INIT + +/* Define to 1 if you have the 'pthread_kill' function. */ +#undef HAVE_PTHREAD_KILL + +/* Define to 1 if you have the 'pthread_setname_np' function. */ +#undef HAVE_PTHREAD_SETNAME_NP + +/* Define to 1 if you have the 'pthread_set_name_np' function. */ +#undef HAVE_PTHREAD_SET_NAME_NP + +/* Define to 1 if you have the 'pthread_sigmask' function. */ +#undef HAVE_PTHREAD_SIGMASK + +/* Define if platform requires stubbed pthreads support */ +#undef HAVE_PTHREAD_STUBS + +/* Define to 1 if you have the 'ptsname' function. */ +#undef HAVE_PTSNAME + +/* Define to 1 if you have the 'ptsname_r' function. */ +#undef HAVE_PTSNAME_R + +/* Define to 1 if you have the <pty.h> header file. */ +#undef HAVE_PTY_H + +/* Define to 1 if you have the 'pwrite' function. */ +#undef HAVE_PWRITE + +/* Define to 1 if you have the 'pwritev' function. */ +#undef HAVE_PWRITEV + +/* Define to 1 if you have the 'pwritev2' function. */ +#undef HAVE_PWRITEV2 + +/* Define to 1 if you have the <readline/readline.h> header file. */ +#undef HAVE_READLINE_READLINE_H + +/* Define to 1 if you have the 'readlink' function. */ +#undef HAVE_READLINK + +/* Define to 1 if you have the 'readlinkat' function. */ +#undef HAVE_READLINKAT + +/* Define to 1 if you have the 'readv' function. */ +#undef HAVE_READV + +/* Define to 1 if you have the 'realpath' function. */ +#undef HAVE_REALPATH + +/* Define if you have the 'recvfrom' function. */ +#undef HAVE_RECVFROM + +/* Define to 1 if you have the 'renameat' function. */ +#undef HAVE_RENAMEAT + +/* Define if readline supports append_history */ +#undef HAVE_RL_APPEND_HISTORY + +/* Define if you can turn off readline's signal handling. */ +#undef HAVE_RL_CATCH_SIGNAL + +/* Define if you have readline 6.3 */ +#undef HAVE_RL_CHANGE_ENVIRONMENT + +/* Define to 1 if the system has the type 'rl_compdisp_func_t'. */ +#undef HAVE_RL_COMPDISP_FUNC_T + +/* Define if you have readline 2.2 */ +#undef HAVE_RL_COMPLETION_APPEND_CHARACTER + +/* Define if you have readline 4.0 */ +#undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK + +/* Define if you have readline 4.2 */ +#undef HAVE_RL_COMPLETION_MATCHES + +/* Define if you have rl_completion_suppress_append */ +#undef HAVE_RL_COMPLETION_SUPPRESS_APPEND + +/* Define if you have readline 4.0 */ +#undef HAVE_RL_PRE_INPUT_HOOK + +/* Define if you have readline 4.0 */ +#undef HAVE_RL_RESIZE_TERMINAL + +/* Define to 1 if you have the 'rtpSpawn' function. */ +#undef HAVE_RTPSPAWN + +/* Define to 1 if you have the 'sched_get_priority_max' function. */ +#undef HAVE_SCHED_GET_PRIORITY_MAX + +/* Define to 1 if you have the <sched.h> header file. */ +#undef HAVE_SCHED_H + +/* Define to 1 if you have the 'sched_rr_get_interval' function. */ +#undef HAVE_SCHED_RR_GET_INTERVAL + +/* Define to 1 if you have the 'sched_setaffinity' function. */ +#undef HAVE_SCHED_SETAFFINITY + +/* Define to 1 if you have the 'sched_setparam' function. */ +#undef HAVE_SCHED_SETPARAM + +/* Define to 1 if you have the 'sched_setscheduler' function. */ +#undef HAVE_SCHED_SETSCHEDULER + +/* Define to 1 if you have the 'sem_clockwait' function. */ +#undef HAVE_SEM_CLOCKWAIT + +/* Define to 1 if you have the 'sem_getvalue' function. */ +#undef HAVE_SEM_GETVALUE + +/* Define to 1 if you have the 'sem_open' function. */ +#undef HAVE_SEM_OPEN + +/* Define to 1 if you have the 'sem_timedwait' function. */ +#undef HAVE_SEM_TIMEDWAIT + +/* Define to 1 if you have the 'sem_unlink' function. */ +#undef HAVE_SEM_UNLINK + +/* Define to 1 if you have the 'sendfile' function. */ +#undef HAVE_SENDFILE + +/* Define if you have the 'sendto' function. */ +#undef HAVE_SENDTO + +/* Define to 1 if you have the 'setegid' function. */ +#undef HAVE_SETEGID + +/* Define to 1 if you have the 'seteuid' function. */ +#undef HAVE_SETEUID + +/* Define to 1 if you have the 'setgid' function. */ +#undef HAVE_SETGID + +/* Define if you have the 'setgroups' function. */ +#undef HAVE_SETGROUPS + +/* Define to 1 if you have the 'sethostname' function. */ +#undef HAVE_SETHOSTNAME + +/* Define to 1 if you have the 'setitimer' function. */ +#undef HAVE_SETITIMER + +/* Define to 1 if you have the <setjmp.h> header file. */ +#undef HAVE_SETJMP_H + +/* Define to 1 if you have the 'setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the 'setns' function. */ +#undef HAVE_SETNS + +/* Define to 1 if you have the 'setpgid' function. */ +#undef HAVE_SETPGID + +/* Define to 1 if you have the 'setpgrp' function. */ +#undef HAVE_SETPGRP + +/* Define to 1 if you have the 'setpriority' function. */ +#undef HAVE_SETPRIORITY + +/* Define to 1 if you have the 'setregid' function. */ +#undef HAVE_SETREGID + +/* Define to 1 if you have the 'setresgid' function. */ +#undef HAVE_SETRESGID + +/* Define to 1 if you have the 'setresuid' function. */ +#undef HAVE_SETRESUID + +/* Define to 1 if you have the 'setreuid' function. */ +#undef HAVE_SETREUID + +/* Define to 1 if you have the 'setsid' function. */ +#undef HAVE_SETSID + +/* Define if you have the 'setsockopt' function. */ +#undef HAVE_SETSOCKOPT + +/* Define to 1 if you have the 'setuid' function. */ +#undef HAVE_SETUID + +/* Define to 1 if you have the 'setvbuf' function. */ +#undef HAVE_SETVBUF + +/* Define to 1 if you have the <shadow.h> header file. */ +#undef HAVE_SHADOW_H + +/* Define to 1 if you have the 'shm_open' function. */ +#undef HAVE_SHM_OPEN + +/* Define to 1 if you have the 'shm_unlink' function. */ +#undef HAVE_SHM_UNLINK + +/* Define to 1 if you have the 'shutdown' function. */ +#undef HAVE_SHUTDOWN + +/* Define to 1 if you have the 'sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the 'sigaltstack' function. */ +#undef HAVE_SIGALTSTACK + +/* Define to 1 if you have the 'sigfillset' function. */ +#undef HAVE_SIGFILLSET + +/* Define to 1 if 'si_band' is a member of 'siginfo_t'. */ +#undef HAVE_SIGINFO_T_SI_BAND + +/* Define to 1 if you have the 'siginterrupt' function. */ +#undef HAVE_SIGINTERRUPT + +/* Define to 1 if you have the <signal.h> header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the 'sigpending' function. */ +#undef HAVE_SIGPENDING + +/* Define to 1 if you have the 'sigrelse' function. */ +#undef HAVE_SIGRELSE + +/* Define to 1 if you have the 'sigtimedwait' function. */ +#undef HAVE_SIGTIMEDWAIT + +/* Define to 1 if you have the 'sigwait' function. */ +#undef HAVE_SIGWAIT + +/* Define to 1 if you have the 'sigwaitinfo' function. */ +#undef HAVE_SIGWAITINFO + +/* Define to 1 if you have the 'sinpi' function. */ +#undef HAVE_SINPI + +/* Define to 1 if you have the 'snprintf' function. */ +#undef HAVE_SNPRINTF + +/* struct sockaddr_alg (linux/if_alg.h) */ +#undef HAVE_SOCKADDR_ALG + +/* Define if sockaddr has sa_len member */ +#undef HAVE_SOCKADDR_SA_LEN + +/* struct sockaddr_storage (sys/socket.h) */ +#undef HAVE_SOCKADDR_STORAGE + +/* Define if you have the 'socket' function. */ +#undef HAVE_SOCKET + +/* Define if you have the 'socketpair' function. */ +#undef HAVE_SOCKETPAIR + +/* Define to 1 if the system has the type 'socklen_t'. */ +#undef HAVE_SOCKLEN_T + +/* Define to 1 if you have the <spawn.h> header file. */ +#undef HAVE_SPAWN_H + +/* Define to 1 if you have the 'splice' function. */ +#undef HAVE_SPLICE + +/* Define to 1 if the system has the type 'ssize_t'. */ +#undef HAVE_SSIZE_T + +/* Define to 1 if you have the 'statvfs' function. */ +#undef HAVE_STATVFS + +/* Define to 1 if you have the 'statx' function. */ +#undef HAVE_STATX + +/* Define if you have struct stat.st_mtim.tv_nsec */ +#undef HAVE_STAT_TV_NSEC + +/* Define if you have struct stat.st_mtimensec */ +#undef HAVE_STAT_TV_NSEC2 + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdio.h> header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Has stdatomic.h with atomic_int and atomic_uintptr_t */ +#undef HAVE_STD_ATOMIC + +/* Define to 1 if you have the 'strftime' function. */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the 'strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the <stropts.h> header file. */ +#undef HAVE_STROPTS_H + +/* Define to 1 if you have the 'strsignal' function. */ +#undef HAVE_STRSIGNAL + +/* Define to 1 if 'pw_gecos' is a member of 'struct passwd'. */ +#undef HAVE_STRUCT_PASSWD_PW_GECOS + +/* Define to 1 if 'pw_passwd' is a member of 'struct passwd'. */ +#undef HAVE_STRUCT_PASSWD_PW_PASSWD + +/* Define to 1 if 'stx_atomic_write_unit_max_opt' is a member of 'struct + statx'. */ +#undef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT + +/* Define to 1 if 'stx_atomic_write_unit_min' is a member of 'struct statx'. + */ +#undef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN + +/* Define to 1 if 'stx_dio_mem_align' is a member of 'struct statx'. */ +#undef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN + +/* Define to 1 if 'stx_dio_read_offset_align' is a member of 'struct statx'. + */ +#undef HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN + +/* Define to 1 if 'stx_mnt_id' is a member of 'struct statx'. */ +#undef HAVE_STRUCT_STATX_STX_MNT_ID + +/* Define to 1 if 'stx_subvol' is a member of 'struct statx'. */ +#undef HAVE_STRUCT_STATX_STX_SUBVOL + +/* Define to 1 if 'st_birthtime' is a member of 'struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BIRTHTIME + +/* Define to 1 if 'st_blksize' is a member of 'struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BLKSIZE + +/* Define to 1 if 'st_blocks' is a member of 'struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BLOCKS + +/* Define to 1 if 'st_flags' is a member of 'struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_FLAGS + +/* Define to 1 if 'st_gen' is a member of 'struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_GEN + +/* Define to 1 if 'st_rdev' is a member of 'struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_RDEV + +/* Define to 1 if 'tm_zone' is a member of 'struct tm'. */ +#undef HAVE_STRUCT_TM_TM_ZONE + +/* Define if you have the 'symlink' function. */ +#undef HAVE_SYMLINK + +/* Define to 1 if you have the 'symlinkat' function. */ +#undef HAVE_SYMLINKAT + +/* Define to 1 if you have the 'sync' function. */ +#undef HAVE_SYNC + +/* Define to 1 if you have the 'sysconf' function. */ +#undef HAVE_SYSCONF + +/* Define to 1 if you have the 'sysctlbyname' function. */ +#undef HAVE_SYSCTLBYNAME + +/* Define to 1 if you have the <sysexits.h> header file. */ +#undef HAVE_SYSEXITS_H + +/* Define to 1 if you have the <syslog.h> header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the 'system' function. */ +#undef HAVE_SYSTEM + +/* Define to 1 if you have the <sys/audioio.h> header file. */ +#undef HAVE_SYS_AUDIOIO_H + +/* Define to 1 if you have the <sys/auxv.h> header file. */ +#undef HAVE_SYS_AUXV_H + +/* Define to 1 if you have the <sys/bsdtty.h> header file. */ +#undef HAVE_SYS_BSDTTY_H + +/* Define to 1 if you have the <sys/devpoll.h> header file. */ +#undef HAVE_SYS_DEVPOLL_H + +/* Define to 1 if you have the <sys/dir.h> header file, and it defines 'DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the <sys/endian.h> header file. */ +#undef HAVE_SYS_ENDIAN_H + +/* Define to 1 if you have the <sys/epoll.h> header file. */ +#undef HAVE_SYS_EPOLL_H + +/* Define to 1 if you have the <sys/eventfd.h> header file. */ +#undef HAVE_SYS_EVENTFD_H + +/* Define to 1 if you have the <sys/event.h> header file. */ +#undef HAVE_SYS_EVENT_H + +/* Define to 1 if you have the <sys/file.h> header file. */ +#undef HAVE_SYS_FILE_H + +/* Define to 1 if you have the <sys/ioctl.h> header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the <sys/kern_control.h> header file. */ +#undef HAVE_SYS_KERN_CONTROL_H + +/* Define to 1 if you have the <sys/loadavg.h> header file. */ +#undef HAVE_SYS_LOADAVG_H + +/* Define to 1 if you have the <sys/lock.h> header file. */ +#undef HAVE_SYS_LOCK_H + +/* Define to 1 if you have the <sys/memfd.h> header file. */ +#undef HAVE_SYS_MEMFD_H + +/* Define to 1 if you have the <sys/mkdev.h> header file. */ +#undef HAVE_SYS_MKDEV_H + +/* Define to 1 if you have the <sys/mman.h> header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the <sys/modem.h> header file. */ +#undef HAVE_SYS_MODEM_H + +/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the <sys/pidfd.h> header file. */ +#undef HAVE_SYS_PIDFD_H + +/* Define to 1 if you have the <sys/poll.h> header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the <sys/random.h> header file. */ +#undef HAVE_SYS_RANDOM_H + +/* Define to 1 if you have the <sys/resource.h> header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the <sys/select.h> header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the <sys/sendfile.h> header file. */ +#undef HAVE_SYS_SENDFILE_H + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the <sys/soundcard.h> header file. */ +#undef HAVE_SYS_SOUNDCARD_H + +/* Define to 1 if you have the <sys/statvfs.h> header file. */ +#undef HAVE_SYS_STATVFS_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/syscall.h> header file. */ +#undef HAVE_SYS_SYSCALL_H + +/* Define to 1 if you have the <sys/sysctl.h> header file. */ +#undef HAVE_SYS_SYSCTL_H + +/* Define to 1 if you have the <sys/sysmacros.h> header file. */ +#undef HAVE_SYS_SYSMACROS_H + +/* Define to 1 if you have the <sys/sys_domain.h> header file. */ +#undef HAVE_SYS_SYS_DOMAIN_H + +/* Define to 1 if you have the <sys/termio.h> header file. */ +#undef HAVE_SYS_TERMIO_H + +/* Define to 1 if you have the <sys/timerfd.h> header file. */ +#undef HAVE_SYS_TIMERFD_H + +/* Define to 1 if you have the <sys/times.h> header file. */ +#undef HAVE_SYS_TIMES_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/uio.h> header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the <sys/un.h> header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the <sys/utsname.h> header file. */ +#undef HAVE_SYS_UTSNAME_H + +/* Define to 1 if you have the <sys/wait.h> header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the <sys/xattr.h> header file. */ +#undef HAVE_SYS_XATTR_H + +/* Define to 1 if you have the 'tanpi' function. */ +#undef HAVE_TANPI + +/* Define to 1 if you have the 'tcgetpgrp' function. */ +#undef HAVE_TCGETPGRP + +/* Define to 1 if you have the 'tcsetpgrp' function. */ +#undef HAVE_TCSETPGRP + +/* Define to 1 if you have the 'tempnam' function. */ +#undef HAVE_TEMPNAM + +/* Define to 1 if you have the <termios.h> header file. */ +#undef HAVE_TERMIOS_H + +/* Define to 1 if you have the <term.h> header file. */ +#undef HAVE_TERM_H + +/* Define to 1 if you have the 'timegm' function. */ +#undef HAVE_TIMEGM + +/* Define if you have the 'timerfd_create' function. */ +#undef HAVE_TIMERFD_CREATE + +/* Define to 1 if you have the 'times' function. */ +#undef HAVE_TIMES + +/* Define to 1 if you have the 'tmpfile' function. */ +#undef HAVE_TMPFILE + +/* Define to 1 if you have the 'tmpnam' function. */ +#undef HAVE_TMPNAM + +/* Define to 1 if you have the 'tmpnam_r' function. */ +#undef HAVE_TMPNAM_R + +/* Define to 1 if your 'struct tm' has 'tm_zone'. Deprecated, use + 'HAVE_STRUCT_TM_TM_ZONE' instead. */ +#undef HAVE_TM_ZONE + +/* Define to 1 if you have the 'truncate' function. */ +#undef HAVE_TRUNCATE + +/* Define to 1 if you have the 'ttyname_r' function. */ +#undef HAVE_TTYNAME_R + +/* Define to 1 if you don't have 'tm_zone' but do have the external array + 'tzname'. */ +#undef HAVE_TZNAME + +/* Define to 1 if you have the 'umask' function. */ +#undef HAVE_UMASK + +/* Define to 1 if you have the 'uname' function. */ +#undef HAVE_UNAME + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the 'unlinkat' function. */ +#undef HAVE_UNLINKAT + +/* Define to 1 if you have the 'unlockpt' function. */ +#undef HAVE_UNLOCKPT + +/* Define to 1 if you have the 'unshare' function. */ +#undef HAVE_UNSHARE + +/* Define if you have a useable wchar_t type defined in wchar.h; useable means + wchar_t must be an unsigned type with at least 16 bits. (see + Include/unicodeobject.h). */ +#undef HAVE_USABLE_WCHAR_T + +/* Define to 1 if you have the <util.h> header file. */ +#undef HAVE_UTIL_H + +/* Define to 1 if you have the 'utimensat' function. */ +#undef HAVE_UTIMENSAT + +/* Define to 1 if you have the 'utimes' function. */ +#undef HAVE_UTIMES + +/* Define to 1 if you have the <utime.h> header file. */ +#undef HAVE_UTIME_H + +/* Define to 1 if you have the <utmp.h> header file. */ +#undef HAVE_UTMP_H + +/* Define if you have the 'HAVE_UT_NAMESIZE' constant. */ +#undef HAVE_UT_NAMESIZE + +/* Define to 1 if you have the 'uuid_create' function. */ +#undef HAVE_UUID_CREATE + +/* Define to 1 if you have the 'uuid_enc_be' function. */ +#undef HAVE_UUID_ENC_BE + +/* Define if uuid_generate_time_safe() exists. */ +#undef HAVE_UUID_GENERATE_TIME_SAFE + +/* Define if uuid_generate_time_safe() is able to deduce a MAC address. */ +#undef HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC + +/* Define to 1 if you have the <uuid.h> header file. */ +#undef HAVE_UUID_H + +/* Define to 1 if you have the <uuid/uuid.h> header file. */ +#undef HAVE_UUID_UUID_H + +/* Define to 1 if you have the 'vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the 'wait' function. */ +#undef HAVE_WAIT + +/* Define to 1 if you have the 'wait3' function. */ +#undef HAVE_WAIT3 + +/* Define to 1 if you have the 'wait4' function. */ +#undef HAVE_WAIT4 + +/* Define to 1 if you have the 'waitid' function. */ +#undef HAVE_WAITID + +/* Define to 1 if you have the 'waitpid' function. */ +#undef HAVE_WAITPID + +/* Define if the compiler provides a wchar.h header file. */ +#undef HAVE_WCHAR_H + +/* Define to 1 if you have the 'wcscoll' function. */ +#undef HAVE_WCSCOLL + +/* Define to 1 if you have the 'wcsftime' function. */ +#undef HAVE_WCSFTIME + +/* Define to 1 if you have the 'wcsxfrm' function. */ +#undef HAVE_WCSXFRM + +/* Define to 1 if you have the 'wmemcmp' function. */ +#undef HAVE_WMEMCMP + +/* Define if tzset() actually switches the local timezone in a meaningful way. + */ +#undef HAVE_WORKING_TZSET + +/* Define to 1 if you have the 'writev' function. */ +#undef HAVE_WRITEV + +/* Define to 1 if you have the <zdict.h> header file. */ +#undef HAVE_ZDICT_H + +/* Define if the zlib library has inflateCopy */ +#undef HAVE_ZLIB_COPY + +/* Define to 1 if you have the <zlib.h> header file. */ +#undef HAVE_ZLIB_H + +/* Define to 1 if you have the <zstd.h> header file. */ +#undef HAVE_ZSTD_H + +/* Define to 1 if you have the '_getpty' function. */ +#undef HAVE__GETPTY + +/* Define to 1 if the system has the type '__uint128_t'. */ +#undef HAVE___UINT128_T + +/* Define to 1 if 'major', 'minor', and 'makedev' are declared in <mkdev.h>. + */ +#undef MAJOR_IN_MKDEV + +/* Define to 1 if 'major', 'minor', and 'makedev' are declared in + <sysmacros.h>. */ +#undef MAJOR_IN_SYSMACROS + +/* Define if mvwdelch in curses.h is an expression. */ +#undef MVWDELCH_IS_EXPRESSION + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define if POSIX semaphores aren't enabled on your system */ +#undef POSIX_SEMAPHORES_NOT_ENABLED + +/* Define if pthread_key_t is compatible with int. */ +#undef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT + +/* Defined if PTHREAD_SCOPE_SYSTEM supported. */ +#undef PTHREAD_SYSTEM_SCHED_SUPPORTED + +/* Define as the preferred size in bits of long digits */ +#undef PYLONG_BITS_IN_DIGIT + +/* Define to use huge pages for pymalloc arenas */ +#undef PYMALLOC_USE_HUGEPAGES + +/* enabled builtin hash modules */ +#undef PY_BUILTIN_HASHLIB_HASHES + +/* Define if you want to coerce the C locale to a UTF-8 based locale */ +#undef PY_COERCE_C_LOCALE + +/* Define to 1 if you have the perf trampoline. */ +#undef PY_HAVE_PERF_TRAMPOLINE + +/* Define to 1 to build the sqlite module with loadable extensions support. */ +#undef PY_SQLITE_ENABLE_LOAD_EXTENSION + +/* Define if SQLite was compiled with the serialize API */ +#undef PY_SQLITE_HAVE_SERIALIZE + +/* Default cipher suites list for ssl module. 1: Python's preferred selection, + 2: leave OpenSSL defaults untouched, 0: custom string */ +#undef PY_SSL_DEFAULT_CIPHERS + +/* Cipher suite string for PY_SSL_DEFAULT_CIPHERS=0 */ +#undef PY_SSL_DEFAULT_CIPHER_STRING + +/* PEP 11 Support tier (1, 2, 3 or 0 for unsupported) */ +#undef PY_SUPPORT_TIER + +/* Define if you want to build an interpreter with many run-time checks. */ +#undef Py_DEBUG + +/* Defined if Python is built as a shared library. */ +#undef Py_ENABLE_SHARED + +/* Define if you want to disable the GIL */ +#undef Py_GIL_DISABLED + +/* Define hash algorithm for str, bytes and memoryview. SipHash24: 1, FNV: 2, + SipHash13: 3, externally defined: 0 */ +#undef Py_HASH_ALGORITHM + +/* Define if you want to enable remote debugging support. */ +#undef Py_REMOTE_DEBUG + +/* Define if rl_startup_hook takes arguments */ +#undef Py_RL_STARTUP_HOOK_TAKES_ARGS + +/* Define if you want to enable internal statistics gathering. */ +#undef Py_STATS + +/* The version of SunOS/Solaris as reported by `uname -r' without the dot. */ +#undef Py_SUNOS_VERSION + +/* Define if you want to enable tracing references for debugging purpose */ +#undef Py_TRACE_REFS + +/* assume C89 semantics that RETSIGTYPE is always void */ +#undef RETSIGTYPE + +/* Define if setpgrp() must be called as setpgrp(0, 0). */ +#undef SETPGRP_HAVE_ARG + +/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */ +#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS + +/* The size of 'double', as computed by sizeof. */ +#undef SIZEOF_DOUBLE + +/* The size of 'float', as computed by sizeof. */ +#undef SIZEOF_FLOAT + +/* The size of 'fpos_t', as computed by sizeof. */ +#undef SIZEOF_FPOS_T + +/* The size of 'int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of 'long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of 'long double', as computed by sizeof. */ +#undef SIZEOF_LONG_DOUBLE + +/* The size of 'long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* The size of 'off_t', as computed by sizeof. */ +#undef SIZEOF_OFF_T + +/* The size of 'pid_t', as computed by sizeof. */ +#undef SIZEOF_PID_T + +/* The size of 'pthread_key_t', as computed by sizeof. */ +#undef SIZEOF_PTHREAD_KEY_T + +/* The size of 'pthread_t', as computed by sizeof. */ +#undef SIZEOF_PTHREAD_T + +/* The size of 'short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of 'size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of 'time_t', as computed by sizeof. */ +#undef SIZEOF_TIME_T + +/* The size of 'uintptr_t', as computed by sizeof. */ +#undef SIZEOF_UINTPTR_T + +/* The size of 'void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* The size of 'wchar_t', as computed by sizeof. */ +#undef SIZEOF_WCHAR_T + +/* The size of '_Bool', as computed by sizeof. */ +#undef SIZEOF__BOOL + +/* Platform tag, used in binary module extension filenames. */ +#undef SOABI_PLATFORM + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both <sys/select.h> and <sys/time.h> + (which you can't on SCO ODT 3.0). */ +#undef SYS_SELECT_WITH_SYS_TIME + +/* Custom thread stack size depending on chosen sanitizer runtimes. */ +#undef THREAD_STACK_SIZE + +/* Library needed by timemodule.c: librt may be needed for clock_gettime() */ +#undef TIMEMODULE_LIB + +/* Define to 1 if your <sys/time.h> declares 'struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Define if you want to use computed gotos in ceval.c. */ +#undef USE_COMPUTED_GOTOS + +/* Enable extensions on AIX, Interix, z/OS. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Identify the host operating system as Minix. + This macro does not affect the system headers' behavior. + A future release of Autoconf may stop defining this macro. */ +#ifndef _MINIX +# undef _MINIX +#endif +/* Enable general extensions on NetBSD. + Enable NetBSD compatibility extensions on Minix. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD compatibility extensions on NetBSD. + Oddly enough, this does nothing on OpenBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Define to 1 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_SOURCE +# undef _POSIX_SOURCE +#endif +/* Define to 2 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_1_SOURCE +# undef _POSIX_1_SOURCE +#endif +/* Enable POSIX-compatible threading on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by C23 Annex F. */ +#ifndef __STDC_WANT_IEC_60559_EXT__ +# undef __STDC_WANT_IEC_60559_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable X/Open extensions. Define to 500 only if necessary + to make mbstate_t available. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif + + +/* Define if WINDOW in curses.h offers a field _flags. */ +#undef WINDOW_HAS_FLAGS + +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#undef WITH_DECIMAL_CONTEXTVAR + +/* Define if you want documentation strings in extension modules */ +#undef WITH_DOC_STRINGS + +/* Define if you want to compile in DTrace support */ +#undef WITH_DTRACE + +/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic + linker (dyld) instead of the old-style (NextStep) dynamic linker (rld). + Dyld is necessary to support frameworks. */ +#undef WITH_DYLD + +/* Define to build the readline module against libedit. */ +#undef WITH_EDITLINE + +/* Define to 1 if libintl is needed for locale functions. */ +#undef WITH_LIBINTL + +/* Define if you want to compile in mimalloc memory allocator. */ +#undef WITH_MIMALLOC + +/* Define if you want to produce an OpenStep/Rhapsody framework (shared + library plus accessory files). */ +#undef WITH_NEXT_FRAMEWORK + +/* Define if you want to compile in Python-specific mallocs */ +#undef WITH_PYMALLOC + +/* Define if you want pymalloc to be disabled when running under valgrind */ +#undef WITH_VALGRIND + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define if arithmetic is subject to x87-style double rounding issue */ +#undef X87_DOUBLE_ROUNDING + +/* Define on OpenBSD to activate all library features */ +#undef _BSD_SOURCE + +/* Define on Darwin to activate all library features */ +#undef _DARWIN_C_SOURCE + +/* This must be set to 64 on some systems to enable large file support. */ +#undef _FILE_OFFSET_BITS + +/* Define to include mbstate_t for mbrtowc */ +#undef _INCLUDE__STDC_A1_SOURCE + +/* Define to activate ISO C23 library declarations */ +#undef _ISOC23_SOURCE + +/* This must be defined on some systems to enable large file support. */ +#undef _LARGEFILE_SOURCE + +/* This must be defined on AIX systems to enable large file support. */ +#undef _LARGE_FILES + +/* Define on NetBSD to activate all library features */ +#undef _NETBSD_SOURCE + +/* Define to activate features from IEEE Std 1003.1-2024 */ +#undef _POSIX_C_SOURCE + +/* Define if you have POSIX threads, and your system does not define that. */ +#undef _POSIX_THREADS + +/* framework name */ +#undef _PYTHONFRAMEWORK + +/* Maximum length in bytes of a thread name */ +#undef _PYTHREAD_NAME_MAXLEN + +/* Defined if _Complex C type can be used with libffi. */ +#undef _Py_FFI_SUPPORT_C_COMPLEX + +/* HACL* library can compile SIMD128 implementations */ +#undef _Py_HACL_CAN_COMPILE_VEC128 + +/* HACL* library can compile SIMD256 implementations */ +#undef _Py_HACL_CAN_COMPILE_VEC256 + +/* Define if compiler supports __builtin_shufflevector with 128-bit vectors + AND the target architecture has native SIMD (not just API availability) */ +#undef _Py_HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR + +/* Define to 1 if libgcc __register_frame and __deregister_frame are linkable. + */ +#undef _Py_HAVE_LIBGCC_EH_FRAME_REGISTRATION + +/* Define if you have the 'PR_SET_VMA_ANON_NAME' constant. */ +#undef _Py_HAVE_PR_SET_VMA_ANON_NAME + +/* Thread stack size set by the linker (in bytes). */ +#undef _Py_LINKER_THREAD_STACK_SIZE + +/* Define to 1 if the machine stack grows down (default); 0 if it grows up. */ +#undef _Py_STACK_GROWS_DOWN + +/* Define if you want to use tail-calling interpreters in CPython. */ +#undef _Py_TAIL_CALL_INTERP + +/* Define to 1 if frame unwinding via pointers is expected to work, 0 if not. + Leave undefined if unknown. */ +#undef _Py_WITH_FRAME_POINTERS + +/* Define to force use of thread-safe errno, h_errno, and other functions */ +#undef _REENTRANT + +/* Define to 1 if you want to emulate getpid() on WASI */ +#undef _WASI_EMULATED_GETPID + +/* Define to 1 if you want to emulate process clocks on WASI */ +#undef _WASI_EMULATED_PROCESS_CLOCKS + +/* Define to 1 if you want to emulate signals on WASI */ +#undef _WASI_EMULATED_SIGNAL + +/* Define to the level of X/Open that your system supports */ +#undef _XOPEN_SOURCE + +/* Define to activate Unix95-and-earlier features */ +#undef _XOPEN_SOURCE_EXTENDED + +/* Define on FreeBSD to activate all library features */ +#undef __BSD_VISIBLE + +/* Define to 'long' if <time.h> does not define clock_t. */ +#undef clock_t + +/* Define to empty if 'const' does not conform to ANSI C. */ +#undef const + +/* Define as 'int' if <sys/types.h> doesn't define. */ +#undef gid_t + +/* Define to 'int' if <sys/types.h> does not define. */ +#undef mode_t + +/* Define to 'long int' if <sys/types.h> does not define. */ +#undef off_t + +/* Define as a signed integer type capable of holding a process identifier. */ +#undef pid_t + +/* Define to empty if the keyword does not work. */ +#undef signed + +/* Define as 'unsigned int' if <stddef.h> doesn't define. */ +#undef size_t + +/* Define to 'int' if <sys/socket.h> does not define. */ +#undef socklen_t + +/* Define as 'int' if <sys/types.h> doesn't define. */ +#undef uid_t + + +/* Define the macros needed if on a UnixWare 7.x system. */ +#if defined(__USLC__) && defined(__SCO_VERSION__) +#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ +#endif + +#endif /*Py_PYCONFIG_H*/ + diff --git a/stdlib/kvlang/reference/rust/reference-repo/.cargo/config.toml b/stdlib/kvlang/reference/rust/reference-repo/.cargo/config.toml new file mode 100644 index 00000000..35049cbc --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run --package xtask --" diff --git a/stdlib/kvlang/reference/rust/reference-repo/.gitattributes b/stdlib/kvlang/reference/rust/reference-repo/.gitattributes new file mode 100644 index 00000000..d56abbf3 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/.gitattributes @@ -0,0 +1,2 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto eol=lf diff --git a/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/daily-grammar-check.yml b/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/daily-grammar-check.yml new file mode 100644 index 00000000..8b90c2e5 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/daily-grammar-check.yml @@ -0,0 +1,72 @@ +name: Daily Grammar Check +on: + schedule: + # Run at 4am UTC every day + - cron: '0 4 * * *' + workflow_dispatch: + +jobs: + grammar-check: + if: github.repository == 'rust-lang/reference' + runs-on: ubuntu-latest + steps: + - name: Checkout reference repository + uses: actions/checkout@v7 + + - name: Checkout rust-lang/rust (shallow clone) + uses: actions/checkout@v7 + with: + repository: rust-lang/rust + path: rust + fetch-depth: 1 + + - name: Update rustup + run: rustup self update + + - name: Install Rust nightly + run: | + rustup set profile minimal + rustup toolchain install nightly -c rustc-dev -c llvm-tools + rustup default nightly + + - name: Report versions + run: | + rustup --version + rustc -Vv + + - name: Run grammar check + id: grammar-check + continue-on-error: true + run: | + cargo run --release -p grammar-check -- lex-compare --path rust + cargo run --release -p grammar-check -- lex-compare --permute Token --tool rustc_parse + cargo run --release -p grammar-check -- lex-compare --permute three + cargo run --release -p grammar-check -- lex-compare --tool rustc_parse + + - name: Check for existing open issues + if: steps.grammar-check.outcome == 'failure' + id: check-issues + env: + GH_TOKEN: ${{ github.token }} + run: | + # Check if there's already an open issue with the label 'daily-grammar-check' + ISSUE_COUNT=$(gh issue list --label "daily-grammar-check" --state open --json number --jq 'length') + echo "open_issues=$ISSUE_COUNT" >> $GITHUB_OUTPUT + + - name: Create issue on failure + if: steps.grammar-check.outcome == 'failure' && steps.check-issues.outputs.open_issues == '0' + env: + GH_TOKEN: ${{ github.token }} + run: | + gh issue create \ + --title "Daily Grammar Check Failed - $(date +%Y-%m-%d)" \ + --label "daily-grammar-check" \ + --body "The daily grammar check failed on $(date +%Y-%m-%d). + + **Workflow Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + **Command:** \`cargo run --release -p grammar-check -- lex-compare --path rust/tests\` + + Please investigate the failure and update the reference as needed. + + This issue was automatically created by the daily grammar check workflow." diff --git a/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/dev-guide.yml b/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/dev-guide.yml new file mode 100644 index 00000000..9a7858d0 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/dev-guide.yml @@ -0,0 +1,49 @@ +name: Deploy dev-guide +on: + push: + branches: + - master + +env: + MDBOOK_VERSION: 0.5.2 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Install mdbook + run: | + mkdir mdbook + curl -Lf https://github.com/rust-lang/mdBook/releases/download/v${{ env.MDBOOK_VERSION }}/mdbook-v${{ env.MDBOOK_VERSION }}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook + echo `pwd`/mdbook >> $GITHUB_PATH + + - name: Build the book + run: | + cd dev-guide + mdbook build + mkdir out + touch out/.nojekyll + mv book out/dev-guide + + - name: Upload Artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./dev-guide/out + + deploy: + needs: build + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/main.yml b/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/main.yml new file mode 100644 index 00000000..bed033f0 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/.github/workflows/main.yml @@ -0,0 +1,191 @@ +name: CI +on: + pull_request: + merge_group: + +env: + MDBOOK_VERSION: 0.5.2 + +permissions: + contents: read + +jobs: + code-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Update rustup + run: rustup self update + - name: Install Rust + run: | + rustup set profile minimal + rustup toolchain install nightly + rustup default nightly + - name: Install mdbook + run: | + mkdir bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + echo "$(pwd)/bin" >> $GITHUB_PATH + - name: Report versions + run: | + rustup --version + rustc -Vv + mdbook --version + - name: Run tests + run: mdbook test + + style-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Checkout rust-lang/rust + uses: actions/checkout@master + with: + repository: rust-lang/rust + path: rust + - name: Update rustup + run: rustup self update + - name: Install Rust + run: | + rustup set profile minimal + rustup toolchain install nightly -c rust-docs,rustfmt + rustup default nightly + - name: Install mdbook + run: | + mkdir bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + echo "$(pwd)/bin" >> $GITHUB_PATH + - name: Report versions + run: | + rustup --version + rustc -Vv + mdbook --version + - name: Style checks + run: cargo xtask style-check + - name: Rustfmt check + run: cargo fmt --check + - name: Verify the book builds + env: + SPEC_DENY_WARNINGS: 1 + SPEC_RUST_ROOT: ${{ github.workspace }}/rust + run: mdbook build + - name: Check for broken links + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -sSLo linkcheck.sh \ + https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh + sh linkcheck.sh --all reference + + mdbook-spec: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Update rustup + run: rustup self update + - name: Install Rust + run: | + rustup set profile minimal + rustup toolchain install nightly -c rustfmt + rustup default nightly + - name: Install mdbook + run: | + mkdir bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + echo "$(pwd)/bin" >> $GITHUB_PATH + - name: Report versions + run: | + rustup --version + rustc -Vv + + tools: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Update rustup + run: rustup self update + - name: Install Rust nightly + run: | + rustup set profile minimal + rustup toolchain install nightly -c rustc-dev -c llvm-tools + rustup default nightly + - name: Report versions + run: | + rustup --version + rustc -Vv + - name: Verify tools workspace lockfile is current + run: cargo update -p mdbook-spec --locked + - name: Test tools + run: cargo test + + dev-guide: + name: dev-guide build check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Install mdbook + env: + MDBOOK_VERSION: 0.5.1 + run: | + mkdir bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + echo "$(pwd)/bin" >> $GITHUB_PATH + - name: Check dev-guide build + run: | + cd dev-guide + mdbook build + + preview: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Checkout rust-lang/rust + uses: actions/checkout@master + with: + repository: rust-lang/rust + path: rust + - name: Update rustup + run: rustup self update + - name: Install Rust + run: | + rustup set profile minimal + rustup toolchain install nightly + rustup default nightly + - name: Install mdbook + run: | + mkdir bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + echo "$(pwd)/bin" >> $GITHUB_PATH + - name: Build the book + env: + SPEC_RELATIVE: 0 + SPEC_RUST_ROOT: ${{ github.workspace }}/rust + run: mdbook build --dest-dir dist/preview-${{ github.event.pull_request.number }} + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: preview-${{ github.event.pull_request.number }} + overwrite: true + path: dist + + # The success job is here to consolidate the total success/failure state of + # all other jobs. This job is then included in the GitHub branch protection + # rule which prevents merges unless all other jobs are passing. This makes + # it easier to manage the list of jobs via this yml file and to prevent + # accidentally adding new jobs without also updating the branch protections. + success: + name: Success gate + if: always() + needs: + - code-tests + - style-tests + - mdbook-spec + - tools + - dev-guide + # preview is explicitly excluded here since it doesn't run on merge + runs-on: ubuntu-latest + steps: + - run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' + - name: Done + run: exit 0 diff --git a/stdlib/kvlang/reference/rust/reference-repo/.gitignore b/stdlib/kvlang/reference/rust/reference-repo/.gitignore new file mode 100644 index 00000000..cf38f923 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/.gitignore @@ -0,0 +1,4 @@ +/book +/dev-guide/book +/target +/linkcheck.sh diff --git a/stdlib/kvlang/reference/rust/reference-repo/CONTRIBUTING.md b/stdlib/kvlang/reference/rust/reference-repo/CONTRIBUTING.md new file mode 100644 index 00000000..5d69b95b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing to The Rust Reference + +See the [Reference Developer Guide](https://rust-lang.github.io/reference/dev-guide/) for information on contributing to the Reference. diff --git a/stdlib/kvlang/reference/rust/reference-repo/Cargo.lock b/stdlib/kvlang/reference/rust/reference-repo/Cargo.lock new file mode 100644 index 00000000..47e2054d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/Cargo.lock @@ -0,0 +1,1017 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "clap" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "console" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" +dependencies = [ + "encode_unicode", + "libc", + "unicode-width", + "windows-sys", +] + +[[package]] +name = "ctrlc" +version = "3.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" +dependencies = [ + "dispatch2", + "nix", + "windows-sys", +] + +[[package]] +name = "diagnostics" +version = "0.0.0" + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getopts" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + +[[package]] +name = "grammar" +version = "0.0.0" +dependencies = [ + "diagnostics", + "pathdiff", + "regex", + "walkdir", +] + +[[package]] +name = "grammar-check" +version = "0.0.0" +dependencies = [ + "clap", + "ctrlc", + "diagnostics", + "grammar", + "indicatif", + "parser", + "proc-macro2", + "regex", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", + "tracing-tree", + "unicode-ident", + "walkdir", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.18.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" +dependencies = [ + "console", + "portable-atomic", + "unicode-width", + "unit-prefix", + "web-time", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "mdbook-core" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8725b7f8e94a5c40a00c907e4006301ba2fc06722de489a0cb19db1823fdf200" +dependencies = [ + "anyhow", + "regex", + "serde", + "serde_json", + "toml", + "tracing", +] + +[[package]] +name = "mdbook-markdown" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca553aa4330b15fa2c706aef373bc714cc719513d1da73c17be3dba208b9aab" +dependencies = [ + "pulldown-cmark 0.13.4", + "regex", + "tracing", +] + +[[package]] +name = "mdbook-preprocessor" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8e75b08763e31982701d5b2680124bd4bd9bed4a4e1b5a499381320ccae199f" +dependencies = [ + "anyhow", + "mdbook-core", + "serde", + "serde_json", +] + +[[package]] +name = "mdbook-spec" +version = "0.0.0" +dependencies = [ + "anyhow", + "diagnostics", + "grammar", + "mdbook-markdown", + "mdbook-preprocessor", + "once_cell", + "pathdiff", + "railroad", + "regex", + "semver", + "serde_json", + "tempfile", + "walkdir", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "parser" +version = "0.0.0" +dependencies = [ + "diagnostics", + "grammar", + "tracing", + "tracing-subscriber", + "tracing-tree", + "unicode-ident", +] + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pulldown-cmark" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" +dependencies = [ + "bitflags", + "getopts", + "memchr", + "pulldown-cmark-escape 0.10.1", + "unicase", +] + +[[package]] +name = "pulldown-cmark" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" +dependencies = [ + "bitflags", + "memchr", + "pulldown-cmark-escape 0.11.0", + "unicase", +] + +[[package]] +name = "pulldown-cmark-escape" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" + +[[package]] +name = "pulldown-cmark-escape" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "railroad" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7286d8b4d9fc00078819e06ff24cefa276f39461ff53b74d63d24736be27192f" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "style-check" +version = "0.0.0" +dependencies = [ + "pulldown-cmark 0.10.3", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "toml" +version = "1.1.4+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-tree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac87aa03b6a4d5a7e4810d1a80c19601dbe0f8a837e9177f23af721c7ba7beec" +dependencies = [ + "nu-ansi-term", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unit-prefix" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" + +[[package]] +name = "xtask" +version = "0.0.0" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/stdlib/kvlang/reference/rust/reference-repo/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/Cargo.toml new file mode 100644 index 00000000..6525dffe --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/Cargo.toml @@ -0,0 +1,8 @@ +[workspace] +members = [ + "tools/*", +] +exclude = [ + "linkchecker" +] +resolver = "2" diff --git a/stdlib/kvlang/reference/rust/reference-repo/LICENSE-APACHE b/stdlib/kvlang/reference/rust/reference-repo/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/stdlib/kvlang/reference/rust/reference-repo/LICENSE-MIT b/stdlib/kvlang/reference/rust/reference-repo/LICENSE-MIT new file mode 100644 index 00000000..25597d58 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2010 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/stdlib/kvlang/reference/rust/reference-repo/README.md b/stdlib/kvlang/reference/rust/reference-repo/README.md new file mode 100644 index 00000000..f961f610 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/README.md @@ -0,0 +1,7 @@ +# The Rust Language Reference + +This document is the primary reference for the Rust programming language. + +## Contributor docs + +See the [Reference Developer Guide](https://rust-lang.github.io/reference/dev-guide/) for information on contributing to the Reference. diff --git a/stdlib/kvlang/reference/rust/reference-repo/book.toml b/stdlib/kvlang/reference/rust/reference-repo/book.toml new file mode 100644 index 00000000..b792c714 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/book.toml @@ -0,0 +1,104 @@ +[book] + +title = "The Rust Reference" +authors = ["The Rust Project Developers"] + +[output.html] +additional-css = ["theme/reference.css"] +additional-js = ["theme/reference.js"] +git-repository-url = "https://github.com/rust-lang/reference/" +edit-url-template = "https://github.com/rust-lang/reference/edit/master/{path}" +smart-punctuation = true + +[output.html.fold] +enable = true +level = 0 + +[output.html.search] +use-boolean-and = true + +[output.html.search.chapter] +"grammar.md" = { enable = false } +"syntax-index.md" = { enable = false } +"test-summary.md" = { enable = false } + +[output.html.redirect] +"/attributes.html#cold-attribute" = "attributes/codegen.html#the-cold-attribute" +"/attributes.html#conditional-compilation" = "conditional-compilation.html" +"/attributes.html#crate-only-attributes" = "attributes.html#built-in-attributes-index" +"/attributes.html#deprecation" = "attributes/diagnostics.html#the-deprecated-attribute" +"/attributes.html#derive" = "attributes/derive.html" +"/attributes.html#documentation" = "../rustdoc/the-doc-attribute.html" +"/attributes.html#ffi-attributes" = "attributes.html#built-in-attributes-index" +"/attributes.html#inline-attribute" = "attributes/codegen.html#the-inline-attribute" +"/attributes.html#lint-check-attributes" = "attributes/diagnostics.html#lint-check-attributes" +"/attributes.html#macro-related-attributes" = "attributes.html#built-in-attributes-index" +"/attributes.html#miscellaneous-attributes" = "attributes.html#built-in-attributes-index" +"/attributes.html#must_use" = "attributes/diagnostics.html#the-must_use-attribute" +"/attributes.html#optimization-hints" = "attributes/codegen.html#optimization-hints" +"/attributes.html#path" = "items/modules.html#the-path-attribute" +"/attributes.html#preludes" = "crates-and-source-files.html#preludes-and-no_std" +"/attributes.html#testing" = "attributes/testing.html" +"/attributes.html#tool-lint-attributes" = "attributes/diagnostics.html#tool-lint-attributes" +"/crates-and-source-files.html#preludes-and-no_std" = "names/preludes.html" +"/expressions/block-expr.html#labelled-block-expressions" = "block-expr.html#labeled-block-expressions" +"/expressions/enum-variant-expr.html" = "struct-expr.html" +"/expressions/if-expr.html#if-let-expressions" = "if-expr.html#if-let-patterns" +"/expressions/loop-expr.html#labelled-block-expressions" = "loop-expr.html#labeled-block-expressions" +"/expressions/loop-expr.html#predicate-pattern-loops" = "loop-expr.html#while-let-patterns" +"/expressions/operator-expr.html#slice-dst-pointer-to-pointer-cast" = "operator-expr.html#pointer-to-pointer-cast" +"/expressions/operator-expr.html#the-question-mark-operator" = "operator-expr.html#the-try-propagation-expression" +"/glossary.html#object-safe-traits" = "glossary.html#dyn-compatible-traits" +"/items/extern-crates.html#extern-prelude" = "../names/preludes.html#extern-prelude" +"/items/modules.html#prelude-items" = "../names/preludes.html" +"/items/traits.html#object-safety" = "traits.html#dyn-compatibility" +"/lifetime-elision.html#static-lifetime-elision" = "lifetime-elision.html#const-and-static-elision" +"/macros-by-example.html#path-based-scope" = "macros-by-example.html#the-macro_export-attribute" +"/patterns.html#rest-patterns" = "patterns.html#rest-pattern" +"/procedural-macros.html#attribute-macros" = "procedural-macros.html#the-proc_macro_attribute-attribute" +"/procedural-macros.html#derive-macros" = "procedural-macros.html#the-proc_macro_derive-attribute" +"/procedural-macros.html#function-like-procedural-macros" = "procedural-macros.html#the-proc_macro-attribute" +"/runtime.html#the-panic_handler-attribute" = "panic.html#the-panic_handler-attribute" +"/types.html#abstract-return-types" = "types/impl-trait.html#abstract-return-types" +"/types.html#anonymous-type-parameters" = "types/impl-trait.html#anonymous-type-parameters" +"/types.html#array-and-slice-types" = "types/array.html" +"/types.html#boolean-type" = "types/boolean.html" +"/types.html#call-traits-and-coercions" = "types/closure.html#call-traits-and-coercions" +"/types.html#capture-modes" = "types/closure.html#capture-modes" +"/types.html#closure-types" = "types/closure.html" +"/types.html#enumerated-types" = "types/enum.html" +"/types.html#function-item-types" = "types/function-item.html" +"/types.html#function-pointer-types" = "types/function-pointer.html" +"/types.html#impl-trait" = "types/impl-trait.html" +"/types.html#inferred-type" = "types/inferred.html" +"/types.html#machine-dependent-integer-types" = "types/numeric.html#machine-dependent-integer-types" +"/types.html#machine-types" = "types/numeric.html" +"/types.html#mutable-references-" = "types/pointer.html#mutable-references-mut" +"/types.html#never-type" = "types/never.html" +"/types.html#numeric-types" = "types/numeric.html" +"/types.html#other-traits" = "types/closure.html#other-traits" +"/types.html#pointer-types" = "types/pointer.html" +"/types.html#raw-pointers-const-and-mut" = "types/pointer.html#raw-pointers-const-and-mut" +"/types.html#self-types" = "paths.html#self-1" +"/types.html#shared-references-" = "types/pointer.html#shared-references-" +"/types.html#smart-pointers" = "types/pointer.html#smart-pointers" +"/types.html#struct-types" = "types/struct.html" +"/types.html#textual-types" = "types/char.html" +"/types.html#trait-object-lifetime-bounds" = "types/trait-object.html#trait-object-lifetime-bounds" +"/types.html#trait-objects" = "types/trait-object.html" +"/types.html#tuple-types" = "types/tuple.html" +"/types.html#type-parameters" = "types/parameters.html" +"/types.html#union-types" = "types/union.html" +"/types.html#unique-immutable-borrows-in-captures" = "types/closure.html#unique-immutable-borrows-in-captures" +"/types/textual.html" = "char.html" +"/unsafe-blocks.html" = "unsafe-keyword.html" +"/unsafe-functions.html" = "unsafe-keyword.html" + +[rust] +edition = "2024" + +[preprocessor.spec] +command = "cargo run --release --manifest-path tools/mdbook-spec/Cargo.toml" + +[build] +extra-watch-dirs = ["tools/mdbook-spec/src", "tools/grammar/src"] diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/README.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/README.md new file mode 100644 index 00000000..3375b8d3 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/README.md @@ -0,0 +1,7 @@ +# The Rust Reference Developer Guide + +This is the source of the Reference Developer Guide, published at <https://rust-lang.github.io/reference/dev-guide/>. It is written in Markdown using [mdbook]. If you are editing these pages, the best way to view them is to run `mdbook serve --open`. This will start a web server on localhost that you can visit to view the book; it will automatically reload each time you edit a page. + +This is published via GitHub Actions to GitHub Pages. + +[mdbook]: https://rust-lang.github.io/mdBook/ diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/book.toml b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/book.toml new file mode 100644 index 00000000..5c820558 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/book.toml @@ -0,0 +1,11 @@ +[book] +title = "The Rust Reference Developer Guide" +language = "en" + +[output.html] +git-repository-url = "https://github.com/rust-lang/reference/tree/master/dev-guide" +edit-url-template = "https://github.com/rust-lang/reference/edit/master/dev-guide/{path}" +smart-punctuation = true + +[output.html.search] +use-boolean-and = true diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/SUMMARY.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/SUMMARY.md new file mode 100644 index 00000000..ad16fc0e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/SUMMARY.md @@ -0,0 +1,22 @@ +# Summary + +- [Introduction](introduction.md) +- [Contribution process](process/index.md) + - [Stabilization process](process/stabilization.md) +- [Publishing process](publishing.md) +- [Reference tooling](tooling/index.md) + - [Building the Reference](tooling/building.md) + - [mdbook-spec](tooling/mdbook-spec.md) +- [Tests](tests.md) +- [Formatting](formatting/index.md) + - [Markdown](formatting/markdown.md) + - [Admonitions](formatting/admonitions.md) +- [Language rules](rules/index.md) + - [rustc test annotations](rules/test-annotations.md) +- [Examples](examples.md) +- [Links](links.md) +- [Rust grammar](grammar.md) +- [Attributes](attributes.md) +- [Style guide](style.md) +- [Review policy](review-policy.md) +- [Resources](resources.md) diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/attributes.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/attributes.md new file mode 100644 index 00000000..2b6d0822 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/attributes.md @@ -0,0 +1,190 @@ +# Attributes + +Attributes should use the following template. Examples are given for phrasing you *should* use, but you should deviate if the attribute doesn't fit any of the examples or if the examples get in the way of clarity. + +When an attribute (or a new attribute position in the grammar) is added, be sure to update all the "attributes on" sections that list which attributes can be used in various positions. + +---- + +<!-- template:attributes --> +r[PARENT.example] +## The `example` attribute + +r[PARENT.example.intro] +The *`example` [attribute][attributes]* ...give a high-level description. + +> [!EXAMPLE] +> ```rust +> // This should be a very basic example showing the attribute +> // used in some way. +> #[example] +> fn some_meaningful_name() {} +> ``` + +r[PARENT.example.syntax] +Describe the accepted syntax of this attribute. You can either explain that it uses one of the pre-existing grammars, such as `MetaWord`, or define an explicit grammar. If there are different forms, briefly describe the syntax here and link to the appropriate rules below that explain the behavior of the different forms. Examples: + +---- + +The `example` attribute uses the [MetaWord] syntax. + +---- + +The `example` attribute uses the [MetaListPaths] syntax to specify a list of ... + +---- + +The `example` attribute uses the [MetaWord] and [MetaNameValueStr] syntaxes. + +---- + +The `example` attribute uses the [MetaWord], [MetaListPaths], and [MetaNameValueStr] syntaxes. + +---- + +The `example` attribute uses the [MetaNameValueStr] syntax. Accepted values are `"X"` and `"Y"`. + +---- + +The `example` attribute uses the [MetaNameValueStr] syntax. The value in the string must be ... + +---- + +The `example` attribute has these forms: + +- [MetaWord] + > [!EXAMPLE] + > ```rust + > #[example] + > fn f() {} + > ``` + +- [MetaNameValueStr] --- The given string must ... + > [!EXAMPLE] + > ```rust + > #[example = "example"] + > fn f() {} + > ``` + +- [MetaListNameValueStr] --- As with the [MetaNameValueStr] syntax, the given string must ... + > [!EXAMPLE] + > ```rust + > #[example(inner = "example")] + > fn f() {} + > ``` + +---- + +The syntax for the `example` attribute is: + +```grammar,attributes +@root ExampleAttribute -> `example` `(` ... `)` +``` +---- + +r[PARENT.example.syntax.foo] +The [MetaNameValueStr] form of the `example` attribute provides a way to specify the foo. + +> [!EXAMPLE] +> ```rust +> #[example = "example"] +> fn some_meaningful_name() {} +> ``` + +r[PARENT.example.allowed-positions] +Explain the valid positions where this attribute can be used. + +See [`check_attr`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_passes/src/check_attr.rs) and [`builtin_attrs.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_feature/src/builtin_attrs.rs) in the compiler. Don't forget that some attributes only work as inner or outer attributes. Examples: + +---- + +The `example` attribute may only be applied to ... + +---- + +The `example` attribute may only be applied to the crate root. + +---- + +The `example` attribute may be used anywhere attributes are allowed. + +---- + +If there are unused attribute warnings, or if `rustc` is incorrectly accepting some positions, include a note about these. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +---- + +r[PARENT.example.duplicates] +Explain the behavior when the attribute is used multiple times on an element. See [`AttributeDuplicates`](https://github.com/rust-lang/rust/blob/40d2563ea200f9327a8cb8b99a0fb82f75a7365c/compiler/rustc_feature/src/builtin_attrs.rs#L143) in the compiler. Examples: + +---- + +The `example` attribute may be used any number of times on a form. + +---- + +Using `example` more than once on a form has the same effect as using it once. + +---- + +The `example` attribute may be used only once on ... + +---- + +Only the first use of `example` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +> [!NOTE] +> `rustc` lints against any use following the first with a future-compatibility warning. This may become an error in the future. + +---- + +Only the last use of `example` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use preceding the last. This may become an error in the future. + +---- + +Only the last use of `example` on an item is used to ... + +---- + +If the `example` attribute is used more than once on an item, then the combination of all listed values is used as ...explain how they are merged. + +---- + +r[PARENT.example.ATTR_NAME] +If this attribute cannot be used with another attribute, specify each conflicting attribute. Do this for both attributes. Example: + +---- + +The `example` attribute may not be used with the [`foo`] attribute. + +---- + +r[PARENT.example.unsafe] +If this is an `unsafe` attribute, explain the safety conditions it must uphold. Otherwise, do not include this section. Be sure to also update `attributes.safety` when adding a new unsafe attribute. Example: + +---- + +The `example` attribute must be marked with [`unsafe`][attributes.safety] because ... + +---- + +r[PARENT.example.stdlib] +This rule explains whether the attribute is exported in the standard library. Skip this section if it is not. Example: + +---- + +The `example` attribute is exported in the standard library prelude as [`core::prelude::v1::example`]. + +---- + +r[PARENT.example.foo] +From here on, add rules explaining all the behaviors of the attribute. If the attribute is very simple, you can just have one rule called `.behavior` to explain its behavior. More complex attributes, such as those with multiple kinds of inputs or different modes, should describe each as a separate rule. diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/examples.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/examples.md new file mode 100644 index 00000000..4dd6888f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/examples.md @@ -0,0 +1,37 @@ +# Examples + +## Example code blocks + +Code examples should use code blocks with triple backticks. The language should always be specified (such as `rust`). + +```rust +println!("Hello!"); +``` + +See the [mdBook supported languages] for a list of supported languages. + +## rustdoc attributes + +Rust examples are [tested via rustdoc] and should include the appropriate annotations: + +- `edition2015`, `edition2018`, etc. --- Use if it is edition-specific (see `book.toml` for the default). +- `no_run` --- The example should compile successfully but should not be executed. +- `should_panic` --- The example should compile and run but produce a panic. +- `compile_fail` --- The example is expected to fail to compile. +- `ignore` --- The example shouldn't be built or tested. This should be avoided if possible. Usually, this is only necessary when the testing framework does not support it (such as external crates, modules, or a proc-macro) or when it contains pseudocode that is not valid Rust. An HTML comment, such as `<!-- ignore: requires extern crate -->`, should be placed before the example to explain why it is ignored. +- `Exxxx` --- If the example is expected to fail to compile with a specific error code, include that code so that `rustdoc` checks that the expected code is used. + +See the [rustdoc documentation] for more detail. + +## Combining examples + +When demonstrating success cases, multiple cases may be included in a single code block. For failure cases, however, each example must appear in a separate code block so that the tests can ensure that each case indeed fails with the appropriate error code. + +## Testing examples + +The Rust code blocks are tested in CI. You can verify that the samples pass by running [`cargo xtask mdbook-test`]. + +[`cargo xtask mdbook-test`]: tests.md#inline-tests +[mdBook supported languages]: https://rust-lang.github.io/mdBook/format/theme/syntax-highlighting.html#supported-languages +[rustdoc documentation]: https://doc.rust-lang.org/rustdoc/documentation-tests.html +[tested via rustdoc]: tests.md#inline-tests diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/admonitions.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/admonitions.md new file mode 100644 index 00000000..84043688 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/admonitions.md @@ -0,0 +1,23 @@ +# Admonitions + +[`mdbook-spec`](../tooling/mdbook-spec.md) provides admonitions that use a style similar to GitHub-flavored Markdown. The style name is placed at the beginning of a blockquote, such as: + +```markdown +> [!WARNING] +> This is a warning. + +> [!NOTE] +> This is a note. + +> [!EDITION-2024] +> This is an edition-specific difference. + +> [!EXAMPLE] +> This is an example. +``` + +The color and styling are defined in [`theme/reference.css`](https://github.com/rust-lang/reference/blob/HEAD/theme/reference.css) and the transformation and icons are in [`tools/mdbook-spec/src/admonitions.rs`](https://github.com/rust-lang/reference/blob/HEAD/tools/mdbook-spec/src/admonitions.rs). + +See **[Conventions]** in the Reference introduction for a description of how these should be used. + +[Conventions]: https://doc.rust-lang.org/nightly/reference/#conventions diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/index.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/index.md new file mode 100644 index 00000000..58b739bf --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/index.md @@ -0,0 +1,3 @@ +# Formatting + +The following chapters detail how the Reference source should be formatted. diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/markdown.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/markdown.md new file mode 100644 index 00000000..83c41120 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/formatting/markdown.md @@ -0,0 +1,45 @@ +# Markdown + +There are automated checks for some of these rules. Run [`cargo xtask style-check`] to run them locally. + +## Formatting style + +- Use [ATX-style headings][atx] (not Setext) with [sentence case]. +- Do not use tabs; use only spaces. +- Files must end with a newline. +- Lines must not end with spaces. Double spaces have semantic meaning but can be invisible. Use a trailing backslash if you need a hard line break. +- If possible, avoid double blank lines. +- Do not wrap long lines. This helps with reviewing diffs of the source. +- Use [smart punctuation] instead of Unicode characters. For example, use `---` for an em dash instead of the Unicode character. Characters such as the em dash can be difficult to see in a fixed-width editor, and some editors may not have easy methods to enter such characters. +- See [Admonitions] for formatting callouts such as notes, edition differences, and warnings. + +## Code blocks + +- Do not use indented code blocks; use fenced code blocks with 3+ backticks instead. +- Code blocks should have an explicit language tag. + +## Links + +See [Links] for more information about linking. + +- Links to other chapters should be relative and use the `.md` extension. +- Links to other rust-lang books that are published with the Reference should also be relative so that the linkchecker can validate them. See [outside book links]. +- Links to the standard library should use rustdoc-style links as described in [standard library links]. +- Prefer reference links, with shortcut reference links where appropriate. Place sorted link reference definitions at the bottom of the file, or at the bottom of a section if there is an unusually large number of links specific to that section. + + ```markdown + Example of shortcut link: [enumerations] + Example of reference link with label: [block expression][block] + + [block]: expressions/block-expr.md + [enumerations]: types/enum.md + ``` + +[`cargo xtask style-check`]: ../tests.md#style-checks +[Admonitions]: admonitions.md +[atx]: https://spec.commonmark.org/0.31.2/#atx-headings +[Links]: ../links.md +[outside book links]: ../links.md#outside-book-links +[sentence case]: https://apastyle.apa.org/style-grammar-guidelines/capitalization/sentence-case +[smart punctuation]: https://rust-lang.github.io/mdBook/format/markdown.html#smart-punctuation +[standard library links]: ../links.md#standard-library-links diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/grammar.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/grammar.md new file mode 100644 index 00000000..af1c23ba --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/grammar.md @@ -0,0 +1,172 @@ +# Rust grammar + +The Reference grammar is written in Markdown code blocks using a modified BNF-like syntax (with a blend of regex and other arbitrary things). The [`mdbook-spec`] extension parses these rules and converts them into a renderable format, including railroad diagrams. + +The code block should have a lang string with the word `grammar`, a comma, and the category of the grammar, like this: + +~~~ +```grammar,items +ProductionName -> SomeExpression +``` +~~~ + +The category is used to group similar productions on the grammar summary page in the appendix. + +## Grammar syntax + +The syntax for the grammar itself is similar to what is described in **[Notation]**, though there are some rendering differences. + +A "root" production, marked with `@root`, is one that is not used in any other production. + +The syntax for the grammar notation, described here using its own notation, is: + +``` +Grammar -> Production+ + +BACKTICK -> U+0060 + +LF -> U+000A + +Production -> + ( Comment LF )* + `@root`? Name ` ->` Expression + +Name -> <Alphanumeric or `_`>+ + +Expression -> Sequence (` `* `|` ` `* Sequence)* + +Sequence -> + (` `* AdornedExpr)* ` `* Cut + | (` `* AdornedExpr)+ + +AdornedExpr -> Prefix? Expr1 Quantifier? Suffix? Footnote? + +Prefix -> NegativeLookahead + +NegativeLookahead -> `!` + +Suffix -> ` _` <not underscore, unless in backtick>* `_` + +Footnote -> `[^` ~[`]` LF]+ `]` + +Quantifier -> + Optional + | Repeat + | RepeatPlus + | RepeatRange + | RepeatRangeInclusive + | RepeatRangeNamed + +Optional -> `?` + +Repeat -> `*` + +RepeatPlus -> `+` + +RepeatRange -> `{` ( Name `:` )? Range? `..` Range? `}` + +RepeatRangeInclusive -> `{` ( Name `:` )? Range? `..=` Range `}` + +RepeatRangeNamed -> `{` Name `}` + +Range -> [0-9]+ + +Expr1 -> + Unicode + | NonTerminal + | Break + | Comment + | Terminal + | Charset + | Prose + | Group + | NegativeExpression + +Unicode -> `U+` [`A`-`Z` `0`-`9`]4..=6 + +NonTerminal -> Name + +Break -> LF ` `+ + +Comment -> `//` ~[LF]+ + +Terminal -> BACKTICK ~[LF]+ BACKTICK + +Charset -> `[` (` `* Characters)+ ` `* `]` + +Characters -> + CharacterRange + | CharacterTerminal + | CharacterName + +CharacterRange -> Character `-` Character + +Character -> + BACKTICK <any char> BACKTICK + | Unicode + +CharacterTerminal -> Terminal + +CharacterName -> Name + +Prose -> `<` ~[`>` LF]+ `>` + +Group -> `(` ` `* Expression ` `* `)` + +NegativeExpression -> `~` ( Charset | Terminal | NonTerminal ) + +Cut -> `^` Sequence +``` + +The general format is a series of productions separated by blank lines. The expressions are as follows: + +| Expression | Example | Description | +|------------|---------|-------------| +| Unicode | U+0060 | A single Unicode character. | +| NonTerminal | FunctionParameters | A reference to another production by name. | +| Break | | Used internally by the renderer to detect line breaks and indentation. | +| Comment | // Single line comment. | A comment extending to the end of the line. | +| Terminal | \`example\` | A sequence of exact characters, surrounded by backticks. | +| Charset | \[ \`A\`-\`Z\` \`0\`-\`9\` \`_\` \] | A choice from a set of characters, space-separated. There are three different forms. | +| CharacterRange | \[ \`A\`-\`Z\` \] | A range of characters. Characters can be a Unicode expression or be a literal character surrounded by backticks. | +| CharacterTerminal | \[ \`x\` \] | A single character, surrounded by backticks. | +| CharacterName | \[ LF \] | A nonterminal, referring to another production. | +| Prose | \<any ASCII character except CR\> | An English description of what should be matched, surrounded in angle brackets. | +| Group | (\`,\` Parameter)+ | Groups an expression for the purpose of precedence, such as applying a repetition operator to a sequence of other expressions. | +| NegativeExpression | ~\[\` \` LF\] | Matches anything except the given Charset, Terminal, or Nonterminal. | +| Cut | Expr1 ^ Expr2 \| Expr3 | The hard cut operator. Once the expressions preceding `^` in the sequence match, the rest of the sequence must match or parsing fails unconditionally --- no enclosing expression can backtrack past the cut point. | +| Sequence | \`fn\` Name Parameters | A sequence of expressions that must match in order. | +| Alternation | Expr1 \| Expr2 | Matches only one of the given expressions, separated by the vertical pipe character. | +| Suffix | \_except \[LazyBooleanExpression\]\_ | Adds a suffix to the previous expression to provide an additional English description, rendered in subscript. This can contain limited Markdown, but try to avoid anything except basics like links. | +| Footnote | \[^extern-safe\] | Adds a footnote, which can supply extra information that may be helpful to the user. The footnote itself should be defined outside of the code block like a normal Markdown footnote. | +| Optional | Expr? | The preceding expression is optional. | +| NegativeLookahead | !Expr | Matches if Expr does not follow, without consuming any input. | +| Repeat | Expr* | The preceding expression is repeated 0 or more times. | +| RepeatPlus | Expr+ | The preceding expression is repeated 1 or more times. | +| RepeatRange | Expr{2..4} | The preceding expression is repeated between the range of times specified. Either bound can be excluded, which works just like Rust ranges. | +| RepeatRangeInclusive | Expr{2..=4} | The preceding expression is repeated between the inclusive range of times specified. The lower bound can be omitted. | +| RepeatRange (named) | Expr{name:2..4} | When a name precedes the range, the number of repetitions is bound to that name so that subsequent RepeatRangeNamed expressions can refer to it. The same applies to RepeatRangeInclusive. | +| RepeatRangeNamed | Expr{name} | The preceding expression is repeated the number of times determined by a previously named RepeatRange or RepeatRangeInclusive. | + +## Automatic linking + +The [`mdbook-spec`] plugin automatically adds Markdown link definitions for all production names on every page. To link directly to a production name, simply surround it in square brackets, like `[ArrayExpression]`. + +In some cases, there might be name collisions with the automatic linking of rule names. In that case, disambiguate with the `grammar-` prefix, such as `[Type][grammar-Type]`. The prefix can also be used when explicitness would aid clarity. + +Production names can also be used in link reference definitions to provide custom link text, both with and without the `grammar-` prefix. + +```markdown +We accept any [type]. + +[type]: grammar-Type +``` + +```markdown +We accept any [type]. + +[type]: Type +``` + +[`mdbook-spec`]: tooling/mdbook-spec.md +[Notation]: https://doc.rust-lang.org/nightly/reference/notation.html diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/introduction.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/introduction.md new file mode 100644 index 00000000..364b0f97 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/introduction.md @@ -0,0 +1,37 @@ +# Introduction + +Thank you for your interest in contributing to **The Rust Reference**. This document provides an overview of how to contribute to the Reference and serves as a guide for editors and reviewers. + +There are a few ways of helping with the Reference: critiquing the Reference, editing the Reference, fixing incorrect information, adding examples and glossary entries, and documenting new or otherwise undocumented features in Rust. + +We encourage you to read the [introduction] of the Reference to familiarize yourself with the kind of content the Reference is expected to contain and the conventions it uses. + +## Critiquing the Reference + +This is the easiest way to contribute. As you read the Reference, if you find something confusing, incorrect, or missing, then you can file an issue against the Reference explaining your concerns. + +## Editing the Reference + +Typos and incorrect links get through from time to time. Should you find them, we welcome PRs to fix them. + +## Adding examples and glossary entries + +Examples are great. Many people will only read examples and ignore the prose. Ideally, every facet of every feature should have an example. + +Likewise, the Reference has a glossary. It doesn't need to explain everything or contain every possible definition, but it does need to be expanded upon from its current state. Ideally, entries in the glossary should link to the associated documentation. + +## Adding documentation + +There are a lot of features that are not documented at all or are documented poorly. This is the hardest but most valuable task. Pick an unassigned issue from the [issue tracker] and write about it. + +While writing, you may find it handy to have a [playground] open to test out what you are documenting. + +Feel free to take information from the standard library and Rustonomicon as appropriate. + +Note that we don't write documentation for purely library features, such as threads and IO, and we don't write about Rust in the future. Documentation is written as if the current stable release of Rust is the last release. The `master` branch of the Reference corresponds to what is **stable** on the `main` branch ("nightly") of [rust-lang/rust]. If you want to write about Rust in the future, you want **[The Unstable Book][unstable]**. + +[introduction]: https://doc.rust-lang.org/nightly/reference/introduction.html +[issue tracker]: https://github.com/rust-lang/reference/issues +[playground]: https://play.rust-lang.org/ +[rust-lang/rust]: https://github.com/rust-lang/rust/ +[unstable]: https://doc.rust-lang.org/nightly/unstable-book/ diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/links.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/links.md new file mode 100644 index 00000000..20458758 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/links.md @@ -0,0 +1,101 @@ +# Links + +This chapter explains how links should be handled by the Reference. Several of these capabilities are provided by [`mdbook-spec`](tooling/mdbook-spec.md). + +See also the [linkchecker tests](tests.md#linkcheck) for testing links. + +## Rule links + +[Rules](rules/index.md) can be linked to by their ID using Markdown, with the destination set to the rule ID. Automatic link references allow any rule to be referred to from any page in the book. + +```markdown +Direct label link: [names.preludes.lang] + +Destination label link (custom link text): [language prelude][names.preludes.lang] + +Definition link: [namespace kinds] + +[namespace kinds]: names.namespaces.kinds +``` + +## Standard library links + +You should link to the standard library without specifying a URL, in a fashion similar to [rustdoc intra-doc links][intra]. Some examples: + +We can link to the page on `Option`: + +```markdown +[`std::option::Option`] +``` + +In these links, generics are ignored and can be included: + +```markdown +[`std::option::Option<T>`] +``` + +If we don't want the full path in the text, we can write: + +```markdown +[`Option`](std::option::Option) +``` + +Macros can end in `!`. This can be helpful for disambiguation. For example, this refers to the macro rather than the module: + +```markdown +[`alloc::vec!`] +``` + +Explicit namespace disambiguation is also supported: + +```markdown +[`std::vec`](mod@std::vec) +``` + +Beware of some limitations, for example: + +- Links to reexports from `std_arch` don't work due to <https://github.com/rust-lang/rust/issues/96506>. +- Links to keywords aren't supported. +- Links to trait impls where the trait is not in the prelude don't work. Traits must be in scope, and currently there is no way to add them. +- If there are multiple generic implementations, it will link to one randomly (see <https://github.com/rust-lang/rust/issues/76895>). + +When running into a rustdoc limitation, consider manually linking to the correct page using a relative link. For example, `../std/arch/macro.is_x86_feature_detected.html`. + +When rendering the Reference locally, it uses relative links by default to conform with how the books are published. This probably isn't what you want, so you will usually want to set the [`SPEC_RELATIVE=0` environment variable][rel] so that the links go to the live site instead. + +[intra]: https://doc.rust-lang.org/rustdoc/write-documentation/linking-to-items-by-name.html +[rel]: tooling/building.md#spec_relative + +## Grammar links + +Link definitions are automatically generated for all grammar production names. See [grammar automatic linking](grammar.md#automatic-linking) for more. + +```markdown +This attribute uses the [MetaWord] syntax. + +Explicit grammar links can have the `grammar-` prefix like [Type][grammar-Type]. + +Grammar links can also appear in link reference definitions, e.g. [type]. + +[type]: grammar-Type +``` + +## Outside book links + +Links to other books published with the Reference should be relative links pointing to the corresponding book. This allows the links to point to the correct version, to work with the offline docs, and to be checked by the linkchecker. For example: + +```markdown +See [`-C panic`]. + +[`-C panic`]: ../rustc/codegen-options/index.html#panic +``` + +## Internal links + +When possible, internal links should use [rule links](#rule-links) or [grammar links](#grammar-links). Otherwise, links should be relative to the file path and use the `.md` extension. + +```markdown +- Rule link: [language prelude][names.preludes.lang] +- Grammar link: [MetaWord] +- Internal link: [Modules](items/modules.md#attributes-on-modules) +``` diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/index.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/index.md new file mode 100644 index 00000000..93250e4f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/index.md @@ -0,0 +1,80 @@ +# Contribution process + +## Before contributing + +For nontrivial changes, we encourage people to discuss these before opening a PR. This gives the Reference team a chance to understand your idea better and ensure it fits with the intended direction of the Reference. Typically, you should file an issue or start a thread on [Zulip](#zulip) before submitting a pull request. + +## Contributing process overview + +The general outline of a contribution is as follows: + +1. [Check out the source.](../tooling/building.md#checking-out-the-source) +2. [Install mdbook.](../tooling/building.md#installing-mdbook) +3. [Learn to build the book locally.](../tooling/building.md#running-mdbook) +4. Make your changes to the source files. Be sure to follow all the guidelines in this book for styling, conventions, etc. +5. [Run the tests.](../tests.md) +6. [Submit a pull request](#submitting-a-pull-request) +7. The PR will go through the review process. + - See **[Review Policy](../review-policy.md)** for the types of reviews it may undergo. + - This may take a while, as the team has limited time. +8. Once approved, a team member will merge the change. + - The team may apply editorial changes before merging. + - It may take a few weeks for the change to appear on the [nightly website](https://doc.rust-lang.org/nightly/reference/). See **[Publishing](../publishing.md)** for more details. + +## Office hours + +The lang-docs team holds office hours on Tuesdays at [3:30 PM US/Eastern](https://dateful.com/convert/est-edt-eastern-time?t=330pm). We meet on [Jitsi Meet](https://meet.jit.si/rust-t-lang-docs). Check the [Zulip](#zulip) channel for the latest status and availability. + +## Zulip + +There are channels on Zulip for discussions about the Reference: + +- [`#t-lang-docs`](https://rust-lang.zulipchat.com/#narrow/channel/237824-t-lang-docs) --- Used by the lang docs team. +- [`#t-lang-docs/reference`](https://rust-lang.zulipchat.com/#narrow/channel/520709-t-lang-docs.2Freference) --- Discussion about the Reference specifically. + +## Working on issues + +When an issue is labeled with [Help Wanted], the team is asking for contributions to help address it. + +If you want to work on an issue, you can assign yourself by commenting `@rustbot claim`. See **[Issue Assignment]** for more information. + +[Help Wanted]: https://github.com/rust-lang/reference/issues?q=state%3Aopen%20label%3A%22Help%20Wanted%22 +[issue assignment]: https://forge.rust-lang.org/triagebot/issue-assignment.html + +## New features + +See **[Stabilization]** for information on how to document new features. + +[stabilization]: stabilization.md + +## Minor changes + +Minor changes --- such as small corrections, wording cleanup, and formatting fixes --- can be made simply by opening a PR. + +## Major changes + +Major changes --- such as large rewrites, reorganizations, and new chapters --- should be discussed with and approved by the Reference team first. Open an issue (if there isn't already one) to discuss the kinds of changes you are interested in. When the Reference team is able, they will work with you to approve or give feedback on the change. + +## Submitting a pull request + +When submitting a pull request, please follow these guidelines: + +- Include a clear description of what the change is and why it is being made. +- Keep a clean git history; each commit should explain the reason for the change. +- Use [GitHub’s keywords] in the description to automatically link to an issue if the PR resolves it. For example, saying `Closes #1234` will link issue #1234 to the PR. When the PR is merged, GitHub will automatically close the issue. + +When your PR is submitted, GitHub automatically runs all tests. The GitHub interface shows a green checkmark if these pass or a red X if they fail. Links to the logs are available on the PR page to diagnose any issues. + +[GitHub’s keywords]: https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue + +### PR labeling + +PRs are marked with [labels] such as [`S-waiting-on-review`] and [`S-waiting-on-author`] to indicate their status. Anyone can use the [`@rustbot`] bot to adjust the labels. If a PR is marked as `S-waiting-on-author` and you have pushed new changes that you would like reviewed, you can comment on the PR with `@rustbot ready`. The bot will switch the labels on the PR. + +More information about these commands can be found at the [shortcuts documentation]. + +[`@rustbot`]: https://github.com/rustbot +[`S-waiting-on-author`]: https://github.com/rust-lang/reference/labels/S-waiting-on-author +[`S-waiting-on-review`]: https://github.com/rust-lang/reference/labels/S-waiting-on-review +[labels]: https://github.com/rust-lang/reference/labels +[shortcuts documentation]: https://forge.rust-lang.org/triagebot/shortcuts.html diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/stabilization.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/stabilization.md new file mode 100644 index 00000000..84498af3 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/process/stabilization.md @@ -0,0 +1,26 @@ +# Stabilization process + +New features and changes to the Rust language usually require an update to the Reference to incorporate the change. This can be done at any time before stabilization, and it is usually better to prepare a PR early (assuming the implementation is not expected to change significantly). + +An exception to this process occurs when a language change involves a part of the language that is undocumented or a section of the Reference that is incomplete. For example, type inference is currently not documented, so changes to the details of type inference do not require an update to the Reference. + +However, when a new feature introduces a rule that can be stated independently of the undocumented material, that rule should still be documented. In this case, add the new rule to the relevant placeholder section. When the section is eventually filled out, the rule will be incorporated into the complete text. + +## Pull request + +When opening a PR, please include links to as much information as possible so that reviewers can better understand the change. This includes links to the following, if they exist: + +- The tracking issue. +- The `rust-lang/rust` stabilization pull request. +- The stabilization report. +- Background information such as RFCs. +- The files in `rustc` where it is implemented, if it is isolated to a relatively concise part. +- The tests in `rust-lang/rust`. + +Always link to the tracking issue and, if applicable, the stabilization PR. Beyond those, information that already appears in the tracking issue, stabilization report, or PR does not need to be duplicated in the PR description. + +## Inline tests + +If a PR documents a newly stabilized feature, its inline tests will fail until the stabilization PR is merged and a new nightly compiler is available. We intend to improve this process in the future (see [#1864]). + +[#1864]: https://github.com/rust-lang/reference/issues/1864 diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/publishing.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/publishing.md new file mode 100644 index 00000000..f9bba2ad --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/publishing.md @@ -0,0 +1,11 @@ +# Publishing process + +The process for getting the Reference content into a [Rust release](https://doc.rust-lang.org/reference/#rust-releases) and on the website is as follows: + +1. Changes are merged to this repository. +2. [Triagebot](https://forge.rust-lang.org/triagebot/doc-updates.html) will automatically synchronize this repository to [rust-lang/rust]. This happens every other week. The Reference is tracked in [rust-lang/rust] as a [submodule](https://github.com/rust-lang/rust/tree/master/src/doc). + - This will open a PR on [rust-lang/rust] that needs to be merged, which can take up to several days. +3. At midnight UTC, whatever is on the default branch of [rust-lang/rust] will be part of that nightly release and will be published after a few hours to <https://doc.rust-lang.org/nightly/reference/>. +4. Following Rust's [release process](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html), every 6 weeks, nightly is promoted to beta (<https://doc.rust-lang.org/beta/reference/>), and 6 weeks after that, it is promoted to stable (<https://doc.rust-lang.org/stable/reference/>). + +[rust-lang/rust]: https://github.com/rust-lang/rust/ diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/resources.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/resources.md new file mode 100644 index 00000000..1dc89515 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/resources.md @@ -0,0 +1,6 @@ +# Resources + +The Reference team has collected a set of resources about language specifications and technical writing. + +- [Language specs](https://hackmd.io/@rust-spec-team/HJey-puL6) --- It can be useful to learn how other languages are specified. This includes papers, standards, and commentary on how languages are specified. +- [Style and writing guides](https://hackmd.io/@rust-spec-team/rkj1RS3uR) --- This contains a large list of different English and technical writing guides. diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/review-policy.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/review-policy.md new file mode 100644 index 00000000..ce6d50db --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/review-policy.md @@ -0,0 +1,60 @@ +# Review policy + +Team members have permission to merge changes from other contributors in the <https://github.com/rust-lang/reference> repository. There are different guidelines for reviewing based on the kind of changes being made: + +## Review principles + +Reviewers and authors should focus on a few key principles during the review process: + +- **Understandability**: Prose within the Reference should be understandable to most members of the Project. Contributions should assume that readers are familiar with the rest of the content of the Reference, but, wherever possible, sections should facilitate that understanding by linking to related content. +- **Defensibility**: When the lang-docs team merges a change to the Reference, they are agreeing to take responsibility for it going forward. Team members need to feel confident defending and explaining the correctness of content within the Reference. Whenever possible, changes to the Reference should back up any claims with concise examples to verify correctness. +- **Voice**: Authors are not expected to have competence as a specification writer when drafting new contributions to the Reference. As long as claims are understandable and defensible, it is fine for PRs to be written in a casual tone or with the voice of the author instead of the voice of the Reference. Team members will bring editorial experience as part of their reviews and will revise the phrasing, organization, style, etc., to fit the Reference before merging if necessary. + +## Policy changes + +Significant changes to the policy of how the team operates, such as changes to this document, should have the agreement of the team without any blocking objections. + +Minor changes to something like style enforcement can be made with the review from a team member, as long as there is high confidence that it is unlikely any team member would object (for example, codifying a guideline that is already in practice) and that the change can be easily reversed. + +## Meaningful content addition or changes + +When adding or changing content in the Reference, the reviewer should consult with appropriate experts to validate the changes. This may not be required if the reviewer has high confidence in the correctness of the changes, if the reviewer is well-versed in the topic, or if the relevant experts are already the author of or actively involved in the PR. It is up to the reviewer to use good judgment on when to consult. + +Content should always follow the guidelines in this contributor guide. + +## Minor content changes + +For minor content changes --- such as small cleanups, wording fixes, or formatting corrections --- a maintainer may push fixes directly to the PR branch and merge, without consulting the author or other reviewers. + +## Tooling changes + +Minor changes to the tooling may be made with a review from a team member. This includes bug fixes, minor additions that are unlikely to have objections, and additions that have already been discussed. + +Major changes, such as a change in how content is authored or major changes to how the tooling works, should be approved by the team without blocking objections. + +## Review process flowchart + +When reviewing a pull request, ask yourself the following questions: + +### Are the proposed changes true? + +If we're not sure and can't easily verify it ourselves, we ask someone who would know. + +### Does this make any new guarantees about the language? + +If this would make a new guarantee about the language, this needs to go through the `lang` team to be accepted (unless the `lang` team has clearly accepted this guarantee elsewhere). Ask @traviscross if at all unsure about any of these. + +### Would we have added this to the Reference ourselves? + +There are a number of PRs that might be true, but when we look at them, we think to ourselves, in our heart of hearts, that this just isn't something we would have bothered to write ourselves. We don't want to accept a PR just because it's in front of us and not obviously false. It should clearly add value. + +### Is this editorially sound? + +Some PRs try to "sell" the language too much, or try to explain more (or less) than needed, or give too many (or too few) examples, etc. The PR should match the general flavor of the Reference here. + +### Is this well written? + +Some PRs are correct but are awkwardly worded or have typographical problems. If the changes are small, we'll just add commits to the branch to clean things up, then merge. + +<!-- TODO --> +This policy does not yet cover the process for getting final approval from the relevant teams. diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/index.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/index.md new file mode 100644 index 00000000..e19d10bf --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/index.md @@ -0,0 +1,44 @@ +# Language rules + +Clauses within the Reference are labeled with a named *rule*. This provides the ability to link and refer to individual clauses and to [link to the `rustc` test suite](test-annotations.md). + +## Rule labels + +Most clauses should be preceded by a rule label. A rule label should be on a line by itself and should look like this: + +```markdown +r[foo.bar] +``` + +The rule name should be lowercase, with periods separating components from most general to most specific (e.g., `r[array.repeat.zero]`). + +Rules can be linked to by their ID using Markdown such as `[foo.bar]`. There are [automatic link references] so that any rule can be referred to from any page in the book. + +In the HTML, the rules are clickable, just like headers. + +## Rule guidelines + +When assigning rules to new paragraphs or modifying rule names, use the following guidelines: + +1. A rule applies to one core idea, which should be easily determined when reading the paragraph it is applied to. +2. Other than the "intro" paragraph, purely explanatory, expository, or exemplary content does not need a rule. If the expository paragraph isn't directly related to the previous one, separate it with a hard (rendered) line break. + - This content will be moved to `[!NOTE]` or more specific admonitions in the future. +3. Rust code examples and tests do not need their own rules. +4. Use the following guidelines for admonitions: + - Notes: Do not include a rule. + - Warning: Omit the rule if the warning follows from the previous paragraph or if the warning is explanatory and doesn't introduce any new rules. + - Target-specific behavior: Always include the rule. + - Edition differences: Always include the rule. +5. The following keywords should be used to identify paragraphs when unambiguous: + - `intro`: The beginning paragraph of each section. It should explain the construct being defined overall. + - `syntax`: Syntax definitions or explanations when BNF syntax definitions are not used. + - `namespace`: For items only, specifies the namespace(s) the item introduces a name in. It may also be used elsewhere when defining a namespace (e.g., `r[attribute.diagnostic.namespace]`). +6. When a rule doesn't fall under the above keywords, or for section rule IDs, name the subrule as follows: + - If the rule names a specific Rust language construct (e.g., an attribute, standard library type/function, or keyword-introduced concept), use the construct as named in the language, appropriately case-adjusted (but do not replace `_`s with `-`s). + - Other than Rust language concepts with `_`s in the name, use `-` characters to separate words within a "subrule". + - Whenever possible, do not repeat previous components of the rule. + - Edition differences admonitions should typically be named by the edition where the behavior changed. You should be able to correspond the dates to the chapters in <https://doc.rust-lang.org/edition-guide/>. + - Target-specific admonitions should typically be named by the least specific target property to which they apply (e.g., if a rule affects all x86 CPUs, the rule name should include `x86` rather than separately listing `i586`, `i686`, and `x86_64`. If a rule applies to all ELF platforms, it should be named `elf` rather than listing every ELF OS). + - Use an appropriately descriptive, but short, name if the language does not provide one. + +[automatic link references]: ../links.md#rule-links diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/test-annotations.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/test-annotations.md new file mode 100644 index 00000000..962b1b7b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/rules/test-annotations.md @@ -0,0 +1,15 @@ +# rustc test annotations + +Tests in <https://github.com/rust-lang/rust> can be linked to rules in the Reference. The rule will include a link to the tests, and there is also an [appendix] that tracks how the rules are currently linked. + +Tests in the `tests` directory can be annotated with the `//@ reference: x.y.z` header to link them to a rule. The header can be specified multiple times if a single file covers multiple rules. + +Compiler developers are not expected to add `reference` annotations to tests. However, if they do want to help, their cooperation is welcome. Reference authors and editors are responsible for ensuring every rule has a test associated with it. + +The tests are beneficial for reviewers to see the behavior of a rule. They are also a benefit to readers who may want to see examples of particular behaviors. When adding new rules, you should wait until the Reference side is approved before submitting a PR to `rust-lang/rust` (to avoid churn if we decide on different names). + +Always annotate with the most specific rule name available. For example, use `asm.rules.reg-not-input` rather than the broader `asm.rules`. + +Complete coverage is the goal but is not yet expected. + +[appendix]: https://doc.rust-lang.org/nightly/reference/test-summary.html diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/style.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/style.md new file mode 100644 index 00000000..71babacc --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/style.md @@ -0,0 +1,15 @@ +# Style guide + +The following sections describe the preferred style for English prose in the Reference. + +## Wording + +Use American English spelling. + +Avoid qualifying something as "in Rust"; the entire Reference is about Rust. + +## Punctuation + +Use Oxford commas. + +Avoid slashes for alternatives ("program/binary"); use a conjunction or rewrite the phrase ("program or binary"). diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tests.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tests.md new file mode 100644 index 00000000..cffdbdc0 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tests.md @@ -0,0 +1,64 @@ +# Running tests + +There are several different kinds of tests you can run (these are enforced in CI): + +- [`cargo xtask test-all`](#all-tests) --- Runs all tests. +- [`cargo xtask mdbook-test`](#inline-tests) --- Tests the inline Rust code blocks. +- [`cargo xtask linkcheck`](#linkcheck) --- Validates that Markdown links aren't broken. +- [`cargo xtask style-check`](#style-checks) --- Validates various style checks. +- [Code formatting](#code-formatting) --- Checks that all Rust tooling code is formatted. +- [mdbook-spec tests](#mdbook-spec-tests) --- Internal tests for `mdbook-spec`. + +## All tests + +```sh +cargo xtask test-all +``` + +This command runs all the tests listed below. + +We recommend running this as a last step before opening a PR. This runs most of the tests required for CI to pass. See [`tools/xtask/src/main.rs`](https://github.com/rust-lang/reference/blob/HEAD/tools/xtask/src/main.rs) for details on what this does. + +## Inline tests + +```sh +cargo xtask mdbook-test +``` + +This command runs all tests that are inline in the Markdown. Internally, this uses [`rustdoc`](https://doc.rust-lang.org/rustdoc/) to run the tests and supports all the same features. Any code block with the `rust` language will be compiled unless it is ignored. See [Examples] for more. + +Previous versions of this guide suggested `mdbook test`, but this only works reliably if your default toolchain is nightly. + +## Linkcheck + +```sh +cargo xtask linkcheck +``` + +This command verifies that links are not broken. It downloads and uses the [`linkchecker`](https://github.com/rust-lang/rust/tree/main/src/tools/linkchecker) script hosted in the `rust-lang/rust` repository. + +This requires a recent nightly installed via `rustup` and the `rust-docs` component. + +After compiling the script, it builds the Reference using `mdbook` and then scans all local links to verify that they are valid, particularly between various books. This does not check any network links. + +## Style checks + +```sh +cargo xtask style-check +``` + +This uses the [`style-check`](https://github.com/rust-lang/reference/tree/HEAD/tools/style-check) tool to enforce various formatting rules. + +## Code formatting + +CI uses `cargo fmt --check` to verify that all Rust sources for the tools (such as `mdbook-spec`) are properly formatted. All code must be formatted with `rustfmt`. + +## mdbook-spec tests + +```sh +cargo test --manifest-path mdbook-spec/Cargo.toml +``` + +CI runs `cargo test` on `mdbook-spec` to execute any tests for the tool itself. + +[Examples]: examples.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/building.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/building.md new file mode 100644 index 00000000..8571a58c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/building.md @@ -0,0 +1,63 @@ +# Building the Reference + +## Checking out the source + +To build the Reference, first clone the project: + +```sh +git clone https://github.com/rust-lang/reference.git +cd reference +``` + +## Installing mdbook + +The Reference is built using [mdbook]. + +First, ensure that you have a recent copy of the nightly Rust compiler installed, as this is needed to run the tests: + +```sh +rustup toolchain install nightly +``` + +Now, ensure you have `mdbook` installed, as this is needed to build the Reference: + +```sh +cargo install --locked mdbook +``` + +[mdbook]: https://rust-lang.github.io/mdBook/ + +## Running mdbook + +`mdbook` provides several commands and options to help you work on the book: + +- `mdbook build --open`: Builds the book and opens it in a web browser. +- `mdbook serve --open`: Launches a web server on localhost. It automatically rebuilds the book whenever any file changes and reloads your web browser. + +The book contents are driven by a `SUMMARY.md` file, and every file must be linked there. See <https://rust-lang.github.io/mdBook/> for more information. + +### `SPEC_RELATIVE` + +The `SPEC_RELATIVE=0` environment variable makes links to the standard library go to <https://doc.rust-lang.org/> instead of being relative. This is useful when viewing locally since you normally don't have a copy of the standard library. + +```sh +SPEC_RELATIVE=0 mdbook serve --open +``` + +The published site at <https://doc.rust-lang.org/reference/> (or local docs using `rustup doc`) does not set this, which means it uses relative links. This supports offline viewing and links to the correct version (for example, links in <https://doc.rust-lang.org/1.81.0/reference/> will stay within the 1.81.0 directory). + +### `SPEC_DENY_WARNINGS` + +The `SPEC_DENY_WARNINGS=1` environment variable turns all warnings generated by `mdbook-spec` into errors. This is used in CI to ensure that there aren't any problems with the book content. + +```sh +SPEC_DENY_WARNINGS=1 mdbook serve --open +``` + +### `SPEC_RUST_ROOT` + +The `SPEC_RUST_ROOT` environment variable can be used to point to the directory of a checkout of <https://github.com/rust-lang/rust>. This is used by the test-linking feature so that it can find tests linked to Reference rules. If this is not set, the tests won't be linked. + +```sh +SPEC_RUST_ROOT=/path/to/rust mdbook serve --open +``` diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/index.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/index.md new file mode 100644 index 00000000..ff043e67 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/index.md @@ -0,0 +1,10 @@ +# Reference tooling + +The Reference uses [mdBook] to convert its source files from Markdown to HTML. See [Building the Reference] for more information. The [`mdbook-spec`] extension adds several custom features used by the Reference. + +For testing, see [Running Tests]. + +[`mdbook-spec`]: mdbook-spec.md +[Building the Reference]: building.md +[mdbook]: https://rust-lang.github.io/mdBook/ +[Running Tests]: ../tests.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/mdbook-spec.md b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/mdbook-spec.md new file mode 100644 index 00000000..8fb73502 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/dev-guide/src/tooling/mdbook-spec.md @@ -0,0 +1,39 @@ +# mdbook-spec + +[`mdbook-spec`] is an mdBook preprocessor that adds features to the Reference. It provides: + +- Parsing and generation of [grammar diagrams]. + - [Automatic grammar production links]. + - Generation of the [grammar summary appendix]. +- [Automatic standard library links]. +- Handling of [rule names]. + - Validation of the names. + - Converting rule names to links. + - [Automatic rule link references]. + - Generation of [links to rule tests]. + - Generation of the [test summary]. +- Support for [admonitions]. + +## Environment variables + +There are a few environment variables that `mdbook-spec` uses, described in **[Building the Reference]**: + +- [`SPEC_RELATIVE`] --- Can be set to link external books to the live site. +- [`SPEC_DENY_WARNINGS`] --- Whether warnings should be treated as errors. +- [`SPEC_RUST_ROOT`] --- The path to a checkout of the [`rust-lang/rust`] GitHub repository. This is used for test linking. + +[`mdbook-spec`]: https://github.com/rust-lang/reference/tree/HEAD/tools/mdbook-spec +[`rust-lang/rust`]: https://github.com/rust-lang/rust +[`SPEC_DENY_WARNINGS`]: building.md#SPEC_DENY_WARNINGS +[`SPEC_RELATIVE`]: building.md#SPEC_RELATIVE +[`SPEC_RUST_ROOT`]: building.md#SPEC_RUST_ROOT +[admonitions]: ../formatting/admonitions.md +[Automatic grammar production links]: ../grammar.md#automatic-linking +[Automatic rule link references]: ../links.md#rule-links +[Automatic standard library links]: ../links.md#standard-library-links +[Building the Reference]: building.md +[grammar diagrams]: ../grammar.md +[grammar summary appendix]: https://doc.rust-lang.org/nightly/reference/grammar.html +[links to rule tests]: ../rules/test-annotations.md +[rule names]: ../rules/index.md +[test summary]: https://doc.rust-lang.org/nightly/reference/test-summary.html diff --git a/stdlib/kvlang/reference/rust/reference-repo/docs/authoring.md b/stdlib/kvlang/reference/rust/reference-repo/docs/authoring.md new file mode 100644 index 00000000..f23b8b79 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/docs/authoring.md @@ -0,0 +1,27 @@ +# Authoring Guide + +This document serves as a guide for editors and reviewers. Some conventions and content guidelines are specified in the [introduction]. + +[introduction]: ../src/introduction.md + +## Content guidelines + +The following are guidelines for the content of the reference. + +### Targets + +The reference does not document which targets exist, or the properties of specific targets. The reference may refer to *platforms* or *target properties* where required by the language. Some examples: + +* Conditional-compilation keys like `target_os` are specified to exist, but not what their values must be. +* The `windows_subsystem` attribute specifies that it only works on Windows platforms. +* Inline assembly and the `target_feature` attribute specify the architectures that are supported. + +### Editions + +The main text and flow should document only the current edition. Whenever there is a difference between editions, the differences should be called out with an edition block, such as: + +```markdown +r[foo.bar.edition2021] +> [!EDITION-2021] +> Describe what changed in 2021. +``` diff --git a/stdlib/kvlang/reference/rust/reference-repo/reference.md b/stdlib/kvlang/reference/rust/reference-repo/reference.md new file mode 100644 index 00000000..fdeea17e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/reference.md @@ -0,0 +1,4 @@ +% The Rust Reference has moved + +We've split up the reference into chapters. Please find it at its new +home [here](reference/index.html). diff --git a/stdlib/kvlang/reference/rust/reference-repo/rust-toolchain.toml b/stdlib/kvlang/reference/rust/reference-repo/rust-toolchain.toml new file mode 100644 index 00000000..5d56faf9 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/stdlib/kvlang/reference/rust/reference-repo/rustfmt.toml b/stdlib/kvlang/reference/rust/reference-repo/rustfmt.toml new file mode 100644 index 00000000..35011368 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/rustfmt.toml @@ -0,0 +1 @@ +style_edition = "2024" diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/SUMMARY.md b/stdlib/kvlang/reference/rust/reference-repo/src/SUMMARY.md new file mode 100644 index 00000000..0692b3f4 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/SUMMARY.md @@ -0,0 +1,143 @@ +# The Rust Reference + +[Introduction](introduction.md) + +- [Notation](notation.md) + +- [Lexical structure](lexical-structure.md) + - [Input format](input-format.md) + - [Shebang](shebang.md) + - [Keywords](keywords.md) + - [Identifiers](identifiers.md) + - [Comments](comments.md) + - [Whitespace](whitespace.md) + - [Tokens](tokens.md) + +- [Macros](macros.md) + - [Macros by example](macros-by-example.md) + - [Procedural macros](procedural-macros.md) + +- [Crates and source files](crates-and-source-files.md) + +- [Conditional compilation](conditional-compilation.md) + +- [Items](items.md) + - [Modules](items/modules.md) + - [Extern crates](items/extern-crates.md) + - [Use declarations](items/use-declarations.md) + - [Functions](items/functions.md) + - [Type aliases](items/type-aliases.md) + - [Structs](items/structs.md) + - [Enumerations](items/enumerations.md) + - [Unions](items/unions.md) + - [Constant items](items/constant-items.md) + - [Static items](items/static-items.md) + - [Traits](items/traits.md) + - [Implementations](items/implementations.md) + - [External blocks](items/external-blocks.md) + - [Generic parameters](items/generics.md) + - [Associated items](items/associated-items.md) + +- [Attributes](attributes.md) + - [Testing](attributes/testing.md) + - [Derive](attributes/derive.md) + - [Diagnostics](attributes/diagnostics.md) + - [Code generation](attributes/codegen.md) + - [Limits](attributes/limits.md) + - [Type system](attributes/type_system.md) + - [Debugger](attributes/debugger.md) + +- [Statements and expressions](statements-and-expressions.md) + - [Statements](statements.md) + - [Expressions](expressions.md) + - [Literal expressions](expressions/literal-expr.md) + - [Path expressions](expressions/path-expr.md) + - [Block expressions](expressions/block-expr.md) + - [Operator expressions](expressions/operator-expr.md) + - [Grouped expressions](expressions/grouped-expr.md) + - [Array and index expressions](expressions/array-expr.md) + - [Tuple and index expressions](expressions/tuple-expr.md) + - [Struct expressions](expressions/struct-expr.md) + - [Call expressions](expressions/call-expr.md) + - [Method call expressions](expressions/method-call-expr.md) + - [Field access expressions](expressions/field-expr.md) + - [Closure expressions](expressions/closure-expr.md) + - [Loop expressions](expressions/loop-expr.md) + - [Range expressions](expressions/range-expr.md) + - [If expressions](expressions/if-expr.md) + - [Match expressions](expressions/match-expr.md) + - [Return expressions](expressions/return-expr.md) + - [Await expressions](expressions/await-expr.md) + - [Underscore expressions](expressions/underscore-expr.md) + +- [Patterns](patterns.md) + +- [Type system](type-system.md) + - [Types](types.md) + - [Boolean type](types/boolean.md) + - [Numeric types](types/numeric.md) + - [Character type](types/char.md) + - [String slice type](types/str.md) + - [Never type](types/never.md) + - [Tuple types](types/tuple.md) + - [Array types](types/array.md) + - [Slice types](types/slice.md) + - [Struct types](types/struct.md) + - [Enumerated types](types/enum.md) + - [Union types](types/union.md) + - [Function item types](types/function-item.md) + - [Closure types](types/closure.md) + - [Pointer types](types/pointer.md) + - [Function pointer types](types/function-pointer.md) + - [Trait object types](types/trait-object.md) + - [Impl trait type](types/impl-trait.md) + - [Type parameters](types/parameters.md) + - [Inferred type](types/inferred.md) + - [Dynamically sized types](dynamically-sized-types.md) + - [Type layout](type-layout.md) + - [Interior mutability](interior-mutability.md) + - [Subtyping and variance](subtyping.md) + - [Trait and lifetime bounds](trait-bounds.md) + - [Type coercions](type-coercions.md) + - [Divergence](divergence.md) + - [Destructors](destructors.md) + - [Lifetime elision](lifetime-elision.md) + +- [Special types and traits](special-types-and-traits.md) + +- [Names](names.md) + - [Namespaces](names/namespaces.md) + - [Scopes](names/scopes.md) + - [Preludes](names/preludes.md) + - [Paths](paths.md) + - [Name resolution](names/name-resolution.md) + - [Visibility and privacy](visibility-and-privacy.md) + +- [Memory model](memory-model.md) + - [Memory allocation and lifetime](memory-allocation-and-lifetime.md) + - [Variables](variables.md) + +- [Panic](panic.md) + +- [Linkage](linkage.md) + +- [Inline assembly](inline-assembly.md) + +- [Unsafety](unsafety.md) + - [The `unsafe` keyword](unsafe-keyword.md) + - [Behavior considered undefined](behavior-considered-undefined.md) + - [Behavior not considered unsafe](behavior-not-considered-unsafe.md) + +- [Constant evaluation](const_eval.md) + +- [Application binary interface](abi.md) + +- [The Rust runtime](runtime.md) + +- [Appendices](appendices.md) + - [Grammar summary](grammar.md) + - [Syntax index](syntax-index.md) + - [Macro follow-set ambiguity formal specification](macro-ambiguity.md) + - [Influences](influences.md) + - [Test summary](test-summary.md) + - [Glossary](glossary.md) diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/abi.md b/stdlib/kvlang/reference/rust/reference-repo/src/abi.md new file mode 100644 index 00000000..2fe7817c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/abi.md @@ -0,0 +1,192 @@ +r[abi] +# Application binary interface (ABI) + +r[abi.intro] +This section documents features that affect the ABI of the compiled output of a crate. + +See *[extern functions]* for information on specifying the ABI for exporting functions. See *[external blocks]* for information on specifying the ABI for linking external libraries. + +<!-- template:attributes --> +r[abi.used] +## The `used` attribute + +r[abi.used.intro] +The *`used` [attribute]* forces a [static] to be kept in the output object file (.o, .rlib, etc., excluding final binaries) even if it's never used or referenced by any other item in the crate. The linker, however, is still free to remove it. + +> [!EXAMPLE] +> ```rust +> // lib.rs +> +> // This is kept because of `#[used]`. +> #[used] +> static S1: u8 = 0; +> +> // This is removable because it's unused. +> #[allow(dead_code)] +> static S2: u8 = 0; +> +> // This is kept because it's publicly reachable. +> pub static S3: u8 = 0; +> +> // This is kept because it's referenced by a publicly +> // reachable function. +> static S4: u8 = 0; +> #[unsafe(no_mangle)] pub fn f4() -> &'static u8 { &S4 } +> +> // This is removable because it's referenced only by a +> // private, unused (dead) function. +> static S5: u8 = 0; +> #[allow(dead_code)] +> fn f5() -> &'static u8 { &S5 } +> ``` +> +> ```console +> $ rustc -O --emit=obj --crate-type=rlib lib.rs +> $ LC_ALL=C nm -C lib.o +> 0000000000000000 R lib::S1 +> 0000000000000000 R lib::S3 +> 0000000000000000 r lib::S4 +> 0000000000000000 T f4 +> ``` + +r[abi.used.syntax] +The `used` attribute uses the [MetaWord] syntax. + +r[abi.used.allowed-positions] +The `used` attribute may only be applied to [`static` items]. + +r[abi.used.duplicates] +Only the first use of `used` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[abi.no_mangle] +## The `no_mangle` attribute + +r[abi.no_mangle.intro] +The *`no_mangle` [attribute]* disables the standard symbol name mangling on a [function] or [static]. The symbol for the item is the item's identifier. + +> [!EXAMPLE] +> ```rust +> #[unsafe(no_mangle)] +> extern "C" fn foo() {} +> ``` + +r[abi.no_mangle.syntax] +The `no_mangle` attribute uses the [MetaWord] syntax. + +r[abi.no_mangle.allowed-positions] +The `no_mangle` attribute may only be applied to: + +- [Static items][items.static] +- [Free functions][items.fn] +- [Inherent associated functions][items.associated.fn] +- [Trait impl functions][items.impl.trait] + +> [!NOTE] +> `rustc` lints against use in other positions. This may become an error in the future. + +<!-- TODO: Currently it works on a trait function with a body, but generates a warning about being phased out. how do we document that? +https://github.com/rust-lang/rust/pull/86492#issuecomment-885682960 +--> + +<!-- TODO: should this clarify that external block items are already unmangled?, and thus the attribute does nothing? Currently it is "phased out" warning. --> + +r[abi.no_mangle.closures] +The `no_mangle` attribute may not be used with a [closure]. + +r[abi.no_mangle.generics] +The `no_mangle` attribute may not be used on an item with generic parameters. + +r[abi.no_mangle.duplicates] +Only the first use of `no_mangle` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[abi.no_mangle.export_name] +When the `no_mangle` and [`export_name`][abi.export_name] attributes are both applied to the same item, the symbol name from `export_name` is used, and `no_mangle` has no effect. + +> [!NOTE] +> `rustc` lints against this combination. + +r[abi.no_mangle.unsafe] +The `no_mangle` attribute must be marked with [`unsafe`][attributes.safety] because an unmangled symbol may collide with another symbol with the same name (or with a well-known symbol), leading to undefined behavior. + +r[abi.no_mangle.edition2024] +> [!EDITION-2024] +> Before the 2024 edition, it is allowed to use the `no_mangle` attribute without `unsafe`. + +r[abi.no_mangle.publicly-exported] +In addition to disabling name mangling, the `no_mangle` attribute causes the symbol to be publicly exported from the produced library or object file, similar to the [`used`][abi.used] attribute. + +r[abi.no_mangle.ascii-only] +The `no_mangle` attribute may only be used on items with a name that contains only ASCII characters. + +r[abi.link_section] +## The `link_section` attribute + +r[abi.link_section.intro] +The *`link_section` attribute* specifies the section of the object file that a [function] or [static]'s content will be placed into. + +r[abi.link_section.syntax] +The `link_section` attribute uses the [MetaNameValueStr] syntax to specify the section name. + +<!-- no_run: don't link. The format of the section name is platform-specific. --> +```rust,no_run +# #[cfg(target_os = "linux")] { +#[unsafe(no_mangle)] +#[unsafe(link_section = ".example_section")] +pub static VAR1: u32 = 1; +# } +``` + +r[abi.link_section.unsafe] +This attribute is unsafe as it allows users to place data and code into sections of memory not expecting them, such as mutable data into read-only areas. + +r[abi.link_section.duplicates] +Only the first use of `link_section` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use following the first with a future-compatibility warning. This may become an error in the future. + +r[abi.link_section.edition2024] +> [!EDITION-2024] +> Before the 2024 edition it is allowed to use the `link_section` attribute without the `unsafe` qualification. + +r[abi.export_name] +## The `export_name` attribute + +r[abi.export_name.intro] +The *`export_name` attribute* specifies the name of the symbol that will be exported on a [function] or [static]. + +r[abi.export_name.syntax] +The `export_name `attribute uses the [MetaNameValueStr] syntax to specify the symbol name. + +```rust +#[unsafe(export_name = "exported_symbol_name")] +pub fn name_in_rust() { } +``` + +r[abi.export_name.unsafe] +This attribute is unsafe as a symbol with a custom name may collide with another symbol with the same name (or with a well-known symbol), leading to undefined behavior. + +r[abi.export_name.duplicates] +Only the first use of `export_name` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use following the first with a future-compatibility warning. This may become an error in the future. + +r[abi.export_name.edition2024] +> [!EDITION-2024] +> Before the 2024 edition it is allowed to use the `export_name` attribute without the `unsafe` qualification. + +[attribute]: attributes.md +[closure]: expr.closure +[extern functions]: items/functions.md#extern-function-qualifier +[external blocks]: items/external-blocks.md +[function]: items/functions.md +[item]: items.md +[`static` items]: items.static +[static]: items/static-items.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/appendices.md b/stdlib/kvlang/reference/rust/reference-repo/src/appendices.md new file mode 100644 index 00000000..28acb81c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/appendices.md @@ -0,0 +1 @@ +# Appendices diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes.md new file mode 100644 index 00000000..7b405a14 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes.md @@ -0,0 +1,368 @@ +r[attributes] +# Attributes + +r[attributes.syntax] +```grammar,attributes +InnerAttribute -> `#` `!` `[` Attr `]` + +OuterAttribute -> `#` `[` Attr `]` + +Attr -> + SimplePath AttrInput? + | `unsafe` `(` SimplePath AttrInput? `)` + +AttrInput -> + DelimTokenTree + | `=` Expression +``` + +r[attributes.intro] +An _attribute_ is a general, free-form metadatum that is interpreted according to name, convention, language, and compiler version. Attributes are modeled on Attributes in [ECMA-335], with the syntax coming from [ECMA-334] \(C#). + +r[attributes.inner] +_Inner attributes_ apply to the form that the attribute is declared within. + +> [!EXAMPLE] +> ```rust +> // General metadata applied to the enclosing module or crate. +> #![crate_type = "lib"] +> +> // Inner attribute applies to the entire function. +> fn some_unused_variables() { +> #![allow(unused_variables)] +> +> let x = (); +> let y = (); +> let z = (); +> } +> ``` + +r[attributes.outer] +_Outer attributes_ apply to the form that follows the attribute. + +> [!EXAMPLE] +> ```rust +> // A function marked as a unit test +> #[test] +> fn test_foo() { +> /* ... */ +> } +> +> // A conditionally-compiled module +> #[cfg(target_os = "linux")] +> mod bar { +> /* ... */ +> } +> +> // A lint attribute used to suppress a warning/error +> #[allow(non_camel_case_types)] +> type int8_t = i8; +> ``` + +r[attributes.input] +The attribute consists of a path to the attribute, followed by an optional delimited token tree whose interpretation is defined by the attribute. Attributes other than macro attributes also allow the input to be an equals sign (`=`) followed by an expression. See the [meta item syntax](#meta-item-attribute-syntax) below for more details. + +r[attributes.safety] +An attribute may be unsafe to apply. To avoid undefined behavior when using these attributes, certain obligations that cannot be checked by the compiler must be met. To assert these have been, the attribute is wrapped in `unsafe(..)`, e.g. `#[unsafe(no_mangle)]`. + +The following attributes are unsafe: + +* [`export_name`] +* [`link_section`] +* [`naked`] +* [`no_mangle`] + +r[attributes.kind] +Attributes can be classified into the following kinds: + +* [Built-in attributes] +* [Proc macro attributes][attribute macros] +* [Derive macro helper attributes] +* [Tool attributes](#tool-attributes) + +r[attributes.allowed-position] +Attributes may be applied to many forms in the language: + +* All [item declarations] accept outer attributes while [external blocks], [functions], [implementations], and [modules] accept inner attributes. +* Most [statements] accept outer attributes (see [Expression Attributes] for limitations on expression statements). +* [Block expressions] accept outer and inner attributes, but only when they are the outer expression of an [expression statement] or the final expression of another block expression. +* [Enum] variants and [struct] and [union] fields accept outer attributes. +* [Match expression arms][match expressions] accept outer attributes. +* [Generic lifetime or type parameter][generics] accept outer attributes. +* Expressions accept outer attributes in limited situations, see [Expression Attributes] for details. +* [Function][functions], [closure] and [function pointer] parameters accept outer attributes. This includes attributes on variadic parameters denoted with `...` in function pointers and [external blocks][variadic functions]. +* [Inline assembly] template strings and operands accept outer attributes. Only certain attributes are accepted semantically; for details, see [asm.attributes.supported-attributes]. + +r[attributes.meta] +## Meta item attribute syntax + +r[attributes.meta.intro] +A "meta item" is the syntax used for the [Attr] rule by most [built-in attributes]. It has the following grammar: + +r[attributes.meta.syntax] +```grammar,attributes +@root MetaItem -> + SimplePath + | SimplePath `=` Expression + | SimplePath `(` MetaSeq? `)` + +MetaSeq -> + MetaItemInner ( `,` MetaItemInner )* `,`? + +MetaItemInner -> + MetaItem + | Expression +``` + +r[attributes.meta.literal-expr] +Expressions in meta items must macro-expand to literal expressions, which must not include integer or float type suffixes. Expressions which are not literal expressions will be syntactically accepted (and can be passed to proc-macros), but will be rejected after parsing. + +r[attributes.meta.order] +Note that if the attribute appears within another macro, it will be expanded after that outer macro. For example, the following code will expand the `Serialize` proc-macro first, which must preserve the `include_str!` call in order for it to be expanded: + +```rust ignore +#[derive(Serialize)] +struct Foo { + #[doc = include_str!("x.md")] + x: u32 +} +``` + +r[attributes.meta.order-macro] +Additionally, macros in attributes will be expanded only after all other attributes applied to the item: + +```rust ignore +#[macro_attr1] // expanded first +#[doc = mac!()] // `mac!` is expanded fourth. +#[macro_attr2] // expanded second +#[derive(MacroDerive1, MacroDerive2)] // expanded third +fn foo() {} +``` + +r[attributes.meta.builtin] +Various built-in attributes use different subsets of the meta item syntax to specify their inputs. The following grammar rules show some commonly used forms: + +r[attributes.meta.builtin-syntax] +```grammar,attributes +@root MetaWord -> + IDENTIFIER + +MetaNameValueStr -> + IDENTIFIER `=` (STRING_LITERAL | RAW_STRING_LITERAL) + +@root MetaListPaths -> + IDENTIFIER `(` ( SimplePath (`,` SimplePath)* `,`? )? `)` + +@root MetaListIdents -> + IDENTIFIER `(` ( IDENTIFIER (`,` IDENTIFIER)* `,`? )? `)` + +@root MetaListNameValueStr -> + IDENTIFIER `(` ( MetaNameValueStr (`,` MetaNameValueStr)* `,`? )? `)` +``` + +Some examples of meta items are: + +Style | Example +------|-------- +[MetaWord] | `no_std` +[MetaNameValueStr] | `doc = "example"` +[MetaListPaths] | `allow(unused, clippy::inline_always)` +[MetaListIdents] | `macro_use(foo, bar)` +[MetaListNameValueStr] | `link(name = "CoreFoundation", kind = "framework")` + +r[attributes.activity] +## Active and inert attributes + +r[attributes.activity.intro] +An attribute is either active or inert. During attribute processing, *active attributes* remove themselves from the form they are on while *inert attributes* stay on. + +The [`cfg`] and [`cfg_attr`] attributes are active. [Attribute macros] are active. All other attributes are inert. + +r[attributes.tool] +## Tool attributes + +r[attributes.tool.intro] +The compiler may allow attributes for external tools where each tool resides in its own module in the [tool prelude]. The first segment of the attribute path is the name of the tool, with one or more additional segments whose interpretation is up to the tool. + +r[attributes.tool.ignored] +When a tool is not in use, the tool's attributes are accepted without a warning. When the tool is in use, the tool is responsible for processing and interpretation of its attributes. + +r[attributes.tool.prelude] +Tool attributes are not available if the [`no_implicit_prelude`] attribute is used. + +```rust +// Tells the rustfmt tool to not format the following element. +#[rustfmt::skip] +struct S { +} + +// Controls the "cyclomatic complexity" threshold for the clippy tool. +#[clippy::cyclomatic_complexity = "100"] +pub fn f() {} +``` + +> [!NOTE] +> `rustc` currently recognizes the tools "clippy", "rustfmt", "diagnostic", "miri", and "rust_analyzer". + +r[attributes.builtin] +## Built-in attributes index + +The following is an index of all built-in attributes. + +- Conditional compilation + - [`cfg`] --- Controls conditional compilation. + - [`cfg_attr`] --- Conditionally includes attributes. + +- Testing + - [`test`] --- Marks a function as a test. + - [`ignore`] --- Disables a test function. + - [`should_panic`] --- Indicates a test should generate a panic. + +- Derive + - [`derive`] --- Automatic trait implementations. + - [`automatically_derived`] --- Marker for implementations created by `derive`. + +- Macros + - [`macro_export`] --- Exports a `macro_rules` macro for cross-crate use. + - [`macro_use`] --- Expands macro visibility, or imports macros from other crates. + - [`proc_macro`] --- Defines a function-like macro. + - [`proc_macro_derive`] --- Defines a derive macro. + - [`proc_macro_attribute`] --- Defines an attribute macro. + +- Diagnostics + - [`allow`], [`expect`], [`warn`], [`deny`], [`forbid`] --- Alters the default lint level. + - [`deprecated`] --- Generates deprecation notices. + - [`must_use`] --- Generates a lint for unused values. + - [`diagnostic::on_unimplemented`] --- Hints the compiler to emit a certain error message if a trait is not implemented. + - [`diagnostic::do_not_recommend`] --- Hints the compiler to not show a certain trait impl in error messages. + +- ABI, linking, symbols, and FFI + - [`link`] --- Specifies a native library to link with an `extern` block. + - [`link_name`] --- Specifies the name of the symbol for functions or statics in an `extern` block. + - [`link_ordinal`] --- Specifies the ordinal of the symbol for functions or statics in an `extern` block. + - [`no_link`] --- Prevents linking an extern crate. + - [`repr`] --- Controls type layout. + - [`crate_type`] --- Specifies the type of crate (library, executable, etc.). + - [`no_main`] --- Disables emitting the `main` symbol. + - [`export_name`] --- Specifies the exported symbol name for a function or static. + - [`link_section`] --- Specifies the section of an object file to use for a function or static. + - [`no_mangle`] --- Disables symbol name encoding. + - [`used`] --- Forces the compiler to keep a static item in the output object file. + - [`crate_name`] --- Specifies the crate name. + +- Code generation + - [`inline`] --- Hint to inline code. + - [`cold`] --- Hint that a function is unlikely to be called. + - [`naked`] --- Prevent the compiler from emitting a function prologue and epilogue. + - [`no_builtins`] --- Disables use of certain built-in functions. + - [`target_feature`] --- Configure platform-specific code generation. + - [`track_caller`] --- Pass the parent call location to `std::panic::Location::caller()`. + - [`instruction_set`] --- Specify the instruction set used to generate a function's code. + +- Documentation + - `doc` --- Specifies documentation. See [The Rustdoc Book] for more information. [Doc comments] are transformed into `doc` attributes. + +- Preludes + - [`no_std`] --- Removes std from the prelude. + - [`no_implicit_prelude`] --- Disables prelude lookups within a module. + +- Modules + - [`path`] --- Specifies the filename for a module. + +- Limits + - [`recursion_limit`] --- Sets the maximum recursion limit for certain compile-time operations. + - [`type_length_limit`] --- Sets the maximum size of a polymorphic type. + +- Runtime + - [`panic_handler`] --- Sets the function to handle panics. + - [`global_allocator`] --- Sets the global memory allocator. + - [`windows_subsystem`] --- Specifies the windows subsystem to link with. + +- Features + - `feature` --- Used to enable unstable or experimental compiler features. See [The Unstable Book] for features implemented in `rustc`. + +- Type System + - [`non_exhaustive`] --- Indicate that a type will have more fields/variants added in future. + +- Debugger + - [`debugger_visualizer`] --- Embeds a file that specifies debugger output for a type. + - [`collapse_debuginfo`] --- Controls how macro invocations are encoded in debuginfo. + +[Doc comments]: comments.md#doc-comments +[ECMA-334]: https://www.ecma-international.org/publications-and-standards/standards/ecma-334/ +[ECMA-335]: https://www.ecma-international.org/publications-and-standards/standards/ecma-335/ +[Expression Attributes]: expressions.md#expression-attributes +[The Rustdoc Book]: ../rustdoc/the-doc-attribute.html +[The Unstable Book]: ../unstable-book/index.html +[`allow`]: attributes/diagnostics.md#lint-check-attributes +[`automatically_derived`]: attributes/derive.md#the-automatically_derived-attribute +[`cfg_attr`]: conditional-compilation.md#the-cfg_attr-attribute +[`cfg`]: conditional-compilation.md#the-cfg-attribute +[`cold`]: attributes/codegen.md#the-cold-attribute +[`collapse_debuginfo`]: attributes/debugger.md#the-collapse_debuginfo-attribute +[`crate_name`]: crates-and-source-files.md#the-crate_name-attribute +[`crate_type`]: linkage.md +[`debugger_visualizer`]: attributes/debugger.md#the-debugger_visualizer-attribute +[`deny`]: attributes/diagnostics.md#lint-check-attributes +[`deprecated`]: attributes/diagnostics.md#the-deprecated-attribute +[`derive`]: attributes/derive.md +[`export_name`]: abi.md#the-export_name-attribute +[`expect`]: attributes/diagnostics.md#lint-check-attributes +[`forbid`]: attributes/diagnostics.md#lint-check-attributes +[`global_allocator`]: runtime.md#the-global_allocator-attribute +[`ignore`]: attributes/testing.md#the-ignore-attribute +[`inline`]: attributes/codegen.md#the-inline-attribute +[`instruction_set`]: attributes/codegen.md#the-instruction_set-attribute +[`link_name`]: items/external-blocks.md#the-link_name-attribute +[`link_ordinal`]: items/external-blocks.md#the-link_ordinal-attribute +[`link_section`]: abi.md#the-link_section-attribute +[`link`]: items/external-blocks.md#the-link-attribute +[`macro_export`]: macros-by-example.md#the-macro_export-attribute +[`macro_use`]: macros-by-example.md#the-macro_use-attribute +[`must_use`]: attributes/diagnostics.md#the-must_use-attribute +[`naked`]: attributes/codegen.md#the-naked-attribute +[`no_builtins`]: attributes/codegen.md#the-no_builtins-attribute +[`no_implicit_prelude`]: names/preludes.md#the-no_implicit_prelude-attribute +[`no_link`]: items/extern-crates.md#the-no_link-attribute +[`no_main`]: crates-and-source-files.md#the-no_main-attribute +[`no_mangle`]: abi.md#the-no_mangle-attribute +[`no_std`]: names/preludes.md#the-no_std-attribute +[`non_exhaustive`]: attributes/type_system.md#the-non_exhaustive-attribute +[`panic_handler`]: panic.md#the-panic_handler-attribute +[`path`]: items/modules.md#the-path-attribute +[`proc_macro_attribute`]: procedural-macros.md#the-proc_macro_attribute-attribute +[`proc_macro_derive`]: macro.proc.derive +[`proc_macro`]: procedural-macros.md#the-proc_macro-attribute +[`recursion_limit`]: attributes/limits.md#the-recursion_limit-attribute +[`repr`]: type-layout.md#representations +[`should_panic`]: attributes/testing.md#the-should_panic-attribute +[`target_feature`]: attributes/codegen.md#the-target_feature-attribute +[`test`]: attributes/testing.md#the-test-attribute +[`track_caller`]: attributes/codegen.md#the-track_caller-attribute +[`type_length_limit`]: attributes/limits.md#the-type_length_limit-attribute +[`used`]: abi.md#the-used-attribute +[`warn`]: attributes/diagnostics.md#lint-check-attributes +[`windows_subsystem`]: runtime.md#the-windows_subsystem-attribute +[attribute macros]: procedural-macros.md#the-proc_macro_attribute-attribute +[block expressions]: expressions/block-expr.md +[built-in attributes]: #built-in-attributes-index +[derive macro helper attributes]: procedural-macros.md#derive-macro-helper-attributes +[enum]: items/enumerations.md +[expression statement]: statements.md#expression-statements +[external blocks]: items/external-blocks.md +[functions]: items/functions.md +[generics]: items/generics.md +[implementations]: items/implementations.md +[item declarations]: items.md +[match expressions]: expressions/match-expr.md +[modules]: items/modules.md +[statements]: statements.md +[struct]: items/structs.md +[tool prelude]: names/preludes.md#tool-prelude +[union]: items/unions.md +[closure]: expressions/closure-expr.md +[function pointer]: types/function-pointer.md +[variadic functions]: items/external-blocks.html#variadic-functions +[`diagnostic::on_unimplemented`]: attributes/diagnostics.md#the-diagnosticon_unimplemented-attribute +[`diagnostic::do_not_recommend`]: attributes/diagnostics.md#the-diagnosticdo_not_recommend-attribute +[Inline assembly]: inline-assembly.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes/codegen.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/codegen.md new file mode 100644 index 00000000..b1a79f3e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/codegen.md @@ -0,0 +1,940 @@ +r[attributes.codegen] +# Code generation attributes + +r[attributes.codegen.intro] +The following [attributes] are used for controlling code generation. + +<!-- template:attributes --> +r[attributes.codegen.inline] +### The `inline` attribute + +r[attributes.codegen.inline.intro] +The *`inline` [attribute]* suggests whether a copy of the attributed function's code should be placed in the caller rather than generating a call to the function. + +> [!EXAMPLE] +> ```rust +> #[inline] +> pub fn example1() {} +> +> #[inline(always)] +> pub fn example2() {} +> +> #[inline(never)] +> pub fn example3() {} +> ``` + +> [!NOTE] +> `rustc` automatically inlines functions when doing so seems worthwhile. Use this attribute carefully as poor decisions about what to inline can slow down programs. + +r[attributes.codegen.inline.syntax] +The syntax for the `inline` attribute is: + +```grammar,attributes +@root InlineAttribute -> + `inline` `(` `always` `)` + | `inline` `(` `never` `)` + | `inline` +``` + +r[attributes.codegen.inline.allowed-positions] +The `inline` attribute may only be applied to functions with [bodies] --- [closures], [async blocks], [free functions], [associated functions] in an [inherent impl] or [trait impl], and associated functions in a [trait definition] when those functions have a [default definition] . + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +> [!NOTE] +> Though the attribute can be applied to [closures] and [async blocks], the usefulness of this is limited as we do not yet support attributes on expressions. +> +> ```rust +> // We allow attributes on statements. +> #[inline] || (); // OK +> #[inline] async {}; // OK +> ``` +> +> ```rust,compile_fail,E0658 +> // We don't yet allow attributes on expressions. +> let f = #[inline] || (); // ERROR +> ``` + +r[attributes.codegen.inline.duplicates] +Only the first use of `inline` on a function has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +r[attributes.codegen.inline.modes] +The `inline` attribute supports these modes: + +- `#[inline]` *suggests* performing inline expansion. +- `#[inline(always)]` *suggests* that inline expansion should always be performed. +- `#[inline(never)]` *suggests* that inline expansion should never be performed. + +> [!NOTE] +> In every form the attribute is a hint. The compiler may ignore it. + +r[attributes.codegen.inline.trait] +When `inline` is applied to a function in a [trait], it applies only to the code of the [default definition]. + +r[attributes.codegen.inline.async] +When `inline` is applied to an [async function] or [async closure], it applies only to the code of the generated `poll` function. + +> [!NOTE] +> For more details, see [Rust issue #129347](https://github.com/rust-lang/rust/issues/129347). + +r[attributes.codegen.inline.externally-exported] +The `inline` attribute is ignored if the function is externally exported with [`no_mangle`] or [`export_name`]. + +<!-- template:attributes --> +r[attributes.codegen.cold] +### The `cold` attribute + +r[attributes.codegen.cold.intro] +The *`cold` [attribute]* suggests that the attributed function is unlikely to be called which may help the compiler produce better code. + +> [!EXAMPLE] +> ```rust +> #[cold] +> pub fn example() {} +> ``` + +r[attributes.codegen.cold.syntax] +The `cold` attribute uses the [MetaWord] syntax. + +r[attributes.codegen.cold.allowed-positions] +The `cold` attribute may only be applied to functions with [bodies] --- [closures], [async blocks], [free functions], [associated functions] in an [inherent impl] or [trait impl], and associated functions in a [trait definition] when those functions have a [default definition] . + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +> [!NOTE] +> Though the attribute can be applied to [closures] and [async blocks], the usefulness of this is limited as we do not yet support attributes on expressions. + +<!-- TODO: rustc currently seems to allow cold on a trait function without a body, but it appears to be ignored. I think that may be a bug, and it should at least warn if not reject (like inline does). --> + +r[attributes.codegen.cold.extern-custom] +The `cold` attribute may not be applied to an [`extern "custom"` function]. + +```rust,compile_fail +#[cold] // ERROR: Not allowed. +#[unsafe(naked)] +unsafe extern "custom" fn f() { + core::arch::naked_asm!("ret") +} +``` + +r[attributes.codegen.cold.duplicates] +Only the first use of `cold` on a function has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +r[attributes.codegen.cold.trait] +When `cold` is applied to a function in a [trait], it applies only to the code of the [default definition]. + +<!-- template:attributes --> +r[attributes.codegen.naked] +## The `naked` attribute + +r[attributes.codegen.naked.intro] +The *`naked` [attribute]* prevents the compiler from emitting a function prologue and epilogue for the attributed function --- a *naked function*. + +> [!EXAMPLE] +> ```rust +> # #[cfg(target_arch = "x86_64")] { +> /// Adds 3 to the given number. +> // SAFETY: The body respects the "sysv64" calling convention, +> // upholds the signature, and does not fall through. +> #[unsafe(naked)] +> pub extern "sysv64" fn add_n(number: u64) -> u64 { +> core::arch::naked_asm!( +> "add rdi, {}", +> "mov rax, rdi", +> "ret", +> const 3, +> ) +> } +> # } +> ``` + +> [!NOTE] +> The assembly code of a naked function often does not follow the calling convention of any ABI known to the compiler. Such a function should be declared as an [`extern "custom"` function][items.fn.extern.custom]. + +r[attributes.codegen.naked.syntax] +The `naked` attribute uses the [MetaWord] syntax. + +r[attributes.codegen.naked.allowed-positions] +The `naked` attribute may only be applied to [free functions], [associated functions] in an [inherent impl] or [trait impl], and associated functions in a [trait definition] when those functions have a [default definition]. + +r[attributes.codegen.naked.duplicates] +Only the first use of `naked` on a function has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[attributes.codegen.naked.unsafe] +The `naked` attribute must be marked with [`unsafe`][attributes.safety] because the body must respect the function's calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code). + +r[attributes.codegen.naked.body] +The [function body] must consist of exactly one [`naked_asm!`] macro invocation. + +r[attributes.codegen.naked.prologue-epilogue] +The compiler emits no prologue or epilogue for a naked function: the assembly code in the [`naked_asm!`] invocation constitutes its entire body. + +r[attributes.codegen.naked.call-stack] +On entry the assembly code may assume that the call stack and register state are valid per the function's signature and calling convention. + +r[attributes.codegen.naked.no-duplication] +The compiler may not duplicate the assembly code except when monomorphizing a polymorphic function. + +> [!NOTE] +> This guarantee matters for naked functions that define symbols. + +r[attributes.codegen.naked.unused-variables] +The [`unused_variables` lint] is suppressed in naked functions. + +r[attributes.codegen.naked.inline] +The [`inline` attribute] cannot be applied to a naked function. + +r[attributes.codegen.naked.track_caller] +The [`track_caller` attribute] cannot be applied to a naked function. + +r[attributes.codegen.naked.testing] +The [testing attributes] cannot be applied to a naked function. + +r[attributes.codegen.naked.target_feature] +The [`target_feature` attribute] cannot be applied to a naked function. + +<!-- TODO: Reflexive rules? --> + +r[attributes.codegen.naked.abi] +A naked function cannot use the ["Rust" ABI]. + +<!-- template:attributes --> +r[attributes.codegen.no_builtins] +## The `no_builtins` attribute + +r[attributes.codegen.no_builtins.intro] +The *`no_builtins` [attribute]* disables optimization of certain code patterns related to calls to library functions that are assumed to exist. + +<!-- TODO: This needs expanding, see <https://github.com/rust-lang/reference/issues/542>. --> + +> [!EXAMPLE] +> ```rust +> #![no_builtins] +> ``` + +r[attributes.codegen.no_builtins.syntax] +The `no_builtins` attribute uses the [MetaWord] syntax. + +r[attributes.codegen.no_builtins.allowed-positions] +The `no_builtins` attribute can only be applied to the crate root. + +r[attributes.codegen.no_builtins.duplicates] +Only the first use of the `no_builtins` attribute has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[attributes.codegen.target_feature] +## The `target_feature` attribute + +r[attributes.codegen.target_feature.intro] +The *`target_feature` [attribute]* may be applied to a function to +enable code generation of that function for specific platform architecture +features. It uses the [MetaListNameValueStr] syntax with a single key of +`enable` whose value is a string of comma-separated feature names to enable. + +```rust +# #[cfg(target_feature = "avx2")] +#[target_feature(enable = "avx2")] +fn foo_avx2() {} +``` + +r[attributes.codegen.target_feature.arch] +Each [target architecture] has a set of features that may be enabled. It is an +error to specify a feature for a target architecture that the crate is not +being compiled for. + +r[attributes.codegen.target_feature.closures] +Closures defined within a `target_feature`-annotated function inherit the +attribute from the enclosing function. + +r[attributes.codegen.target_feature.target-ub] +It is [undefined behavior] to call a function that is compiled with a feature +that is not supported on the current platform the code is running on, *except* +if the platform explicitly documents this to be safe. + +r[attributes.codegen.target_feature.safety-restrictions] +The following restrictions apply unless otherwise specified by the platform rules below: + +- Safe `#[target_feature]` functions (and closures that inherit the attribute) can only be safely called within a caller that enables all the `target_feature`s that the callee enables. + This restriction does not apply in an `unsafe` context. +- Safe `#[target_feature]` functions (and closures that inherit the attribute) can only be coerced to *safe* function pointers in contexts that enable all the `target_feature`s that the coercee enables. + This restriction does not apply to `unsafe` function pointers. + +Implicitly enabled features are included in this rule. For example an `sse2` function can call ones marked with `sse`. + +```rust +# #[cfg(target_feature = "sse2")] { +#[target_feature(enable = "sse")] +fn foo_sse() {} + +fn bar() { + // Calling `foo_sse` here is unsafe, as we must ensure that SSE is + // available first, even if `sse` is enabled by default on the target + // platform or manually enabled as compiler flags. + unsafe { + foo_sse(); + } +} + +#[target_feature(enable = "sse")] +fn bar_sse() { + // Calling `foo_sse` here is safe. + foo_sse(); + || foo_sse(); +} + +#[target_feature(enable = "sse2")] +fn bar_sse2() { + // Calling `foo_sse` here is safe because `sse2` implies `sse`. + foo_sse(); +} +# } +``` + +r[attributes.codegen.target_feature.fn-traits] +A function with a `#[target_feature]` attribute *never* implements the `Fn` family of traits, although closures inheriting features from the enclosing function do. + +r[attributes.codegen.target_feature.allowed-positions] +The `#[target_feature]` attribute is not allowed on the following places: + +- [the `main` function][crate.main] +- a [`panic_handler` function][panic.panic_handler] +- safe trait methods +- safe default functions in traits + +r[attributes.codegen.target_feature.inline] +Functions marked with `target_feature` are not inlined into a context that +does not support the given features. The `#[inline(always)]` attribute may not +be used with a `target_feature` attribute. + +r[attributes.codegen.target_feature.availability] +### Available features + +The following is a list of the available feature names. + +r[attributes.codegen.target_feature.x86] +#### `x86` or `x86_64` + +Executing code with unsupported features is undefined behavior on this platform. +Hence on this platform use of `#[target_feature]` functions follows the +[above restrictions][attributes.codegen.target_feature.safety-restrictions]. + +Feature | Implicitly Enables | Description +------------|--------------------|------------------- +`adx` | | [ADX] --- Multi-Precision Add-Carry Instruction Extensions +`aes` | `sse2` | [AES] --- Advanced Encryption Standard +`avx` | `sse4.2` | [AVX] --- Advanced Vector Extensions +`avx2` | `avx` | [AVX2] --- Advanced Vector Extensions 2 +`avx512bf16` | `avx512bw` | [AVX512-BF16] --- Advanced Vector Extensions 512-bit - Bfloat16 Extensions +`avx512bitalg` | `avx512bw` | [AVX512-BITALG] --- Advanced Vector Extensions 512-bit - Bit Algorithms +`avx512bw` | `avx512f` | [AVX512-BW] --- Advanced Vector Extensions 512-bit - Byte and Word Instructions +`avx512cd` | `avx512f` | [AVX512-CD] --- Advanced Vector Extensions 512-bit - Conflict Detection Instructions +`avx512dq` | `avx512f` | [AVX512-DQ] --- Advanced Vector Extensions 512-bit - Doubleword and Quadword Instructions +`avx512f` | `avx2`, `fma`, `f16c`| [AVX512-F] --- Advanced Vector Extensions 512-bit - Foundation +`avx512fp16` | `avx512bw` | [AVX512-FP16] --- Advanced Vector Extensions 512-bit - Float16 Extensions +`avx512ifma` | `avx512f` | [AVX512-IFMA] --- Advanced Vector Extensions 512-bit - Integer Fused Multiply Add +`avx512vbmi` | `avx512bw` | [AVX512-VBMI] --- Advanced Vector Extensions 512-bit - Vector Byte Manipulation Instructions +`avx512vbmi2` | `avx512bw` | [AVX512-VBMI2] --- Advanced Vector Extensions 512-bit - Vector Byte Manipulation Instructions 2 +`avx512vl` | `avx512f` | [AVX512-VL] --- Advanced Vector Extensions 512-bit - Vector Length Extensions +`avx512vnni` | `avx512f` | [AVX512-VNNI] --- Advanced Vector Extensions 512-bit - Vector Neural Network Instructions +`avx512vp2intersect`| `avx512f` | [AVX512-VP2INTERSECT] --- Advanced Vector Extensions 512-bit - Vector Pair Intersection to a Pair of Mask Registers +`avx512vpopcntdq` | `avx512f` | [AVX512-VPOPCNTDQ] --- Advanced Vector Extensions 512-bit - Vector Population Count Instruction +`avxifma` | `avx2` | [AVX-IFMA] --- Advanced Vector Extensions - Integer Fused Multiply Add +`avxneconvert` | `avx2` | [AVX-NE-CONVERT] --- Advanced Vector Extensions - No-Exception Floating-Point conversion Instructions +`avxvnni` | `avx2` | [AVX-VNNI] --- Advanced Vector Extensions - Vector Neural Network Instructions +`avxvnniint16` | `avx2` | [AVX-VNNI-INT16] --- Advanced Vector Extensions - Vector Neural Network Instructions with 16-bit Integers +`avxvnniint8` | `avx2` | [AVX-VNNI-INT8] --- Advanced Vector Extensions - Vector Neural Network Instructions with 8-bit Integers +`bmi1` | | [BMI1] --- Bit Manipulation Instruction Sets +`bmi2` | | [BMI2] --- Bit Manipulation Instruction Sets 2 +`cmpxchg16b`| | [`cmpxchg16b`] --- Compares and exchange 16 bytes (128 bits) of data atomically +`f16c` | `avx` | [F16C] --- 16-bit floating point conversion instructions +`fma` | `avx` | [FMA3] --- Three-operand fused multiply-add +`fxsr` | | [`fxsave`] and [`fxrstor`] --- Save and restore x87 FPU, MMX Technology, and SSE State +`gfni` | `sse2` | [GFNI] --- Galois Field New Instructions +`kl` | `sse2` | [KEYLOCKER] --- Intel Key Locker Instructions +`lzcnt` | | [`lzcnt`] --- Leading zeros count +`movbe` | | [`movbe`] --- Move data after swapping bytes +`pclmulqdq` | `sse2` | [`pclmulqdq`] --- Packed carry-less multiplication quadword +`popcnt` | | [`popcnt`] --- Count of bits set to 1 +`rdrand` | | [`rdrand`] --- Read random number +`rdseed` | | [`rdseed`] --- Read random seed +`sha` | `sse2` | [SHA] --- Secure Hash Algorithm +`sha512` | `avx2` | [SHA512] --- Secure Hash Algorithm with 512-bit digest +`sm3` | `avx` | [SM3] --- ShangMi 3 Hash Algorithm +`sm4` | `avx2` | [SM4] --- ShangMi 4 Cipher Algorithm +`sse` | | [SSE] --- Streaming <abbr title="Single Instruction Multiple Data">SIMD</abbr> Extensions +`sse2` | `sse` | [SSE2] --- Streaming SIMD Extensions 2 +`sse3` | `sse2` | [SSE3] --- Streaming SIMD Extensions 3 +`sse4.1` | `ssse3` | [SSE4.1] --- Streaming SIMD Extensions 4.1 +`sse4.2` | `sse4.1` | [SSE4.2] --- Streaming SIMD Extensions 4.2 +`sse4a` | `sse3` | [SSE4a] --- Streaming SIMD Extensions 4a +`ssse3` | `sse3` | [SSSE3] --- Supplemental Streaming SIMD Extensions 3 +`tbm` | | [TBM] --- Trailing Bit Manipulation +`vaes` | `avx2`, `aes` | [VAES] --- Vector AES Instructions +`vpclmulqdq`| `avx`, `pclmulqdq`| [VPCLMULQDQ] --- Vector Carry-less multiplication of Quadwords +`widekl` | `kl` | [KEYLOCKER_WIDE] --- Intel Wide Keylocker Instructions +`xsave` | | [`xsave`] --- Save processor extended states +`xsavec` | | [`xsavec`] --- Save processor extended states with compaction +`xsaveopt` | | [`xsaveopt`] --- Save processor extended states optimized +`xsaves` | | [`xsaves`] --- Save processor extended states supervisor + +<!-- Keep links near each table to make it easier to move and update. --> + +[ADX]: https://en.wikipedia.org/wiki/Intel_ADX +[AES]: https://en.wikipedia.org/wiki/AES_instruction_set +[AVX]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions +[AVX2]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX2 +[AVX512-BF16]: https://en.wikipedia.org/wiki/AVX-512#BF16 +[AVX512-BITALG]: https://en.wikipedia.org/wiki/AVX-512#VPOPCNTDQ_and_BITALG +[AVX512-BW]: https://en.wikipedia.org/wiki/AVX-512#BW,_DQ_and_VBMI +[AVX512-CD]: https://en.wikipedia.org/wiki/AVX-512#Conflict_detection +[AVX512-DQ]: https://en.wikipedia.org/wiki/AVX-512#BW,_DQ_and_VBMI +[AVX512-F]: https://en.wikipedia.org/wiki/AVX-512 +[AVX512-FP16]: https://en.wikipedia.org/wiki/AVX-512#FP16 +[AVX512-IFMA]: https://en.wikipedia.org/wiki/AVX-512#IFMA +[AVX512-VBMI]: https://en.wikipedia.org/wiki/AVX-512#BW,_DQ_and_VBMI +[AVX512-VBMI2]: https://en.wikipedia.org/wiki/AVX-512#VBMI2 +[AVX512-VL]: https://en.wikipedia.org/wiki/AVX-512 +[AVX512-VNNI]: https://en.wikipedia.org/wiki/AVX-512#VNNI +[AVX512-VP2INTERSECT]: https://en.wikipedia.org/wiki/AVX-512#VP2INTERSECT +[AVX512-VPOPCNTDQ]:https://en.wikipedia.org/wiki/AVX-512#VPOPCNTDQ_and_BITALG +[AVX-IFMA]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX-VNNI,_AVX-IFMA +[AVX-NE-CONVERT]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX-VNNI,_AVX-IFMA +[AVX-VNNI]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX-VNNI,_AVX-IFMA +[AVX-VNNI-INT16]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX-VNNI,_AVX-IFMA +[AVX-VNNI-INT8]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX-VNNI,_AVX-IFMA +[BMI1]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets +[BMI2]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#BMI2 +[`cmpxchg16b`]: https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b +[F16C]: https://en.wikipedia.org/wiki/F16C +[FMA3]: https://en.wikipedia.org/wiki/FMA_instruction_set +[`fxsave`]: https://www.felixcloutier.com/x86/fxsave +[`fxrstor`]: https://www.felixcloutier.com/x86/fxrstor +[GFNI]: https://en.wikipedia.org/wiki/AVX-512#GFNI +[KEYLOCKER]: https://en.wikipedia.org/wiki/List_of_x86_cryptographic_instructions#Intel_Key_Locker_instructions +[KEYLOCKER_WIDE]: https://en.wikipedia.org/wiki/List_of_x86_cryptographic_instructions#Intel_Key_Locker_instructions +[`lzcnt`]: https://www.felixcloutier.com/x86/lzcnt +[`movbe`]: https://www.felixcloutier.com/x86/movbe +[`pclmulqdq`]: https://www.felixcloutier.com/x86/pclmulqdq +[`popcnt`]: https://www.felixcloutier.com/x86/popcnt +[`rdrand`]: https://en.wikipedia.org/wiki/RdRand +[`rdseed`]: https://en.wikipedia.org/wiki/RdRand +[SHA]: https://en.wikipedia.org/wiki/Intel_SHA_extensions +[SHA512]: https://en.wikipedia.org/wiki/Intel_SHA_extensions +[SM3]: https://en.wikipedia.org/wiki/List_of_x86_cryptographic_instructions#Intel_SHA_and_SM3_instructions +[SM4]: https://en.wikipedia.org/wiki/List_of_x86_cryptographic_instructions#Intel_SHA_and_SM3_instructions +[SSE]: https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions +[SSE2]: https://en.wikipedia.org/wiki/SSE2 +[SSE3]: https://en.wikipedia.org/wiki/SSE3 +[SSE4.1]: https://en.wikipedia.org/wiki/SSE4#SSE4.1 +[SSE4.2]: https://en.wikipedia.org/wiki/SSE4#SSE4.2 +[SSE4a]: https://en.wikipedia.org/wiki/SSE4#SSE4a +[SSSE3]: https://en.wikipedia.org/wiki/SSSE3 +[TBM]: https://en.wikipedia.org/wiki/X86_Bit_manipulation_instruction_set#TBM_(Trailing_Bit_Manipulation) +[VAES]: https://en.wikipedia.org/wiki/AVX-512#VAES +[VPCLMULQDQ]: https://en.wikipedia.org/wiki/AVX-512#VPCLMULQDQ +[`xsave`]: https://www.felixcloutier.com/x86/xsave +[`xsavec`]: https://www.felixcloutier.com/x86/xsavec +[`xsaveopt`]: https://www.felixcloutier.com/x86/xsaveopt +[`xsaves`]: https://www.felixcloutier.com/x86/xsaves + +r[attributes.codegen.target_feature.aarch64] +#### `aarch64` + +On this platform the use of `#[target_feature]` functions follows the +[above restrictions][attributes.codegen.target_feature.safety-restrictions]. + +Further documentation on these features can be found in the [ARM Architecture +Reference Manual], or elsewhere on [developer.arm.com]. + +[ARM Architecture Reference Manual]: https://developer.arm.com/documentation/ddi0487/latest +[developer.arm.com]: https://developer.arm.com + +> [!NOTE] +> The following pairs of features should both be marked as enabled or disabled together if used: +> - `paca` and `pacg`, which LLVM currently implements as one feature. + +Feature | Implicitly Enables | Feature Name +------- | ------------------ | ------------ +`aes` | `neon` | FEAT_AES & FEAT_PMULL --- Advanced <abbr title="Single Instruction Multiple Data">SIMD</abbr> AES & PMULL instructions +`bf16` | | FEAT_BF16 --- BFloat16 instructions +`bti` | | FEAT_BTI --- Branch Target Identification +`crc` | | FEAT_CRC --- CRC32 checksum instructions +`dit` | | FEAT_DIT --- Data Independent Timing instructions +`dotprod` | `neon` | FEAT_DotProd --- Advanced SIMD Int8 dot product instructions +`dpb` | | FEAT_DPB --- Data cache clean to point of persistence +`dpb2` | `dpb` | FEAT_DPB2 --- Data cache clean to point of deep persistence +`f32mm` | `sve` | FEAT_F32MM --- SVE single-precision FP matrix multiply instruction +`f64mm` | `sve` | FEAT_F64MM --- SVE double-precision FP matrix multiply instruction +`fcma` | `neon` | FEAT_FCMA --- Floating point complex number support +`fhm` | `fp16` | FEAT_FHM --- Half-precision FP FMLAL instructions +`flagm` | | FEAT_FLAGM --- Conditional flag manipulation +`fp16` | `neon` | FEAT_FP16 --- Half-precision FP data processing +`frintts` | | FEAT_FRINTTS --- Floating-point to int helper instructions +`i8mm` | | FEAT_I8MM --- Int8 Matrix Multiplication +`jsconv` | `neon` | FEAT_JSCVT --- JavaScript conversion instruction +`lor` | | FEAT_LOR --- Limited Ordering Regions extension +`lse` | | FEAT_LSE --- Large System Extensions +`mte` | | FEAT_MTE & FEAT_MTE2 --- Memory Tagging Extension +`neon` | | FEAT_AdvSimd & FEAT_FP --- Floating Point and Advanced SIMD extension +`paca` | | FEAT_PAUTH --- Pointer Authentication (address authentication) +`pacg` | | FEAT_PAUTH --- Pointer Authentication (generic authentication) +`pan` | | FEAT_PAN --- Privileged Access-Never extension +`pmuv3` | | FEAT_PMUv3 --- Performance Monitors extension (v3) +`rand` | | FEAT_RNG --- Random Number Generator +`ras` | | FEAT_RAS & FEAT_RASv1p1 --- Reliability, Availability and Serviceability extension +`rcpc` | | FEAT_LRCPC --- Release consistent Processor Consistent +`rcpc2` | `rcpc` | FEAT_LRCPC2 --- RcPc with immediate offsets +`rdm` | `neon` | FEAT_RDM --- Rounding Double Multiply accumulate +`sb` | | FEAT_SB --- Speculation Barrier +`sha2` | `neon` | FEAT_SHA1 & FEAT_SHA256 --- Advanced SIMD SHA instructions +`sha3` | `sha2` | FEAT_SHA512 & FEAT_SHA3 --- Advanced SIMD SHA instructions +`sm4` | `neon` | FEAT_SM3 & FEAT_SM4 --- Advanced SIMD SM3/4 instructions +`spe` | | FEAT_SPE --- Statistical Profiling Extension +`ssbs` | | FEAT_SSBS & FEAT_SSBS2 --- Speculative Store Bypass Safe +`sve` | `neon` | FEAT_SVE --- Scalable Vector Extension +`sve2` | `sve` | FEAT_SVE2 --- Scalable Vector Extension 2 +`sve2-aes` | `sve2`, `aes` | FEAT_SVE_AES & FEAT_SVE_PMULL128 --- SVE AES instructions +`sve2-bitperm` | `sve2` | FEAT_SVE2_BitPerm --- SVE Bit Permute +`sve2-sha3` | `sve2`, `sha3` | FEAT_SVE2_SHA3 --- SVE SHA3 instructions +`sve2-sm4` | `sve2`, `sm4` | FEAT_SVE2_SM4 --- SVE SM4 instructions +`tme` | | FEAT_TME --- Transactional Memory Extension +`vh` | | FEAT_VHE --- Virtualization Host Extensions + +r[attributes.codegen.target_feature.loongarch] +#### `loongarch` + +On this platform the use of `#[target_feature]` functions follows the +[above restrictions][attributes.codegen.target_feature.safety-restrictions]. + +Feature | Implicitly Enables | Description +------------|---------------------|------------------- +`f` | | [F][la-f] --- Single-precision float-point instructions +`d` | `f` | [D][la-d] --- Double-precision float-point instructions +`frecipe` | | [FRECIPE][la-frecipe] --- Reciprocal approximation instructions +`lasx` | `lsx` | [LASX][la-lasx] --- 256-bit vector instructions +`lbt` | | [LBT][la-lbt] --- Binary translation instructions +`lsx` | `d` | [LSX][la-lsx] --- 128-bit vector instructions +`lvz` | | [LVZ][la-lvz] --- Virtualization instructions +`div32` | | [DIV32][la-div32] --- Division instructions accepting non-sign-extended 32-bit operands +`lam-bh` | | [LAM-BH][la-lam-bh] --- Atomic swap and add instructions for byte and halfword +`lamcas` | | [LAMCAS][la-lamcas] --- Atomic compare-and-swap instructions for byte, halfword, word, and doubleword +`ld-seq-sa` | | [LD-SEQ-SA][la-ld-seq-sa] --- Sequential ordering of load operations to the same address +`scq` | | [SCQ][la-scq] --- Store-conditional quadword instructions + +<!-- Keep links near each table to make it easier to move and update. --> + +[la-f]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-fp_sp +[la-d]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-fp_dp +[la-frecipe]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-frecipe +[la-lasx]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-lasx +[la-lbt]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-lbt_x86 +[la-lsx]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-lsx +[la-lvz]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-lvz +[la-div32]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-div32 +[la-lam-bh]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-lam_bh +[la-lamcas]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-lamcas +[la-ld-seq-sa]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-ld_seq_sa +[la-scq]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#cpucfg-scq + +r[attributes.codegen.target_feature.riscv] +#### `riscv32` or `riscv64` + +On this platform the use of `#[target_feature]` functions follows the +[above restrictions][attributes.codegen.target_feature.safety-restrictions]. + +Further documentation on these features can be found in their respective +specification. Many specifications are described in the [RISC-V ISA Manual], +[version 20250508], or in another manual hosted on the [RISC-V GitHub Account]. + +[RISC-V ISA Manual]: https://github.com/riscv/riscv-isa-manual +[version 20250508]: https://github.com/riscv/riscv-isa-manual/tree/20250508 +[RISC-V GitHub Account]: https://github.com/riscv + +Feature | Implicitly Enables | Description +------------|---------------------|------------------- +`a` | `zaamo`, `zalrsc` | [A][rv-a] --- Atomic instructions +`b` | `zba`, `zbc`, `zbs` | [B][rv-b] --- Bit Manipulation instructions +`c` | `zca` | [C][rv-c] --- Compressed instructions +`m` | | [M][rv-m] --- Integer Multiplication and Division instructions +`za64rs` | `za128rs` | [Za64rs][rv-za64rs] --- Platform Behavior: Naturally aligned Reservation sets with ≦ 64 Bytes +`za128rs` | | [Za128rs][rv-za128rs] --- Platform Behavior: Naturally aligned Reservation sets with ≦ 128 Bytes +`zaamo` | | [Zaamo][rv-zaamo] --- Atomic Memory Operation instructions +`zabha` | `zaamo` | [Zabha][rv-zabha] --- Byte and Halfword Atomic Memory Operation instructions +`zacas` | `zaamo` | [Zacas][rv-zacas] --- Atomic Compare-and-Swap (CAS) instructions +`zalrsc` | | [Zalrsc][rv-zalrsc] --- Load-Reserved/Store-Conditional instructions +`zama16b` | | [Zama16b][rv-zama16b] --- Platform Behavior: Misaligned loads, stores, and AMOs to main memory regions that do not cross a naturally aligned 16-byte boundary are atomic +`zawrs` | | [Zawrs][rv-zawrs] --- Wait-on-Reservation-Set instructions +`zba` | | [Zba][rv-zba] --- Address Generation instructions +`zbb` | | [Zbb][rv-zbb] --- Basic bit-manipulation +`zbc` | `zbkc` | [Zbc][rv-zbc] --- Carry-less multiplication +`zbkb` | | [Zbkb][rv-zbkb] --- Bit Manipulation Instructions for Cryptography +`zbkc` | | [Zbkc][rv-zbkc] --- Carry-less multiplication for Cryptography +`zbkx` | | [Zbkx][rv-zbkx] --- Crossbar permutations +`zbs` | | [Zbs][rv-zbs] --- Single-bit instructions +`zca` | | [Zca][rv-zca] --- Compressed instructions: integer part subset +`zcb` | `zca` | [Zcb][rv-zcb] --- Simple Code-size Saving Compressed instructions +`zcmop` | `zca` | [Zcmop][rv-zcmop] --- Compressed May-Be-Operations +`zic64b` | | [Zic64b][rv-zic64b] --- Platform Behavior: Naturally aligned 64 byte Cache blocks +`zicbom` | | [Zicbom][rv-zicbom] --- Cache-Block Management instructions +`zicbop` | | [Zicbop][rv-zicbop] --- Cache-Block Prefetch Hint instructions +`zicboz` | | [Zicboz][rv-zicboz] --- Cache-Block Zero instruction +`ziccamoa` | | [Ziccamoa][rv-ziccamoa] --- Platform Behavior: Cacheable and Coherent Main memory supports all basic atomic operations +`ziccif` | | [Ziccif][rv-ziccif] --- Platform Behavior: Cacheable and Coherent Main memory supports instruction fetch and fetches of naturally aligned power-of-2 sizes up to `min(ILEN,XLEN)` are atomic +`zicclsm` | | [Zicclsm][rv-zicclsm] --- Platform Behavior: Cacheable and Coherent Main memory supports misaligned load/store accesses +`ziccrse` | | [Ziccrse][rv-ziccrse] --- Platform Behavior: Cacheable and Coherent Main memory guarantees eventual success on LR/SC sequences +`zicntr` | `zicsr` | [Zicntr][rv-zicntr] --- Base Counters and Timers +`zicond` | | [Zicond][rv-zicond] --- Integer Conditional Operation instructions +`zicsr` | | [Zicsr][rv-zicsr] --- Control and Status Register (CSR) instructions +`zifencei` | | [Zifencei][rv-zifencei] --- Instruction-Fetch Fence instruction +`zihintntl` | | [Zihintntl][rv-zihintntl] --- Non-Temporal Locality Hint instructions +`zihintpause` | | [Zihintpause][rv-zihintpause] --- Pause Hint instruction +`zihpm` | `zicsr` | [Zihpm][rv-zihpm] --- Hardware Performance Counters +`zimop` | | [Zimop][rv-zimop] --- May-Be-Operations +`zk` | `zkn`, `zkr`, `zks`, `zkt`, `zbkb`, `zbkc`, `zkbx` | [Zk][rv-zk] --- Scalar Cryptography +`zkn` | `zknd`, `zkne`, `zknh`, `zbkb`, `zbkc`, `zkbx` | [Zkn][rv-zkn] --- NIST Algorithm suite extension +`zknd` | | [Zknd][rv-zknd] --- NIST Suite: AES Decryption +`zkne` | | [Zkne][rv-zkne] --- NIST Suite: AES Encryption +`zknh` | | [Zknh][rv-zknh] --- NIST Suite: Hash Function Instructions +`zkr` | | [Zkr][rv-zkr] --- Entropy Source Extension +`zks` | `zksed`, `zksh`, `zbkb`, `zbkc`, `zkbx` | [Zks][rv-zks] --- ShangMi Algorithm Suite +`zksed` | | [Zksed][rv-zksed] --- ShangMi Suite: SM4 Block Cipher Instructions +`zksh` | | [Zksh][rv-zksh] --- ShangMi Suite: SM3 Hash Function Instructions +`zkt` | | [Zkt][rv-zkt] --- Data Independent Execution Latency Subset +`ztso` | | [Ztso][rv-ztso] --- Total Store Ordering + +<!-- Keep links near each table to make it easier to move and update. --> + +[rv-a]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/a-st-ext.adoc +[rv-b]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-c]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/c-st-ext.adoc +[rv-m]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/m-st-ext.adoc +[rv-za64rs]: https://github.com/riscv/riscv-profiles/blob/rva23-rvb23-ratified/src/rva23-profile.adoc +[rv-za128rs]: https://github.com/riscv/riscv-profiles/blob/v1.0/profiles.adoc +[rv-zaamo]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/a-st-ext.adoc +[rv-zabha]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zabha.adoc +[rv-zacas]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zacas.adoc +[rv-zalrsc]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/a-st-ext.adoc +[rv-zama16b]: https://github.com/riscv/riscv-profiles/blob/rva23-rvb23-ratified/src/rva23-profile.adoc +[rv-zawrs]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zawrs.adoc +[rv-zba]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-zbb]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-zbc]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-zbkb]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-zbkc]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-zbkx]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-zbs]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/b-st-ext.adoc +[rv-zca]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zc.adoc +[rv-zcb]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zc.adoc +[rv-zcmop]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zimop.adoc +[rv-zic64b]: https://github.com/riscv/riscv-profiles/blob/v1.0/profiles.adoc +[rv-zicbom]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/cmo.adoc +[rv-zicbop]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/cmo.adoc +[rv-zicboz]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/cmo.adoc +[rv-ziccamoa]: https://github.com/riscv/riscv-profiles/blob/v1.0/profiles.adoc +[rv-ziccif]: https://github.com/riscv/riscv-profiles/blob/v1.0/profiles.adoc +[rv-zicclsm]: https://github.com/riscv/riscv-profiles/blob/v1.0/profiles.adoc +[rv-ziccrse]: https://github.com/riscv/riscv-profiles/blob/v1.0/profiles.adoc +[rv-zicntr]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/counters.adoc +[rv-zicond]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zicond.adoc +[rv-zicsr]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zicsr.adoc +[rv-zifencei]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zifencei.adoc +[rv-zihintntl]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zihintntl.adoc +[rv-zihintpause]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zihintpause.adoc +[rv-zihpm]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/counters.adoc +[rv-zimop]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/zimop.adoc +[rv-zk]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zkn]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zkne]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zknd]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zknh]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zkr]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zks]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zksed]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zksh]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-zkt]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/scalar-crypto.adoc +[rv-ztso]: https://github.com/riscv/riscv-isa-manual/blob/20250508/src/ztso-st-ext.adoc + +r[attributes.codegen.target_feature.wasm] +#### `wasm32` or `wasm64` + +Safe `#[target_feature]` functions may always be used in safe contexts on Wasm +platforms. It is impossible to cause undefined behavior via the +`#[target_feature]` attribute because attempting to use instructions +unsupported by the Wasm engine will fail at load time without the risk of being +interpreted in a way different from what the compiler expected. + +Feature | Implicitly Enables | Description +----------------------|---------------------|------------------- +`bulk-memory` | | [WebAssembly bulk memory operations proposal][bulk-memory] +`extended-const` | | [WebAssembly extended const expressions proposal][extended-const] +`mutable-globals` | | [WebAssembly mutable global proposal][mutable-globals] +`nontrapping-fptoint` | | [WebAssembly non-trapping float-to-int conversion proposal][nontrapping-fptoint] +`relaxed-simd` | `simd128` | [WebAssembly relaxed simd proposal][relaxed-simd] +`sign-ext` | | [WebAssembly sign extension operators Proposal][sign-ext] +`simd128` | | [WebAssembly simd proposal][simd128] +`multivalue` | | [WebAssembly multivalue proposal][multivalue] +`reference-types` | | [WebAssembly reference-types proposal][reference-types] +`tail-call` | | [WebAssembly tail-call proposal][tail-call] + +[bulk-memory]: https://github.com/WebAssembly/bulk-memory-operations +[extended-const]: https://github.com/WebAssembly/extended-const +[mutable-globals]: https://github.com/WebAssembly/mutable-global +[nontrapping-fptoint]: https://github.com/WebAssembly/nontrapping-float-to-int-conversions +[relaxed-simd]: https://github.com/WebAssembly/relaxed-simd +[sign-ext]: https://github.com/WebAssembly/sign-extension-ops +[simd128]: https://github.com/webassembly/simd +[reference-types]: https://github.com/webassembly/reference-types +[tail-call]: https://github.com/webassembly/tail-call +[multivalue]: https://github.com/webassembly/multi-value + +r[attributes.codegen.target_feature.s390x] +#### `s390x` + +On `s390x` targets, use of functions with the `#[target_feature]` attribute follows the [above restrictions][attributes.codegen.target_feature.safety-restrictions]. + +Further documentation on these features can be found in the "Additions to z/Architecture" section of Chapter 1 of the *[z/Architecture Principles of Operation]*. + +Feature | Implicitly Enables | Description +---------------------------------------|---------------------------------------|--------------------- +`vector` | | 128-bit vector instructions +`vector-enhancements-1` | `vector` | vector enhancements 1 +`vector-enhancements-2` | `vector-enhancements-1` | vector enhancements 2 +`vector-enhancements-3` | `vector-enhancements-2` | vector enhancements 3 +`vector-packed-decimal` | `vector` | vector packed-decimal +`vector-packed-decimal-enhancement` | `vector-packed-decimal` | vector packed-decimal enhancement +`vector-packed-decimal-enhancement-2` | `vector-packed-decimal-enhancement-2` | vector packed-decimal enhancement 2 +`vector-packed-decimal-enhancement-3` | `vector-packed-decimal-enhancement-3` | vector packed-decimal enhancement 3 +`nnp-assist` | `vector` | nnp assist +`miscellaneous-extensions-2` | | miscellaneous extensions 2 +`miscellaneous-extensions-3` | | miscellaneous extensions 3 +`miscellaneous-extensions-4` | | miscellaneous extensions 4 + +[z/Architecture Principles of Operation]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf + +r[attributes.codegen.target_feature.info] +### Additional information + +r[attributes.codegen.target_feature.remark-cfg] +See the [`target_feature` conditional compilation option] for selectively +enabling or disabling compilation of code based on compile-time settings. Note +that this option is not affected by the `target_feature` attribute, and is +only driven by the features enabled for the entire crate. + +r[attributes.codegen.target_feature.remark-rt] +Whether a feature is enabled can be checked at runtime using a platform-specific macro from the standard library, for instance [`is_x86_feature_detected`] or [`is_aarch64_feature_detected`]. + +> [!NOTE] +> `rustc` has a default set of features enabled for each target and CPU. The CPU may be chosen with the [`-C target-cpu`] flag. Individual features may be enabled or disabled for an entire crate with the [`-C target-feature`] flag. + +r[attributes.codegen.track_caller] +## The `track_caller` attribute + +r[attributes.codegen.track_caller.allowed-positions] +The `track_caller` attribute may be applied to any function with [`"Rust"` ABI][rust-abi] +with the exception of the entry point `fn main`. + +r[attributes.codegen.track_caller.traits] +When applied to functions and methods in trait declarations, the attribute applies to all implementations. If the trait provides a +default implementation with the attribute, then the attribute also applies to override implementations. + +r[attributes.codegen.track_caller.extern] +When applied to a function in an `extern` block the attribute must also be applied to any linked +implementations, otherwise undefined behavior results. When applied to a function which is made +available to an `extern` block, the declaration in the `extern` block must also have the attribute, +otherwise undefined behavior results. + +r[attributes.codegen.track_caller.behavior] +### Behavior + +Applying the attribute to a function `f` allows code within `f` to get a hint of the [`Location`] of +the "topmost" tracked call that led to `f`'s invocation. At the point of observation, an +implementation behaves as if it walks up the stack from `f`'s frame to find the nearest frame of an +*unattributed* function `outer`, and it returns the [`Location`] of the tracked call in `outer`. + +```rust +#[track_caller] +fn f() { + println!("{}", std::panic::Location::caller()); +} +``` + +> [!NOTE] +> `core` provides [`core::panic::Location::caller`] for observing caller locations. It wraps the [`core::intrinsics::caller_location`] intrinsic implemented by `rustc`. + +> [!NOTE] +> Because the resulting `Location` is a hint, an implementation may halt its walk up the stack early. See [Limitations](#limitations) for important caveats. + +#### Examples + +When `f` is called directly by `calls_f`, code in `f` observes its callsite within `calls_f`: + +```rust +# #[track_caller] +# fn f() { +# println!("{}", std::panic::Location::caller()); +# } +fn calls_f() { + f(); // <-- f() prints this location +} +``` + +When `f` is called by another attributed function `g` which is in turn called by `calls_g`, code in +both `f` and `g` observes `g`'s callsite within `calls_g`: + +```rust +# #[track_caller] +# fn f() { +# println!("{}", std::panic::Location::caller()); +# } +#[track_caller] +fn g() { + println!("{}", std::panic::Location::caller()); + f(); +} + +fn calls_g() { + g(); // <-- g() prints this location twice, once itself and once from f() +} +``` + +When `g` is called by another attributed function `h` which is in turn called by `calls_h`, all code +in `f`, `g`, and `h` observes `h`'s callsite within `calls_h`: + +```rust +# #[track_caller] +# fn f() { +# println!("{}", std::panic::Location::caller()); +# } +# #[track_caller] +# fn g() { +# println!("{}", std::panic::Location::caller()); +# f(); +# } +#[track_caller] +fn h() { + println!("{}", std::panic::Location::caller()); + g(); +} + +fn calls_h() { + h(); // <-- prints this location three times, once itself, once from g(), once from f() +} +``` + +And so on. + +r[attributes.codegen.track_caller.limits] +### Limitations + +r[attributes.codegen.track_caller.hint] +This information is a hint and implementations are not required to preserve it. + +r[attributes.codegen.track_caller.decay] +In particular, coercing a function with `#[track_caller]` to a function pointer creates a shim which +appears to observers to have been called at the attributed function's definition site, losing actual +caller information across virtual calls. A common example of this coercion is the creation of a +trait object whose methods are attributed. + +> [!NOTE] +> The aforementioned shim for function pointers is necessary because `rustc` implements `track_caller` in a codegen context by appending an implicit parameter to the function ABI, but this would be unsound for an indirect call because the parameter is not a part of the function's type and a given function pointer type may or may not refer to a function with the attribute. The creation of a shim hides the implicit parameter from callers of the function pointer, preserving soundness. + +<!-- template:attributes --> +r[attributes.codegen.instruction_set] +## The `instruction_set` attribute + +r[attributes.codegen.instruction_set.intro] +The *`instruction_set` [attribute]* specifies the instruction set that a function will use during code generation. This allows mixing more than one instruction set in a single program. + +> [!EXAMPLE] +> <!-- ignore: arm-only --> +> ```rust,ignore +> #[instruction_set(arm::a32)] +> fn arm_code() {} +> +> #[instruction_set(arm::t32)] +> fn thumb_code() {} +> ``` + +r[attributes.codegen.instruction_set.syntax] +The `instruction_set` attribute uses the [MetaListPaths] syntax to specify a single path consisting of the architecture family name and instruction set name. + +r[attributes.codegen.instruction_set.allowed-positions] +The `instruction_set` attribute may only be applied to functions with [bodies] --- [closures], [async blocks], [free functions], [associated functions] in an [inherent impl] or [trait impl], and associated functions in a [trait definition] when those functions have a [default definition] . + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +> [!NOTE] +> Though the attribute can be applied to [closures] and [async blocks], the usefulness of this is limited as we do not yet support attributes on expressions. + +r[attributes.codegen.instruction_set.duplicates] +The `instruction_set` attribute may be used only once on a function. + +r[attributes.codegen.instruction_set.target-limits] +The `instruction_set` attribute may only be used with a target that supports the given value. + +r[attributes.codegen.instruction_set.inline-asm] +When the `instruction_set` attribute is used, any inline assembly in the function must use the specified instruction set instead of the target default. + +r[attributes.codegen.instruction_set.arm] +### `instruction_set` on ARM + +When targeting the `ARMv4T` and `ARMv5te` architectures, the supported values for `instruction_set` are: + +- `arm::a32` --- Generate the function as A32 "ARM" code. +- `arm::t32` --- Generate the function as T32 "Thumb" code. + +If the address of the function is taken as a function pointer, the low bit of the address will depend on the selected instruction set: + +- For `arm::a32` ("ARM"), it will be 0. +- For `arm::t32` ("Thumb"), it will be 1. + +[`-C target-cpu`]: ../../rustc/codegen-options/index.html#target-cpu +[`-C target-feature`]: ../../rustc/codegen-options/index.html#target-feature +[`export_name`]: abi.export_name +[`extern "custom"` function]: items.fn.extern.custom +[`inline` attribute]: attributes.codegen.inline +[`is_aarch64_feature_detected`]: ../../std/arch/macro.is_aarch64_feature_detected.html +[`is_x86_feature_detected`]: ../../std/arch/macro.is_x86_feature_detected.html +[`Location`]: core::panic::Location +[`naked_asm!`]: asm +[`no_mangle`]: abi.no_mangle +[`target_feature` attribute]: attributes.codegen.target_feature +[`target_feature` conditional compilation option]: ../conditional-compilation.md#target_feature +[`track_caller` attribute]: attributes.codegen.track_caller +[`unused_variables` lint]: ../../rustc/lints/listing/warn-by-default.html#unused-variables +[associated functions]: items.associated.fn +[async blocks]: expr.block.async +[async closure]: expr.closure.async +[async function]: items.fn.async +[attribute]: ../attributes.md +[attributes]: ../attributes.md +[bodies]: items.fn.body +[closures]: expr.closure +[default definition]: items.traits.associated-item-decls +[free functions]: items.fn +[function body]: items.fn.body +[functions]: ../items/functions.md +[inherent impl]: items.impl.inherent +["Rust" ABI]: items.extern.abi.rust +[rust-abi]: ../items/external-blocks.md#abi +[target architecture]: ../conditional-compilation.md#target_arch +[testing attributes]: attributes.testing +[trait]: items.traits +[trait definition]: items.traits +[trait impl]: items.impl.trait +[undefined behavior]: ../behavior-considered-undefined.md +[unsafe attribute]: ../attributes.md#r-attributes.safety diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes/debugger.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/debugger.md new file mode 100644 index 00000000..7f9372fc --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/debugger.md @@ -0,0 +1,228 @@ +r[attributes.debugger] +# Debugger attributes + +r[attributes.debugger.intro] +The following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or WinDbg. + +<!-- template:attributes --> +r[attributes.debugger.debugger_visualizer] +## The `debugger_visualizer` attribute + +r[attributes.debugger.debugger_visualizer.intro] +The *`debugger_visualizer` [attribute][attributes]* can be used to embed a debugger visualizer file into the debug information. This improves the debugger experience when displaying values. + +> [!EXAMPLE] +> <!-- ignore: requires external files--> +> ```rust,ignore +> #![debugger_visualizer(natvis_file = "Example.natvis")] +> #![debugger_visualizer(gdb_script_file = "example.py")] +> ``` + +r[attributes.debugger.debugger_visualizer.syntax] +The `debugger_visualizer` attribute uses the [MetaListNameValueStr] syntax to specify its inputs. One of the following keys must be specified: + +- [`natvis_file`][attributes.debugger.debugger_visualizer.natvis] +- [`gdb_script_file`][attributes.debugger.debugger_visualizer.gdb] + +r[attributes.debugger.debugger_visualizer.allowed-positions] +The `debugger_visualizer` attribute may only be applied to a [module] or to the crate root. + +r[attributes.debugger.debugger_visualizer.duplicates] +The `debugger_visualizer` attribute may be used any number of times on a form. All specified visualizer files will be loaded. + +r[attributes.debugger.debugger_visualizer.natvis] +### Using `debugger_visualizer` with Natvis + +r[attributes.debugger.debugger_visualizer.natvis.intro] +Natvis is an XML-based framework for Microsoft debuggers (such as Visual Studio and WinDbg) that uses declarative rules to customize the display of types. For detailed information on the Natvis format, refer to Microsoft's [Natvis documentation]. + +r[attributes.debugger.debugger_visualizer.natvis.msvc] +This attribute only supports embedding Natvis files on `-windows-msvc` targets. + +r[attributes.debugger.debugger_visualizer.natvis.path] +The path to the Natvis file is specified with the `natvis_file` key, which is a path relative to the source file. + +> [!EXAMPLE] +> <!-- ignore: requires external files and msvc --> +> ```rust ignore +> #![debugger_visualizer(natvis_file = "Rectangle.natvis")] +> +> struct FancyRect { +> x: f32, +> y: f32, +> dx: f32, +> dy: f32, +> } +> +> fn main() { +> let fancy_rect = FancyRect { x: 10.0, y: 10.0, dx: 5.0, dy: 5.0 }; +> println!("set breakpoint here"); +> } +> ``` +> +> `Rectangle.natvis` contains: +> +> ```xml +> <?xml version="1.0" encoding="utf-8"?> +> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> +> <Type Name="foo::FancyRect"> +> <DisplayString>({x},{y}) + ({dx}, {dy})</DisplayString> +> <Expand> +> <Synthetic Name="LowerLeft"> +> <DisplayString>({x}, {y})</DisplayString> +> </Synthetic> +> <Synthetic Name="UpperLeft"> +> <DisplayString>({x}, {y + dy})</DisplayString> +> </Synthetic> +> <Synthetic Name="UpperRight"> +> <DisplayString>({x + dx}, {y + dy})</DisplayString> +> </Synthetic> +> <Synthetic Name="LowerRight"> +> <DisplayString>({x + dx}, {y})</DisplayString> +> </Synthetic> +> </Expand> +> </Type> +> </AutoVisualizer> +> ``` +> +> When viewed under WinDbg, the `fancy_rect` variable would be shown as follows: +> +> ```text +> > Variables: +> > fancy_rect: (10.0, 10.0) + (5.0, 5.0) +> > LowerLeft: (10.0, 10.0) +> > UpperLeft: (10.0, 15.0) +> > UpperRight: (15.0, 15.0) +> > LowerRight: (15.0, 10.0) +> ``` + +r[attributes.debugger.debugger_visualizer.gdb] +### Using `debugger_visualizer` with GDB + +r[attributes.debugger.debugger_visualizer.gdb.pretty] +GDB supports the use of a structured Python script, called a *pretty printer*, that describes how a type should be visualized in the debugger view. For detailed information on pretty printers, refer to GDB's [pretty printing documentation]. + +> [!NOTE] +> Embedded pretty printers are not automatically loaded when debugging a binary under GDB. +> +> There are two ways to enable auto-loading embedded pretty printers: +> +> 1. Launch GDB with extra arguments to explicitly add a directory or binary to the auto-load safe path: `gdb -iex "add-auto-load-safe-path safe-path path/to/binary" path/to/binary` For more information, see GDB's [auto-loading documentation]. +> 1. Create a file named `gdbinit` under `$HOME/.config/gdb` (you may need to create the directory if it doesn't already exist). Add the following line to that file: `add-auto-load-safe-path path/to/binary`. + +r[attributes.debugger.debugger_visualizer.gdb.path] +These scripts are embedded using the `gdb_script_file` key, which is a path relative to the source file. + +> [!EXAMPLE] +> <!-- ignore: requires external files --> +> ```rust ignore +> #![debugger_visualizer(gdb_script_file = "printer.py")] +> +> struct Person { +> name: String, +> age: i32, +> } +> +> fn main() { +> let bob = Person { name: String::from("Bob"), age: 10 }; +> println!("set breakpoint here"); +> } +> ``` +> +> `printer.py` contains: +> +> ```python +> import gdb +> +> class PersonPrinter: +> "Print a Person" +> +> def __init__(self, val): +> self.val = val +> self.name = val["name"] +> self.age = int(val["age"]) +> +> def to_string(self): +> return "{} is {} years old.".format(self.name, self.age) +> +> def lookup(val): +> lookup_tag = val.type.tag +> if lookup_tag is None: +> return None +> if "foo::Person" == lookup_tag: +> return PersonPrinter(val) +> +> return None +> +> gdb.current_objfile().pretty_printers.append(lookup) +> ``` +> +> When the crate's debug executable is passed into GDB[^rust-gdb], `print bob` will display: +> +> ```text +> "Bob" is 10 years old. +> ``` +> +> [^rust-gdb]: Note: This assumes you are using the `rust-gdb` script which configures pretty-printers for standard library types like `String`. + +[auto-loading documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading-safe-path.html +[attributes]: ../attributes.md +[Natvis documentation]: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects +[pretty printing documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html + +<!-- template:attributes --> +r[attributes.debugger.collapse_debuginfo] +## The `collapse_debuginfo` attribute + +r[attributes.debugger.collapse_debuginfo.intro] +The *`collapse_debuginfo` [attribute]* controls whether code locations from a macro definition are collapsed into a single location associated with the macro's call site when generating debuginfo for code calling this macro. + +> [!EXAMPLE] +> ```rust +> #[collapse_debuginfo(yes)] +> macro_rules! example { +> () => { +> println!("hello!"); +> }; +> } +> ``` +> +> When using a debugger, invoking the `example` macro may appear as though it is calling a function. That is, when you step to the invocation site, it may show the macro invocation rather than the expanded code. + +<!-- TODO: I think it would be nice to extend this to explain a little more about why this is useful, and the kinds of scenarios where you would want one vs the other. See https://github.com/rust-lang/rfcs/pull/2117 for some guidance. --> + +r[attributes.debugger.collapse_debuginfo.syntax] +The syntax for the `collapse_debuginfo` attribute is: + +```grammar,attributes +@root CollapseDebuginfoAttribute -> `collapse_debuginfo` `(` CollapseDebuginfoOption `)` + +CollapseDebuginfoOption -> + `yes` + | `no` + | `external` +``` + +r[attributes.debugger.collapse_debuginfo.allowed-positions] +The `collapse_debuginfo` attribute may only be applied to a [`macro_rules` definition]. + +r[attributes.debugger.collapse_debuginfo.duplicates] +The `collapse_debuginfo` attribute may used only once on a macro. + +r[attributes.debugger.collapse_debuginfo.options] +The `collapse_debuginfo` attribute accepts these options: + +- `#[collapse_debuginfo(yes)]` --- Code locations in debuginfo are collapsed. +- `#[collapse_debuginfo(no)]` --- Code locations in debuginfo are not collapsed. +- `#[collapse_debuginfo(external)]` --- Code locations in debuginfo are collapsed only if the macro comes from a different crate. + +r[attributes.debugger.collapse_debuginfo.default] +The `external` behavior is the default for macros that don't have this attribute unless they are built-in macros. For built-in macros the default is `yes`. + +> [!NOTE] +> `rustc` has a [`-C collapse-macro-debuginfo`] CLI option to override both the default behavior and the values of any `#[collapse_debuginfo]` attributes. + +[`-C collapse-macro-debuginfo`]: ../../rustc/codegen-options/index.html#collapse-macro-debuginfo +[`macro_rules` definition]: ../macros-by-example.md +[attribute]: ../attributes.md +[module]: ../items/modules.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes/derive.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/derive.md new file mode 100644 index 00000000..5aa7f712 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/derive.md @@ -0,0 +1,116 @@ +<!-- template:attributes --> +r[attributes.derive] +# Derive + +r[attributes.derive.intro] +The *`derive` [attribute][attributes]* invokes one or more [derive macros], allowing new [items] to be automatically generated for data structures. You can create `derive` macros with [procedural macros]. + +> [!EXAMPLE] +> The [`PartialEq`][macro@PartialEq] derive macro emits an [implementation] of [`PartialEq`] for `Foo<T> where T: PartialEq`. The [`Clone`][macro@Clone] derive macro does likewise for [`Clone`]. +> +> ```rust +> #[derive(PartialEq, Clone)] +> struct Foo<T> { +> a: i32, +> b: T, +> } +> ``` +> +> The generated `impl` items are equivalent to: +> +> ```rust +> # struct Foo<T> { a: i32, b: T } +> impl<T: PartialEq> PartialEq for Foo<T> { +> fn eq(&self, other: &Foo<T>) -> bool { +> self.a == other.a && self.b == other.b +> } +> } +> +> impl<T: Clone> Clone for Foo<T> { +> fn clone(&self) -> Self { +> Foo { a: self.a.clone(), b: self.b.clone() } +> } +> } +> ``` + +r[attributes.derive.syntax] +The `derive` attribute uses the [MetaListPaths] syntax to specify a list of paths to [derive macros] to invoke. + +r[attributes.derive.allowed-positions] +The `derive` attribute may only be applied to [structs][items.struct], [enums][items.enum], and [unions][items.union]. + +r[attributes.derive.duplicates] +The `derive` attribute may be used any number of times on an item. All derive macros listed in all attributes are invoked. + +r[attributes.derive.stdlib] +The `derive` attribute is exported in the standard library as: + +- [`core::derive`] +- [`std::derive`] +- [`core::prelude::v1::derive`] +- [`std::prelude::v1::derive`] + +r[attributes.derive.built-in] +Built-in derives are defined in the [language prelude][names.preludes.lang]. The list of built-in derives are: + +- [`Clone`] +- [`Copy`] +- [`Debug`] +- [`Default`] +- [`Eq`] +- [`Hash`] +- [`Ord`] +- [`PartialEq`] +- [`PartialOrd`] + +r[attributes.derive.built-in-automatically_derived] +The built-in derives include the [`automatically_derived` attribute][attributes.derive.automatically_derived] on the implementations they generate. + +r[attributes.derive.behavior] +During macro expansion, for each element in the list of derives, the corresponding derive macro expands to zero or more [items]. + +<!-- template:attributes --> +r[attributes.derive.automatically_derived] +## The `automatically_derived` attribute + +r[attributes.derive.automatically_derived.intro] +The *`automatically_derived` [attribute][attributes]* is used to annotate an [implementation] to indicate that it was automatically created by a [derive macro]. It has no direct effect, but it may be used by tools and diagnostic lints to detect these automatically generated implementations. + +> [!EXAMPLE] +> Given [`#[derive(Clone)]`][macro@Clone] on `struct Example`, the [derive macro] may produce: +> +> ```rust +> # struct Example; +> #[automatically_derived] +> impl ::core::clone::Clone for Example { +> #[inline] +> fn clone(&self) -> Self { +> Example +> } +> } +> ``` + +r[attributes.derive.automatically_derived.syntax] +The `automatically_derived` attribute uses the [MetaWord] syntax. + +r[attributes.derive.automatically_derived.allowed-positions] +The `automatically_derived` attribute may only be applied to an [implementation]. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[attributes.derive.automatically_derived.duplicates] +Using `automatically_derived` more than once on an implementation has the same effect as using it once. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[attributes.derive.automatically_derived.behavior] +The `automatically_derived` attribute has no behavior. + +[items]: ../items.md +[derive macro]: macro.proc.derive +[derive macros]: macro.proc.derive +[implementation]: ../items/implementations.md +[items]: ../items.md +[procedural macros]: macro.proc.derive diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes/diagnostics.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/diagnostics.md new file mode 100644 index 00000000..f2f6b62b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/diagnostics.md @@ -0,0 +1,781 @@ +r[attributes.diagnostics] +# Diagnostic attributes + +r[attributes.diagnostics.intro] +The following [attributes] are used for controlling or generating diagnostic +messages during compilation. + +r[attributes.diagnostics.lint] +## Lint check attributes + +r[attributes.diagnostics.lint.intro] +A lint check names a potentially undesirable coding pattern, such as +unreachable code or omitted documentation. + +r[attributes.diagnostics.lint.level] +The lint attributes `allow`, +`expect`, `warn`, `deny`, and `forbid` use the [MetaListPaths] syntax +to specify a list of lint names to change the lint level for the entity +to which the attribute applies. + +For any lint check `C`: + +r[attributes.diagnostics.lint.allow] +* `#[allow(C)]` overrides the check for `C` so that violations will go + unreported. + +r[attributes.diagnostics.lint.expect] +* `#[expect(C)]` indicates that lint `C` is expected to be emitted. The + attribute will suppress the emission of `C` or issue a warning, if the + expectation is unfulfilled. + +r[attributes.diagnostics.lint.warn] +* `#[warn(C)]` warns about violations of `C` but continues compilation. + +r[attributes.diagnostics.lint.deny] +* `#[deny(C)]` signals an error after encountering a violation of `C`, + +r[attributes.diagnostics.lint.forbid] +* `#[forbid(C)]` is the same as `deny(C)`, but also forbids changing the lint + level afterwards, + +> [!NOTE] +> The lint checks supported by `rustc` can be found via `rustc -W help`, along with their default settings and are documented in the [rustc book]. + +```rust +pub mod m1 { + // Missing documentation is ignored here + #[allow(missing_docs)] + pub fn undocumented_one() -> i32 { 1 } + + // Missing documentation signals a warning here + #[warn(missing_docs)] + pub fn undocumented_too() -> i32 { 2 } + + // Missing documentation signals an error here + #[deny(missing_docs)] + pub fn undocumented_end() -> i32 { 3 } +} +``` + +r[attributes.diagnostics.lint.override] +Lint attributes can override the level specified from a previous attribute, as +long as the level does not attempt to change a forbidden lint +(except for `deny`, which is allowed inside a `forbid` context, but ignored). +Previous attributes are those from a higher level in the syntax tree, or from a +previous attribute on the same entity as listed in left-to-right source order. + +This example shows how one can use `allow` and `warn` to toggle a particular +check on and off: + +```rust +#[warn(missing_docs)] +pub mod m2 { + #[allow(missing_docs)] + pub mod nested { + // Missing documentation is ignored here + pub fn undocumented_one() -> i32 { 1 } + + // Missing documentation signals a warning here, + // despite the allow above. + #[warn(missing_docs)] + pub fn undocumented_two() -> i32 { 2 } + } + + // Missing documentation signals a warning here + pub fn undocumented_too() -> i32 { 3 } +} +``` + +This example shows how one can use `forbid` to disallow uses of `allow` or +`expect` for that lint check: + +```rust,compile_fail +#[forbid(missing_docs)] +pub mod m3 { + // Attempting to toggle warning signals an error here + #[allow(missing_docs)] + /// Returns 2. + pub fn undocumented_too() -> i32 { 2 } +} +``` + +> [!NOTE] +> `rustc` allows setting lint levels on the [command-line][rustc-lint-cli], and also supports [setting caps][rustc-lint-caps] on the lints that are reported. + +r[attributes.diagnostics.lint.reason] +### Lint reasons + +All lint attributes support an additional `reason` parameter, to give context why +a certain attribute was added. This reason will be displayed as part of the lint +message if the lint is emitted at the defined level. + +```rust,edition2015,compile_fail +// `keyword_idents` is allowed by default. Here we deny it to +// avoid migration of identifiers when we update the edition. +#![deny( + keyword_idents, + reason = "we want to avoid these idents to be future compatible" +)] + +// This name was allowed in Rust's 2015 edition. We still aim to avoid +// this to be future compatible and not confuse end users. +fn dyn() {} +``` + +Here is another example, where the lint is allowed with a reason: + +```rust +use std::path::PathBuf; + +pub fn get_path() -> PathBuf { + // The `reason` parameter on `allow` attributes acts as documentation for the reader. + #[allow(unused_mut, reason = "this is only modified on some platforms")] + let mut file_name = PathBuf::from("git"); + + #[cfg(target_os = "windows")] + file_name.set_extension("exe"); + + file_name +} +``` + +r[attributes.diagnostics.expect] +### The `#[expect]` attribute + +r[attributes.diagnostics.expect.intro] +The `#[expect(C)]` attribute creates a lint expectation for lint `C`. The +expectation will be fulfilled, if a `#[warn(C)]` attribute at the same location +would result in a lint emission. If the expectation is unfulfilled, because +lint `C` would not be emitted, the `unfulfilled_lint_expectations` lint will +be emitted at the attribute. + +```rust +fn main() { + // This `#[expect]` attribute creates a lint expectation, that the `unused_variables` + // lint would be emitted by the following statement. This expectation is + // unfulfilled, since the `question` variable is used by the `println!` macro. + // Therefore, the `unfulfilled_lint_expectations` lint will be emitted at the + // attribute. + #[expect(unused_variables)] + let question = "who lives in a pineapple under the sea?"; + println!("{question}"); + + // This `#[expect]` attribute creates a lint expectation that will be fulfilled, since + // the `answer` variable is never used. The `unused_variables` lint, that would usually + // be emitted, is suppressed. No warning will be issued for the statement or attribute. + #[expect(unused_variables)] + let answer = "SpongeBob SquarePants!"; +} +``` + +r[attributes.diagnostics.expect.fulfillment] +The lint expectation is only fulfilled by lint emissions which have been suppressed by +the `expect` attribute. If the lint level is modified in the scope with other level +attributes like `allow` or `warn`, the lint emission will be handled accordingly and the +expectation will remain unfulfilled. + +```rust +#[expect(unused_variables)] +fn select_song() { + // This will emit the `unused_variables` lint at the warn level + // as defined by the `warn` attribute. This will not fulfill the + // expectation above the function. + #[warn(unused_variables)] + let song_name = "Crab Rave"; + + // The `allow` attribute suppresses the lint emission. This will not + // fulfill the expectation as it has been suppressed by the `allow` + // attribute and not the `expect` attribute above the function. + #[allow(unused_variables)] + let song_creator = "Noisestorm"; + + // This `expect` attribute will suppress the `unused_variables` lint emission + // at the variable. The `expect` attribute above the function will still not + // be fulfilled, since this lint emission has been suppressed by the local + // expect attribute. + #[expect(unused_variables)] + let song_version = "Monstercat Release"; +} +``` + +r[attributes.diagnostics.expect.independent] +If the `expect` attribute contains several lints, each one is expected separately. For a +lint group it's enough if one lint inside the group has been emitted: + +```rust +// This expectation will be fulfilled by the unused value inside the function +// since the emitted `unused_variables` lint is inside the `unused` lint group. +#[expect(unused)] +pub fn thoughts() { + let unused = "I'm running out of examples"; +} + +pub fn another_example() { + // This attribute creates two lint expectations. The `unused_mut` lint will be + // suppressed and with that fulfill the first expectation. The `unused_variables` + // wouldn't be emitted, since the variable is used. That expectation will therefore + // be unsatisfied, and a warning will be emitted. + #[expect(unused_mut, unused_variables)] + let mut link = "https://www.rust-lang.org/"; + + println!("Welcome to our community: {link}"); +} +``` + +> [!NOTE] +> The behavior of `#[expect(unfulfilled_lint_expectations)]` is currently defined to always generate the `unfulfilled_lint_expectations` lint. + +r[attributes.diagnostics.lint.group] +### Lint groups + +r[attributes.diagnostics.lint.group.intro] +Lints may be organized into named groups so that the level of related lints can be adjusted together. + +r[attributes.diagnostics.lint.group.equivalence] +Using a named group is equivalent to listing out the lints within that group. + +```rust,compile_fail +// This allows all lints in the "unused" group. +#[allow(unused)] +// This overrides the "unused_must_use" lint from the "unused" +// group to deny. +#[deny(unused_must_use)] +fn example() { + // This does not generate a warning because the "unused_variables" + // lint is in the "unused" group. + let x = 1; + // This generates an error because the result is unused and + // "unused_must_use" is marked as "deny". + std::fs::remove_file("some_file"); // ERROR: unused `Result` that must be used +} +``` + +r[attributes.diagnostics.lint.group.warnings] +There is a special group named "warnings" which includes all lints at the +"warn" level. The "warnings" group ignores attribute order and applies to all +lints that would otherwise warn within the entity. + +```rust,compile_fail +# unsafe fn an_unsafe_fn() {} +// The order of these two attributes does not matter. +#[deny(warnings)] +// The unsafe_code lint is normally "allow" by default. +#[warn(unsafe_code)] +fn example_err() { + // This is an error because the `unsafe_code` warning has + // been lifted to "deny". + unsafe { an_unsafe_fn() } // ERROR: use of `unsafe` block +} +``` + +r[attributes.diagnostics.lint.tool] +### Tool lint attributes + +r[attributes.diagnostics.lint.tool.intro] +Tool lints allows using scoped lints, to `allow`, `warn`, `deny` or `forbid` +lints of certain tools. + +r[attributes.diagnostics.lint.tool.activation] +Tool lints only get checked when the associated tool is active. If a lint +attribute, such as `allow`, references a nonexistent tool lint, the compiler +will not warn about the nonexistent lint until you use the tool. + +Otherwise, they work just like regular lint attributes: + +```rust +// set the entire `pedantic` clippy lint group to warn +#![warn(clippy::pedantic)] +// silence warnings from the `filter_map` clippy lint +#![allow(clippy::filter_map)] + +fn main() { + // ... +} + +// silence the `cmp_nan` clippy lint just for this function +#[allow(clippy::cmp_nan)] +fn foo() { + // ... +} +``` + +> [!NOTE] +> `rustc` currently recognizes the tool lints for "[clippy]" and "[rustdoc]". + +r[attributes.diagnostics.deprecated] +## The `deprecated` attribute + +r[attributes.diagnostics.deprecated.intro] +The *`deprecated` attribute* marks an item as deprecated. `rustc` will issue +warnings on use of `#[deprecated]` items. `rustdoc` will show item +deprecation, including the `since` version and `note`, if available. + +r[attributes.diagnostics.deprecated.syntax] +The `deprecated` attribute has several forms: + +- `deprecated` --- Issues a generic message. +- `deprecated = "message"` --- Includes the given string in the deprecation + message. +- [MetaListNameValueStr] syntax with two optional fields: + - `since` --- Specifies a version number when the item was deprecated. `rustc` + does not currently interpret the string, but external tools like [Clippy] + may check the validity of the value. + - `note` --- Specifies a string that should be included in the deprecation + message. This is typically used to provide an explanation about the + deprecation and preferred alternatives. + +r[attributes.diagnostics.deprecated.allowed-positions] +The `deprecated` attribute may be applied to any [item], [trait item], [enum +variant], [struct field], [external block item], or [macro definition]. It +cannot be applied to [trait implementation items][trait-impl]. When applied to an item +containing other items, such as a [module] or [implementation], all child +items inherit the deprecation attribute. +<!-- NOTE: It is only rejected for trait impl items +(AnnotationKind::Prohibited). In all other locations, it is silently ignored. +Tuple struct fields are ignored. +--> + +Here is an example: + +```rust +#[deprecated(since = "5.2.0", note = "foo was rarely used. Users should instead use bar")] +pub fn foo() {} + +pub fn bar() {} +``` + +The [RFC][1270-deprecation.md] contains motivations and more details. + +[1270-deprecation.md]: https://github.com/rust-lang/rfcs/blob/master/text/1270-deprecation.md + +<!-- template:attributes --> +r[attributes.diagnostics.must_use] +## The `must_use` attribute + +r[attributes.diagnostics.must_use.intro] +The *`must_use` [attribute]* marks a value that should be used. + +r[attributes.diagnostics.must_use.syntax] +The `must_use` attribute uses the [MetaWord] and [MetaNameValueStr] syntaxes. + +> [!EXAMPLE] +> ```rust +> #[must_use] +> fn use_me1() -> u8 { 0 } +> +> #[must_use = "explanation of why it should be used"] +> fn use_me2() -> u8 { 0 } +> ``` + +r[attributes.diagnostics.must_use.allowed-positions] +The `must_use` attribute may be applied to a: + +- [Struct] +- [Enumeration] +- [Union] +- [Function] +- [Trait] + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[attributes.diagnostics.must_use.duplicates] +The `must_use` attribute may be used only once on an item. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +r[attributes.diagnostics.must_use.message] +The `must_use` attribute may include a message by using the [MetaNameValueStr] syntax, e.g., `#[must_use = "example message"]`. The message may be emitted as part of the lint. + +r[attributes.diagnostics.must_use.type] +When the attribute is applied to a [struct], [enumeration], or [union], if the [expression] of an [expression statement] has that type, the use triggers the `unused_must_use` lint. + +```rust,compile_fail +#![deny(unused_must_use)] +#[must_use] +struct MustUse(); +MustUse(); // ERROR: Unused value that must be used. +``` + +r[attributes.diagnostics.must_use.type-uninhabited] +As an exception to [attributes.diagnostics.must_use.type], the lint does not fire for `Result<(), E>` when `E` is [uninhabited] or for `ControlFlow<B, ()>` when `B` is [uninhabited]. A `#[non_exhaustive]` type from an external crate is not considered uninhabited for this purpose, because it may gain constructors in the future. + +```rust +#![deny(unused_must_use)] +# use core::ops::ControlFlow; +fn f1() -> Result<(), !> { Ok(()) } +f1(); // OK: `!` is uninhabited. +fn f2() -> ControlFlow<!, ()> { ControlFlow::Continue(()) } +f2(); // OK: `!` is uninhabited. +``` + +r[attributes.diagnostics.must_use.fn] +If the [expression] of an [expression statement] is a [call expression] or [method call expression] whose function operand is a function to which the attribute is applied, the use triggers the `unused_must_use` lint. + +```rust,compile_fail +#![deny(unused_must_use)] +#[must_use] +fn f() {} +f(); // ERROR: Unused return value that must be used. +``` + +r[attributes.diagnostics.must_use.trait] +If the [expression] of an [expression statement] is a [call expression] or [method call expression] whose function operand is a function that returns an [impl trait] or a [dyn trait] type where one or more traits in the bound are marked with the attribute, the use triggers the `unused_must_use` lint. + +```rust,compile_fail +#![deny(unused_must_use)] +#[must_use] +trait Tr {} +impl Tr for () {} +fn f() -> impl Tr {} +f(); // ERROR: Unused implementor that must be used. +``` + +r[attributes.diagnostics.must_use.trait-function] +When the attribute is applied to a function in a trait declaration, the rules described in [attributes.diagnostics.must_use.fn] also apply when the function operand of the [call expression] or [method call expression] is an implementation of that function. + +```rust,compile_fail +#![deny(unused_must_use)] +trait Tr { + #[must_use] + fn use_me(&self); +} + +impl Tr for () { + fn use_me(&self) {} +} + +().use_me(); // ERROR: Unused return value that must be used. +``` + +```rust,compile_fail +# #![deny(unused_must_use)] +# trait Tr { +# #[must_use] +# fn use_me(&self); +# } +# +# impl Tr for () { +# fn use_me(&self) {} +# } +# +<() as Tr>::use_me(&()); +// ^^^^^^^^^^^ ERROR: Unused return value that must be used. +``` + +r[attributes.diagnostics.must_use.block-expr] +When checking the [expression] of an [expression statement] for [attributes.diagnostics.must_use.type], [attributes.diagnostics.must_use.fn], [attributes.diagnostics.must_use.trait], and [attributes.diagnostics.must_use.trait-function], the lint looks through [block expressions][block expression] (including [`unsafe` blocks] and [labeled block expressions]) to the trailing expression of each. This applies recursively for nested block expressions. + +```rust,compile_fail +#![deny(unused_must_use)] +#[must_use] +fn f() {} + +{ f() }; // ERROR: The lint looks through block expressions. +unsafe { f() }; // ERROR: The lint looks through `unsafe` blocks. +{ { f() } }; // ERROR: The lint looks through nested blocks. +``` + +r[attributes.diagnostics.must_use.trait-impl-function] +When used on a function in a trait implementation, the attribute does nothing. + +```rust +#![deny(unused_must_use)] +trait Tr { + fn f(&self); +} + +impl Tr for () { + #[must_use] // This has no effect. + fn f(&self) {} +} + +().f(); // OK. +``` + +> [!NOTE] +> `rustc` lints against use on functions in trait implementations. This may become an error in the future. + +r[attributes.diagnostics.must_use.wrapping-suppression] +> [!NOTE] +> Wrapping the result of a `#[must_use]` function in certain expressions can suppress the [fn-based check][attributes.diagnostics.must_use.fn], because the [expression] of the [expression statement] is not a [call expression] or [method call expression] to a `#[must_use]` function. The [type-based check][attributes.diagnostics.must_use.type] still applies if the type of the overall expression is `#[must_use]`. +> +> ```rust +> #![deny(unused_must_use)] +> #[must_use] +> fn f() {} +> +> // The fn-based check does not fire for any of these, because the +> // expression of the expression statement is not a call to a +> // `#[must_use]` function. +> (f(),); // Expression is a tuple, not a call. +> Some(f()); // Callee `Some` is not `#[must_use]`. +> if true { f() } else {}; // Expression is an `if`, not a call. +> match true { // Expression is a `match`, not a call. +> _ => f() +> }; +> ``` +> +> ```rust,compile_fail +> #![deny(unused_must_use)] +> #[must_use] +> struct MustUse; +> fn g() -> MustUse { MustUse } +> +> // Despite the `if` expression not being a call, the type-based check +> // fires because the type of the expression is `MustUse`, which has +> // the `#[must_use]` attribute. +> if true { g() } else { MustUse }; // ERROR: Must be used. +> ``` + +r[attributes.diagnostics.must_use.underscore-idiom] +> [!NOTE] +> Using a [let statement] or [destructuring assignment] with a pattern of `_` when a must-used value is purposely discarded is idiomatic. +> +> ```rust +> #![deny(unused_must_use)] +> #[must_use] +> fn f() {} +> let _ = f(); // OK. +> _ = f(); // OK. +> ``` + +r[attributes.diagnostic.namespace] +## The `diagnostic` tool attribute namespace + +r[attributes.diagnostic.namespace.intro] +The `#[diagnostic]` attribute namespace is a home for attributes to influence compile-time error messages. +The hints provided by these attributes are not guaranteed to be used. + +r[attributes.diagnostic.namespace.unknown-invalid-syntax] +Unknown attributes in this namespace are accepted, though they may emit warnings for unused attributes. +Additionally, invalid inputs to known attributes will typically be a warning (see the attribute definitions for details). +This is meant to allow adding or discarding attributes and changing inputs in the future to allow changes without the need to keep the non-meaningful attributes or options working. + +r[attributes.diagnostic.on_unimplemented] +### The `diagnostic::on_unimplemented` attribute + +r[attributes.diagnostic.on_unimplemented.intro] +The `#[diagnostic::on_unimplemented]` attribute is a hint to the compiler to supplement the error message that would normally be generated in scenarios where a trait is required but not implemented on a type. + +r[attributes.diagnostic.on_unimplemented.allowed-positions] +The attribute should be placed on a [trait declaration], though it is not an error to be located in other positions. + +r[attributes.diagnostic.on_unimplemented.syntax] +The attribute uses the [MetaListNameValueStr] syntax to specify its inputs, though any malformed input to the attribute is not considered as an error to provide both forwards and backwards compatibility. + +r[attributes.diagnostic.on_unimplemented.keys] +The following keys have the given meaning: +* `message` --- The text for the top level error message. +* `label` --- The text for the label shown inline in the broken code in the error message. +* `note` --- Provides additional notes. + +r[attributes.diagnostic.on_unimplemented.note-repetition] +The `note` option can appear several times, which results in several note messages being emitted. + +r[attributes.diagnostic.on_unimplemented.repetition] +If any of the other options appears several times the first occurrence of the relevant option specifies the actually used value. Subsequent occurrences generates a warning. + +r[attributes.diagnostic.on_unimplemented.unknown-keys] +A warning is generated for any unknown keys. + +r[attributes.diagnostic.on_unimplemented.format-string] +All three options accept a string as an argument, interpreted using the same formatting as a [`std::fmt`] string. + +r[attributes.diagnostic.on_unimplemented.format-parameters] +Format parameters with the given named parameter will be replaced with the following text: +* `{Self}` --- The name of the type implementing the trait. +* `{` *GenericParameterName* `}` --- The name of the generic argument's type for the given generic parameter. + +r[attributes.diagnostic.on_unimplemented.invalid-formats] +Any other format parameter will generate a warning, but will otherwise be included in the string as-is. + +r[attributes.diagnostic.on_unimplemented.invalid-string] +Invalid format strings may generate a warning, but are otherwise allowed, but may not display as intended. +Format specifiers may generate a warning, but are otherwise ignored. + +In this example: + +```rust,compile_fail,E0277 +#[diagnostic::on_unimplemented( + message = "My Message for `ImportantTrait<{A}>` implemented for `{Self}`", + label = "My Label", + note = "Note 1", + note = "Note 2" +)] +trait ImportantTrait<A> {} + +fn use_my_trait(_: impl ImportantTrait<i32>) {} + +fn main() { + use_my_trait(String::new()); +} +``` + +the compiler may generate an error message which looks like this: + +```text +error[E0277]: My Message for `ImportantTrait<i32>` implemented for `String` + --> src/main.rs:14:18 + | +14 | use_my_trait(String::new()); + | ------------ ^^^^^^^^^^^^^ My Label + | | + | required by a bound introduced by this call + | + = help: the trait `ImportantTrait<i32>` is not implemented for `String` + = note: Note 1 + = note: Note 2 +``` + +r[attributes.diagnostic.do_not_recommend] +### The `diagnostic::do_not_recommend` attribute + +r[attributes.diagnostic.do_not_recommend.intro] +The `#[diagnostic::do_not_recommend]` attribute is a hint to the compiler to not show the annotated trait implementation as part of a diagnostic message. + +> [!NOTE] +> Suppressing the recommendation can be useful if you know that the recommendation would normally not be useful to the programmer. This often occurs with broad, blanket impls. The recommendation may send the programmer down the wrong path, or the trait implementation may be an internal detail that you don't want to expose, or the bounds may not be able to be satisfied by the programmer. +> +> For example, in an error message about a type not implementing a required trait, the compiler may find a trait implementation that would satisfy the requirements if it weren't for specific bounds in the trait implementation. The compiler may tell the user that there is an impl, but the problem is the bounds in the trait implementation. The `#[diagnostic::do_not_recommend]` attribute can be used to tell the compiler to *not* tell the user about the trait implementation, and instead simply tell the user the type doesn't implement the required trait. + +r[attributes.diagnostic.do_not_recommend.allowed-positions] +The attribute should be placed on a [trait implementation item][trait-impl], though it is not an error to be located in other positions. + +r[attributes.diagnostic.do_not_recommend.syntax] +The attribute does not accept any arguments, though unexpected arguments are not considered as an error. + +In the following example, there is a trait called `AsExpression` which is used for casting arbitrary types to the `Expression` type used in an SQL library. There is a method called `check` which takes an `AsExpression`. + +```rust,compile_fail,E0277 +# pub trait Expression { +# type SqlType; +# } +# +# pub trait AsExpression<ST> { +# type Expression: Expression<SqlType = ST>; +# } +# +# pub struct Text; +# pub struct Integer; +# +# pub struct Bound<T>(T); +# pub struct SelectInt; +# +# impl Expression for SelectInt { +# type SqlType = Integer; +# } +# +# impl<T> Expression for Bound<T> { +# type SqlType = T; +# } +# +# impl AsExpression<Integer> for i32 { +# type Expression = Bound<Integer>; +# } +# +# impl AsExpression<Text> for &'_ str { +# type Expression = Bound<Text>; +# } +# +# impl<T> Foo for T where T: Expression {} + +// Uncomment this line to change the recommendation. +// #[diagnostic::do_not_recommend] +impl<T, ST> AsExpression<ST> for T +where + T: Expression<SqlType = ST>, +{ + type Expression = T; +} + +trait Foo: Expression + Sized { + fn check<T>(&self, _: T) -> <T as AsExpression<<Self as Expression>::SqlType>>::Expression + where + T: AsExpression<Self::SqlType>, + { + todo!() + } +} + +fn main() { + SelectInt.check("bar"); +} +``` + +The `SelectInt` type's `check` method is expecting an `Integer` type. Calling it with an i32 type works, as it gets converted to an `Integer` by the `AsExpression` trait. However, calling it with a string does not, and generates a an error that may look like this: + +```text +error[E0277]: the trait bound `&str: Expression` is not satisfied + --> src/main.rs:53:15 + | +53 | SelectInt.check("bar"); + | ^^^^^ the trait `Expression` is not implemented for `&str` + | + = help: the following other types implement trait `Expression`: + Bound<T> + SelectInt +note: required for `&str` to implement `AsExpression<Integer>` + --> src/main.rs:45:13 + | +45 | impl<T, ST> AsExpression<ST> for T + | ^^^^^^^^^^^^^^^^ ^ +46 | where +47 | T: Expression<SqlType = ST>, + | ------------------------ unsatisfied trait bound introduced here +``` + +By adding the `#[diagnostic::do_not_recommend]` attribute to the blanket `impl` for `AsExpression`, the message changes to: + +```text +error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied + --> src/main.rs:53:15 + | +53 | SelectInt.check("bar"); + | ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str` + | + = help: the trait `AsExpression<Integer>` is not implemented for `&str` + but trait `AsExpression<Text>` is implemented for it + = help: for that trait implementation, expected `Text`, found `Integer` +``` + +The first error message includes a somewhat confusing error message about the relationship of `&str` and `Expression`, as well as the unsatisfied trait bound in the blanket impl. After adding `#[diagnostic::do_not_recommend]`, it no longer considers the blanket impl for the recommendation. The message should be a little clearer, with an indication that a string cannot be converted to an `Integer`. + +[Clippy]: https://github.com/rust-lang/rust-clippy +[`Drop`]: ../special-types-and-traits.md#drop +[`unsafe` blocks]: ../expressions/block-expr.md#unsafe-blocks +[attribute]: ../attributes.md +[attributes]: ../attributes.md +[block expression]: ../expressions/block-expr.md +[call expression]: ../expressions/call-expr.md +[destructuring assignment]: expr.assign.destructure +[method call expression]: ../expressions/method-call-expr.md +[dyn trait]: ../types/trait-object.md +[enum variant]: ../items/enumerations.md +[enumeration]: ../items/enumerations.md +[expression statement]: ../statements.md#expression-statements +[expression]: ../expressions.md +[external block item]: ../items/external-blocks.md +[functions]: ../items/functions.md +[impl trait]: ../types/impl-trait.md +[implementation]: ../items/implementations.md +[item]: ../items.md +[labeled block expressions]: ../expressions/block-expr.md#labeled-block-expressions +[let statement]: ../statements.md#let-statements +[macro definition]: ../macros-by-example.md +[module]: ../items/modules.md +[rustc book]: ../../rustc/lints/index.html +[rustc-lint-caps]: ../../rustc/lints/levels.html#capping-lints +[rustc-lint-cli]: ../../rustc/lints/levels.html#via-compiler-flag +[rustdoc]: ../../rustdoc/lints.html +[struct field]: ../items/structs.md +[struct]: ../items/structs.md +[external block]: ../items/external-blocks.md +[trait declaration]: ../items/traits.md +[trait item]: ../items/traits.md +[trait-impl]: ../items/implementations.md#trait-implementations +[traits]: ../items/traits.md +[uninhabited]: glossary.uninhabited +[union]: ../items/unions.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes/limits.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/limits.md new file mode 100644 index 00000000..c07020c7 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/limits.md @@ -0,0 +1,88 @@ +r[attributes.limits] +# Limits + +r[attributes.limits.intro] +The following [attributes] affect compile-time limits. + +r[attributes.limits.recursion_limit] +## The `recursion_limit` attribute + +r[attributes.limits.recursion_limit.intro] +The *`recursion_limit` attribute* may be applied at the [crate] level to set the +maximum depth for potentially infinitely-recursive compile-time operations +like macro expansion or auto-dereference. + +r[attributes.limits.recursion_limit.syntax] +It uses the [MetaNameValueStr] +syntax to specify the recursion depth. + +> [!NOTE] +> The default in `rustc` is 128. + +```rust,compile_fail +#![recursion_limit = "4"] + +macro_rules! a { + () => { a!(1); }; + (1) => { a!(2); }; + (2) => { a!(3); }; + (3) => { a!(4); }; + (4) => { }; +} + +// This fails to expand because it requires a recursion depth greater than 4. +a!{} +``` + +```rust,compile_fail +#![recursion_limit = "1"] + +// This fails because it requires two recursive steps to auto-dereference. +(|_: &u8| {})(&&&1); +``` + +<!-- template:attributes --> +r[attributes.limits.type_length_limit] +## The `type_length_limit` attribute + +r[attributes.limits.type_length_limit.intro] +The *`type_length_limit` [attribute][attributes]* sets the maximum number of type substitutions allowed when constructing a concrete type during monomorphization. + +> [!NOTE] +> `rustc` only enforces the limit when the nightly `-Zenforce-type-length-limit` flag is active. +> +> For more information, see [Rust PR #127670](https://github.com/rust-lang/rust/pull/127670). + +> [!EXAMPLE] +> <!-- ignore: not enforced without nightly flag --> +> ```rust,ignore +> #![type_length_limit = "4"] +> +> fn f<T>(x: T) {} +> +> // This fails to compile because monomorphizing to +> // `f::<((((i32,), i32), i32), i32)>` requires more +> // than 4 type elements. +> f(((((1,), 2), 3), 4)); +> ``` + +> [!NOTE] +> The default value in `rustc` is `1048576`. + +r[attributes.limits.type_length_limit.syntax] +The `type_length_limit` attribute uses the [MetaNameValueStr] syntax. The value in the string must be a non-negative number. + +r[attributes.limits.type_length_limit.allowed-positions] +The `type_length_limit` attribute may only be applied to the crate root. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[attributes.limits.type_length_limit.duplicates] +Only the first use of `type_length_limit` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +[attributes]: ../attributes.md +[crate]: ../crates-and-source-files.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes/testing.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/testing.md new file mode 100644 index 00000000..28c57ba5 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/testing.md @@ -0,0 +1,191 @@ +r[attributes.testing] +# Testing attributes + +r[attributes.testing.intro] +The following [attributes] are used for specifying functions for performing +tests. Compiling a crate in "test" mode enables building the test functions +along with a test harness for executing the tests. Enabling the test mode also +enables the [`test` conditional compilation option]. + +<!-- template:attributes --> +r[attributes.testing.test] +## The `test` attribute + +r[attributes.testing.test.intro] +The *`test` [attribute][attributes]* marks a function to be executed as a test. + +> [!EXAMPLE] +> ```rust,no_run +> # pub fn add(left: u64, right: u64) -> u64 { left + right } +> #[test] +> fn it_works() { +> let result = add(2, 2); +> assert_eq!(result, 4); +> } +> ``` + +r[attributes.testing.test.syntax] +The `test` attribute uses the [MetaWord] syntax. + +r[attributes.testing.test.allowed-positions] +The `test` attribute may only be applied to [free functions] that are monomorphic, that take no arguments, and where the return type implements the [`Termination`] trait. + +> [!NOTE] +> Some of types that implement the [`Termination`] trait include: +> * `()` +> * `Result<T, E> where T: Termination, E: Debug` + +r[attributes.testing.test.duplicates] +Only the first use of `test` on a function has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +<!-- TODO: This is a minor lie. Currently rustc warns that duplicates are ignored, but it then generates multiple test entries with the same name. I would vote for rejecting this in the future. --> + +r[attributes.testing.test.stdlib] +The `test` attribute is exported from the standard library prelude as [`std::prelude::v1::test`]. + +r[attributes.testing.test.enabled] +These functions are only compiled when in test mode. + +> [!NOTE] +> The test mode is enabled by passing the `--test` argument to `rustc` or using `cargo test`. + +r[attributes.testing.test.success] +The test harness calls the returned value's [`report`] method, and classifies the test as passed or failed depending on whether the resulting [`ExitCode`] represents successful termination. +In particular: +* Tests that return `()` pass as long as they terminate and do not panic. +* Tests that return a `Result<(), E>` pass as long as they return `Ok(())`. +* Tests that return `ExitCode::SUCCESS` pass, and tests that return `ExitCode::FAILURE` fail. +* Tests that do not terminate neither pass nor fail. + +> [!EXAMPLE] +> ```rust,no_run +> # use std::io; +> # fn setup_the_thing() -> io::Result<i32> { Ok(1) } +> # fn do_the_thing(s: &i32) -> io::Result<()> { Ok(()) } +> #[test] +> fn test_the_thing() -> io::Result<()> { +> let state = setup_the_thing()?; // expected to succeed +> do_the_thing(&state)?; // expected to succeed +> Ok(()) +> } +> ``` + +<!-- template:attributes --> +r[attributes.testing.ignore] +## The `ignore` attribute + +r[attributes.testing.ignore.intro] +The *`ignore` [attribute][attributes]* can be used with the [`test` attribute][attributes.testing.test] to tell the test harness to not execute that function as a test. + +> [!EXAMPLE] +> ```rust,no_run +> #[test] +> #[ignore] +> fn check_thing() { +> // … +> } +> ``` + +> [!NOTE] +> The `rustc` test harness supports the `--include-ignored` flag to force ignored tests to be run. + +r[attributes.testing.ignore.syntax] +The `ignore` attribute uses the [MetaWord] and [MetaNameValueStr] syntaxes. + +r[attributes.testing.ignore.reason] +The [MetaNameValueStr] form of the `ignore` attribute provides a way to specify a reason why the test is ignored. + +> [!EXAMPLE] +> ```rust,no_run +> #[test] +> #[ignore = "not yet implemented"] +> fn mytest() { +> // … +> } +> ``` + +r[attributes.testing.ignore.allowed-positions] +The `ignore` attribute may only be applied to functions annotated with the `test` attribute. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[attributes.testing.ignore.duplicates] +Only the first use of `ignore` on a function has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +r[attributes.testing.ignore.behavior] +Ignored tests are still compiled when in test mode, but they are not executed. + +<!-- template:attributes --> +r[attributes.testing.should_panic] +## The `should_panic` attribute + +r[attributes.testing.should_panic.intro] +The *`should_panic` [attribute][attributes]* causes a test to pass only if the [test function][attributes.testing.test] to which the attribute is applied panics. + +> [!EXAMPLE] +> ```rust,no_run +> #[test] +> #[should_panic(expected = "values don't match")] +> fn mytest() { +> assert_eq!(1, 2, "values don't match"); +> } +> ``` + +r[attributes.testing.should_panic.syntax] +The `should_panic` attribute has these forms: + +- [MetaWord] + > [!EXAMPLE] + > ```rust,no_run + > #[test] + > #[should_panic] + > fn mytest() { panic!("error: some message, and more"); } + > ``` + +- [MetaNameValueStr] --- The given string must appear within the panic message for the test to pass. + > [!EXAMPLE] + > ```rust,no_run + > #[test] + > #[should_panic = "some message"] + > fn mytest() { panic!("error: some message, and more"); } + > ``` + +- [MetaListNameValueStr] --- As with the [MetaNameValueStr] syntax, the given string must appear within the panic message. + > [!EXAMPLE] + > ```rust,no_run + > #[test] + > #[should_panic(expected = "some message")] + > fn mytest() { panic!("error: some message, and more"); } + > ``` + +r[attributes.testing.should_panic.allowed-positions] +The `should_panic` attribute may only be applied to functions annotated with the `test` attribute. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[attributes.testing.should_panic.duplicates] +Only the first use of `should_panic` on a function has effect. + +> [!NOTE] +> `rustc` lints against any use following the first with a future-compatibility warning. This may become an error in the future. + +r[attributes.testing.should_panic.expected] +When the [MetaNameValueStr] form or the [MetaListNameValueStr] form with the `expected` key is used, the given string must appear somewhere within the panic message for the test to pass. + +r[attributes.testing.should_panic.return] +The return type of the test function must be `()`. + +[`Termination`]: std::process::Termination +[`report`]: std::process::Termination::report +[`test` conditional compilation option]: ../conditional-compilation.md#test +[attributes]: ../attributes.md +[`ExitCode`]: std::process::ExitCode +[free functions]: ../glossary.md#free-item diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/attributes/type_system.md b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/type_system.md new file mode 100644 index 00000000..cecf911e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/attributes/type_system.md @@ -0,0 +1,210 @@ +r[attributes.type-system] +# Type system attributes + +r[attributes.type-system.intro] +The following [attributes] are used for changing how a type can be used. + +r[attributes.type-system.non_exhaustive] +## The `non_exhaustive` attribute + +r[attributes.type-system.non_exhaustive.intro] +The *`non_exhaustive` attribute* indicates that a type or variant may have +more fields or variants added in the future. + +r[attributes.type-system.non_exhaustive.allowed-positions] +It can be applied to [`struct`s][struct], [`enum`s][enum], and `enum` variants. + +r[attributes.type-system.non_exhaustive.syntax] +The `non_exhaustive` attribute uses the [MetaWord] syntax and thus does not +take any inputs. + +r[attributes.type-system.non_exhaustive.same-crate] +Within the defining crate, `non_exhaustive` has no effect. + +```rust +#[non_exhaustive] +pub struct Config { + pub window_width: u16, + pub window_height: u16, +} + +#[non_exhaustive] +pub struct Token; + +#[non_exhaustive] +pub struct Id(pub u64); + +#[non_exhaustive] +pub enum Error { + Message(String), + Other, +} + +pub enum Message { + #[non_exhaustive] Send { from: u32, to: u32, contents: String }, + #[non_exhaustive] Reaction(u32), + #[non_exhaustive] Quit, +} + +// Non-exhaustive structs can be constructed as normal within the defining crate. +let config = Config { window_width: 640, window_height: 480 }; +let token = Token; +let id = Id(4); + +// Non-exhaustive structs can be matched on exhaustively within the defining crate. +let Config { window_width, window_height } = config; +let Token = token; +let Id(id_number) = id; + +let error = Error::Other; +let message = Message::Reaction(3); + +// Non-exhaustive enums can be matched on exhaustively within the defining crate. +match error { + Error::Message(ref s) => { }, + Error::Other => { }, +} + +match message { + // Non-exhaustive variants can be matched on exhaustively within the defining crate. + Message::Send { from, to, contents } => { }, + Message::Reaction(id) => { }, + Message::Quit => { }, +} +``` + +r[attributes.type-system.non_exhaustive.external-crate] +Outside of the defining crate, types annotated with `non_exhaustive` have limitations that +preserve backwards compatibility when new fields or variants are added. + +r[attributes.type-system.non_exhaustive.construction] +Non-exhaustive types cannot be constructed outside of the defining crate: + +- Non-exhaustive variants ([`struct`][struct] or [`enum` variant][enum]) cannot be constructed + with a [StructExpression] \(including with [functional update syntax]). +- The implicitly defined same-named constant of a [unit-like struct][struct], + or the same-named constructor function of a [tuple struct][struct], + has a [visibility] no greater than `pub(crate)`. + That is, if the struct’s visibility is `pub`, then the constant or constructor’s visibility + is `pub(crate)`, and otherwise the visibility of the two items is the same + (as is the case without `#[non_exhaustive]`). +- [`enum`][enum] instances can be constructed. + +The following examples of construction do not compile when outside the defining crate: + +<!-- ignore: requires external crates --> +```rust,ignore +// These are types defined in an upstream crate that have been annotated as +// `#[non_exhaustive]`. +use upstream::{Config, Token, Id, Error, Message}; + +// Cannot construct an instance of `Config`; if new fields were added in +// a new version of `upstream` then this would fail to compile, so it is +// disallowed. +let config = Config { window_width: 640, window_height: 480 }; + +// Cannot construct an instance of `Token`; if new fields were added, then +// it would not be a unit-like struct any more, so the same-named constant +// created by it being a unit-like struct is not public outside the crate; +// this code fails to compile. +let token = Token; + +// Cannot construct an instance of `Id`; if new fields were added, then +// its constructor function signature would change, so its constructor +// function is not public outside the crate; this code fails to compile. +let id = Id(5); + +// Can construct an instance of `Error`; new variants being introduced would +// not result in this failing to compile. +let error = Error::Message("foo".to_string()); + +// Cannot construct an instance of `Message::Send` or `Message::Reaction`; +// if new fields were added in a new version of `upstream` then this would +// fail to compile, so it is disallowed. +let message = Message::Send { from: 0, to: 1, contents: "foo".to_string(), }; +let message = Message::Reaction(0); + +// Cannot construct an instance of `Message::Quit`; if this were converted to +// a tuple enum variant `upstream`, this would fail to compile. +let message = Message::Quit; +``` + +r[attributes.type-system.non_exhaustive.match] +There are limitations when matching on non-exhaustive types outside of the defining crate: + +- When pattern matching on a non-exhaustive variant ([`struct`][struct] or [`enum` variant][enum]), a [StructPattern] must be used which must include a `..`. A tuple enum variant's constructor's [visibility] is reduced to be no greater than `pub(crate)`. +- When pattern matching on a non-exhaustive [`enum`][enum], matching on a variant does not contribute towards the exhaustiveness of the arms. The following examples of matching do not compile when outside the defining crate: + +<!-- ignore: requires external crates --> +```rust, ignore +// These are types defined in an upstream crate that have been annotated as +// `#[non_exhaustive]`. +use upstream::{Config, Token, Id, Error, Message}; + +// Cannot match on a non-exhaustive enum without including a wildcard arm. +match error { + Error::Message(ref s) => { }, + Error::Other => { }, + // would compile with: `_ => {},` +} + +// Cannot match on a non-exhaustive struct without a wildcard. +if let Ok(Config { window_width, window_height }) = config { + // would compile with: `..` +} + +// Cannot match a non-exhaustive unit-like or tuple struct except by using +// braced struct syntax with a wildcard. +// This would compile as `let Token { .. } = token;` +let Token = token; +// This would compile as `let Id { 0: id_number, .. } = id;` +let Id(id_number) = id; + +match message { + // Cannot match on a non-exhaustive struct enum variant without including a wildcard. + Message::Send { from, to, contents } => { }, + // Cannot match on a non-exhaustive tuple or unit enum variant. + Message::Reaction(type) => { }, + Message::Quit => { }, +} +``` + +It's also not allowed to use numeric casts (`as`) on enums that contain any non-exhaustive variants. + +For example, the following enum can be cast because it doesn't contain any non-exhaustive variants: + +```rust +#[non_exhaustive] +pub enum Example { + First, + Second, +} +``` + +However, if the enum contains even a single non-exhaustive variant, casting will result in an error. Consider this modified version of the same enum: + +```rust +#[non_exhaustive] +pub enum EnumWithNonExhaustiveVariants { + First, + #[non_exhaustive] + Second, +} +``` + +<!-- ignore: needs multiple crates --> +```rust,ignore +use othercrate::EnumWithNonExhaustiveVariants; + +// Error: cannot cast an enum with a non-exhaustive variant when it's defined in another crate +let _ = EnumWithNonExhaustiveVariants::First as u8; +``` + +Non-exhaustive types are always considered inhabited in downstream crates. + +[`match`]: ../expressions/match-expr.md +[attributes]: ../attributes.md +[enum]: ../items/enumerations.md +[functional update syntax]: ../expressions/struct-expr.md#functional-update-syntax +[struct]: ../items/structs.md +[visibility]: ../visibility-and-privacy.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/behavior-considered-undefined.md b/stdlib/kvlang/reference/rust/reference-repo/src/behavior-considered-undefined.md new file mode 100644 index 00000000..ff34d0af --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/behavior-considered-undefined.md @@ -0,0 +1,220 @@ +r[undefined] +# Behavior considered undefined + +r[undefined.intro] +Rust code is incorrect if it exhibits any of the behaviors in the following list. This includes code within `unsafe` blocks and `unsafe` functions. `unsafe` only means that avoiding undefined behavior is on the programmer; it does not change anything about the fact that Rust programs must never cause undefined behavior. + +r[undefined.soundness] +It is the programmer's responsibility when writing `unsafe` code to ensure that any safe code interacting with the `unsafe` code cannot trigger these behaviors. `unsafe` code that satisfies this property for any safe client is called *sound*; if `unsafe` code can be misused by safe code to exhibit undefined behavior, it is *unsound*. + +> [!WARNING] +> The following list is not exhaustive; it may grow or shrink. There is no formal model of Rust's semantics for what is and is not allowed in unsafe code, so there may be more behavior considered unsafe. We also reserve the right to make some of the behavior in that list defined in the future. In other words, this list does not say that anything will *definitely* always be undefined in all future Rust versions (but we might make such commitments for some list items in the future). +> +> Please read the [Rustonomicon] before writing unsafe code. + +r[undefined.race] +* Data races. + +r[undefined.pointer-access] +* Accessing (loading from or storing to) a place that is [dangling] or [based on a misaligned pointer]. + +r[undefined.place-projection] +* Performing an offsetting place projection that violates the requirements of [in-bounds pointer arithmetic](pointer#method.offset). An offsetting place projection is a [field expression][project-field], a [tuple index expression][project-tuple], or an [array/slice index expression][project-slice]. + +r[undefined.alias] +* Breaking the pointer aliasing rules. The exact aliasing rules are not determined yet, but here is an outline of the general principles: + + * `&T` must point to memory that is not mutated while they are live (except for data inside an [`UnsafeCell<U>`]). + * `&mut T` must point to memory that is not read or written by any pointer not derived from the reference and that no other reference points to while they are live (with no exceptions). + * `Box<T>` is treated similar to `&'static mut T` for the purpose of these rules. + + These rules apply to *all* references and `Box<T>`, including those stored inside private fields (e.g., if your type has a private field of type `&mut T`, that reference must be unique in the sense described above for as long as values of your type are live). + + The exact liveness duration is not specified, but some bounds exist: + + * For references, the liveness duration is upper-bounded by the syntactic lifetime assigned by the borrow checker; it cannot be live any *longer* than that lifetime. + * Each time a reference or box is dereferenced or reborrowed, it is considered live. + * Each time a reference or box is passed to or returned from a function, it is considered live. + * When a reference (but not a `Box`!) is passed to a function, it is live at least as long as that function call, again except if the `&T` contains an [`UnsafeCell<U>`]. + + All this also applies when values of these types are passed in a (nested) field of a compound type, but not behind pointer indirections. + +r[undefined.immutable] +* Mutating immutable bytes. All bytes reachable through a [const-promoted] expression are immutable, as well as bytes reachable through borrows in `static` and `const` initializers that have been [lifetime-extended] to `'static`. The bytes owned by an immutable binding or immutable `static` are immutable, unless those bytes are part of an [`UnsafeCell<U>`]. + + Moreover, the bytes [pointed to] by a shared reference, including transitively through other references (both shared and mutable) and `Box`es, are immutable; transitivity includes those references stored in fields of compound types. + + A mutation is any write of more than 0 bytes which overlaps with any of the relevant bytes (even if that write does not change the memory contents). + +r[undefined.intrinsic] +* Invoking undefined behavior via compiler intrinsics. + +r[undefined.target-feature] +* Executing code compiled with platform features that the current platform does not support (see [`target_feature`]), *except* if the platform explicitly documents this to be safe. + +r[undefined.call] +* Calling a function with the wrong [call ABI][abi], or unwinding past a stack frame that does not allow unwinding (e.g. by calling a `"C-unwind"` function imported or transmuted as a `"C"` function or function pointer). + +r[undefined.invalid] +* Producing an [invalid value][invalid-values]. "Producing" a value happens any time a value is assigned to or read from a place, passed to a function/primitive operation or returned from a function/primitive operation. + +r[undefined.asm] +* Incorrect use of inline assembly. For more details, refer to the [rules] to follow when writing code that uses inline assembly. + +r[undefined.runtime] +* Violating assumptions of the Rust runtime. Most assumptions of the Rust runtime are currently not explicitly documented. + * For assumptions specifically related to unwinding, see the [panic documentation][unwinding-ffi]. + * The runtime assumes that a Rust stack frame is not deallocated without executing destructors for local variables owned by the stack frame. This assumption can be violated by C functions like `longjmp`. + +> [!NOTE] +> Undefined behavior affects the entire program. For example, calling a function in C that exhibits undefined behavior of C means your entire program contains undefined behaviour that can also affect the Rust code. And vice versa, undefined behavior in Rust can cause adverse affects on code executed by any FFI calls to other languages. + +r[undefined.pointed-to] +## Pointed-to bytes + +The span of bytes a pointer or reference "points to" is determined by the pointer value and the size of the pointee type (using `size_of_val`). + +r[undefined.misaligned] +## Places based on misaligned pointers +[based on a misaligned pointer]: #places-based-on-misaligned-pointers + +r[undefined.misaligned.ptr] +A place is said to be "based on a misaligned pointer" if the last `*` projection during place computation was performed on a pointer that was not aligned for its type. (If there is no `*` projection in the place expression, then this is accessing the field of a local or `static` and rustc will guarantee proper alignment. If there are multiple `*` projections, then each of them incurs a load of the pointer-to-be-dereferenced itself from memory, and each of these loads is subject to the alignment constraint. Note that some `*` projections can be omitted in surface Rust syntax due to automatic dereferencing; we are considering the fully expanded place expression here.) + +For instance, if `ptr` has type `*const S` where `S` has an alignment of 8, then `ptr` must be 8-aligned or else `(*ptr).f` is "based on an misaligned pointer". This is true even if the type of the field `f` is `u8` (i.e., a type with alignment 1). In other words, the alignment requirement derives from the type of the pointer that was dereferenced, *not* the type of the field that is being accessed. + +r[undefined.misaligned.load-store] +Note that a place based on a misaligned pointer only leads to undefined behavior when it is loaded from or stored to. + +r[undefined.misaligned.raw] +`&raw const`/`&raw mut` on such a place is allowed. + +r[undefined.misaligned.reference] +`&`/`&mut` on a place requires the alignment of the field type (or else the program would be "producing an invalid value"), which generally is a less restrictive requirement than being based on an aligned pointer. + +r[undefined.misaligned.packed] +Taking a reference will lead to a compiler error in cases where the field type might be more aligned than the type that contains it, i.e., `repr(packed)`. This means that being based on an aligned pointer is always sufficient to ensure that the new reference is aligned, but it is not always necessary. + +r[undefined.dangling] +## Dangling pointers +[dangling]: #dangling-pointers + +r[undefined.dangling.def] +A reference/pointer is "dangling" if not all of the bytes it [points to] are part of the same live [allocation] (so in particular they all have to be part of *some* allocation). + +> [!NOTE] +> This implies that the dynamic size of a Rust value (as determined by `size_of_val`) must never exceed `isize::MAX`, since it is impossible for a single allocation to be larger than `isize::MAX`. + +> [!NOTE] +> This also implies that if the [size is 0][zero-sized], then the pointer is trivially never "dangling" (even if it is a null pointer). + +r[undefined.validity] +## Invalid values +[invalid-values]: #invalid-values + +r[undefined.validity.def] +The Rust compiler assumes that all values produced during program execution are "valid", and producing an invalid value is hence immediate UB. + +Whether a value is valid depends on the type: + +r[undefined.validity.bool] +* A [`bool`] value must be `false` (`0`) or `true` (`1`). + +r[undefined.validity.fn-pointer] +* A `fn` pointer value must be non-null. + +r[undefined.validity.char] +* A `char` value must not be a surrogate (i.e., must not be in the range `0xD800..=0xDFFF`) and must be equal to or less than `char::MAX`. + +r[undefined.validity.never] +* A `!` value must never exist. + +r[undefined.validity.scalar] +* An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer must be initialized, i.e., must not be obtained from uninitialized memory. + +r[undefined.validity.str] +* A `str` value is treated like `[u8]`, i.e. it must be initialized. + +r[undefined.validity.enum] +* An `enum` must have a valid discriminant, and all fields of the variant indicated by that discriminant must be valid at their respective type. + +r[undefined.validity.struct] +* A `struct`, tuple, and array requires all fields/elements to be valid at their respective type. + +r[undefined.validity.union] +* For a `union`, the exact validity requirements are not decided yet. Obviously, all values that can be created entirely in safe code are valid. If the union has a [zero-sized] field, then every possible value is valid. Further details are [still being debated](https://github.com/rust-lang/unsafe-code-guidelines/issues/438). + +r[undefined.validity.reference-box] +* A reference or [`Box<T>`] must be aligned and non-null, it cannot be [dangling], and it must point to a valid value (in case of dynamically sized types, using the actual dynamic type of the pointee as determined by the [metadata]). Note that the last point (about pointing to a valid value) remains a subject of some debate. + +r[undefined.validity.wide] +* The [metadata] of a wide reference, [`Box<T>`], or raw pointer must match the type of the [unsized tail]: + * `dyn Trait` metadata must be a pointer to a compiler-generated vtable for `Trait`. (For raw pointers, this requirement remains a subject of some debate.) + * Slice (`[T]`) and `str` metadata must be a valid `usize`. + + In addition, for a wide reference or [`Box<T>`], the metadata is invalid if it makes the total size of the pointed-to value (as determined by `size_of_val`) bigger than `isize::MAX`. + + > [!NOTE] + > This bound is on the size of the entire pointed-to value, not just its unsized tail, and it constrains `dyn Trait` metadata just as it does a slice or `str` length. A valid vtable describes an erased type no larger than `isize::MAX`, but a sized prefix can still carry the total past the limit. + +r[undefined.validity.valid-range] +* If a type has a custom range of valid values, then a valid value must be in that range. In the standard library, this affects [`NonNull<T>`] and [`NonZero<T>`]. + + > [!NOTE] + > `rustc` achieves this with the unstable `rustc_layout_scalar_valid_range_*` attributes. + +r[undefined.validity.const-provenance] +* **In [const contexts]**: In addition to what is described above, further provenance-related requirements apply during const evaluation. Any value that holds pure integer data (the `i*`/`u*`/`f*` types as well as `bool` and `char`, enum discriminants, and slice [metadata]) must not carry any provenance. Any value that holds pointer data (references, raw pointers, function pointers, and `dyn Trait` metadata) must either carry no provenance, or all bytes must be fragments of the same original pointer value in the correct order. + + This implies that transmuting or otherwise reinterpreting a pointer (reference, raw pointer, or function pointer) into a non-pointer type (such as integers) is undefined behavior if the pointer had provenance. + + > [!EXAMPLE] + > All of the following are UB: + > + > ```rust,compile_fail + > # use core::mem::MaybeUninit; + > # use core::ptr; + > // We cannot reinterpret a pointer with provenance as an integer, + > // as then the bytes of the integer will have provenance. + > const _: usize = { + > let ptr = &0; + > unsafe { (&raw const ptr as *const usize).read() } + > }; + > + > // We cannot rearrange the bytes of a pointer with provenance and + > // then interpret them as a reference, as then a value holding + > // pointer data will have pointer fragments in the wrong order. + > const _: &i32 = { + > let mut ptr = &0; + > let ptr_bytes = &raw mut ptr as *mut MaybeUninit::<u8>; + > unsafe { ptr::swap(ptr_bytes.add(1), ptr_bytes.add(2)) }; + > ptr + > }; + > ``` + +r[undefined.validity.undef] +**Note:** Uninitialized memory is also implicitly invalid for any type that has a restricted set of valid values. In other words, the only cases in which reading uninitialized memory is permitted are inside `union`s and in "padding" (the gaps between the fields of a type). + +[`bool`]: types/boolean.md +[`const`]: items/constant-items.md +[abi]: items/external-blocks.md#abi +[allocation]: core::ptr#allocation +[const contexts]: const-eval.const-context +[`target_feature`]: attributes/codegen.md#the-target_feature-attribute +[`UnsafeCell<U>`]: std::cell::UnsafeCell +[Rustonomicon]: ../nomicon/index.html +[metadata]: dynamic-sized.pointer-types +[`NonNull<T>`]: core::ptr::NonNull +[`NonZero<T>`]: core::num::NonZero +[place expression context]: expressions.md#place-expressions-and-value-expressions +[rules]: inline-assembly.md#rules-for-inline-assembly +[points to]: #pointed-to-bytes +[pointed to]: #pointed-to-bytes +[project-field]: expressions/field-expr.md +[project-tuple]: expressions/tuple-expr.md#tuple-indexing-expressions +[project-slice]: expressions/array-expr.md#array-and-slice-indexing-expressions +[unsized tail]: dynamic-sized.tail +[unwinding-ffi]: panic.md#unwinding-across-ffi-boundaries +[const-promoted]: destructors.md#constant-promotion +[lifetime-extended]: destructors.md#temporary-lifetime-extension +[zero-sized]: glossary.zst diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/behavior-not-considered-unsafe.md b/stdlib/kvlang/reference/rust/reference-repo/src/behavior-not-considered-unsafe.md new file mode 100644 index 00000000..60f52945 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/behavior-not-considered-unsafe.md @@ -0,0 +1,30 @@ +# Behavior not considered `unsafe` + +The Rust compiler does not consider the following behaviors _unsafe_, though a programmer may (should) find them undesirable, unexpected, or erroneous. + +- Deadlocks +- Leaks of memory and other resources +- Exiting without calling destructors +- Exposing randomized base addresses through pointer leaks + +## Integer overflow + +If a program contains arithmetic overflow, the programmer has made an error. In the following discussion, we maintain a distinction between arithmetic overflow and wrapping arithmetic. The first is erroneous, while the second is intentional. + +When the programmer has enabled `debug_assert!` assertions (for example, by enabling a non-optimized build), implementations must insert dynamic checks that `panic` on overflow. Other kinds of builds may result in `panics` or silently wrapped values on overflow, at the implementation's discretion. + +In the case of implicitly-wrapped overflow, implementations must provide well-defined (even if still considered erroneous) results by using two's complement overflow conventions. + +The integral types provide inherent methods to allow programmers explicitly to perform wrapping arithmetic. For example, `i32::wrapping_add` provides two's complement, wrapping addition. + +The standard library also provides a `Wrapping<T>` newtype which ensures all standard arithmetic operations for `T` have wrapping semantics. + +See [RFC 560] for error conditions, rationale, and more details about integer overflow. + +## Logic errors + +Safe code may impose extra logical constraints that can be checked at neither compile-time nor runtime. If a program breaks such a constraint, the behavior may be unspecified but will not result in undefined behavior. This could include panics, incorrect results, aborts, and non-termination. The behavior may also differ between runs, builds, or kinds of build. + +For example, implementing both `Hash` and `Eq` requires that values considered equal have equal hashes. Another example are data structures like `BinaryHeap`, `BTreeMap`, `BTreeSet`, `HashMap` and `HashSet` which describe constraints on the modification of their keys while they are in the data structure. Violating such constraints is not considered unsafe, yet the program is considered erroneous and its behavior unpredictable. + +[RFC 560]: https://github.com/rust-lang/rfcs/blob/master/text/0560-integer-overflow.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/comments.md b/stdlib/kvlang/reference/rust/reference-repo/src/comments.md new file mode 100644 index 00000000..44ef06fc --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/comments.md @@ -0,0 +1,149 @@ +r[comments] +# Comments + +r[comments.syntax] +```grammar,lexer +@root COMMENT -> + LINE_COMMENT + | INNER_LINE_DOC + | OUTER_LINE_DOC + | INNER_BLOCK_DOC + | OUTER_BLOCK_DOC + | BLOCK_COMMENT + +LINE_COMMENT -> + `//` (~[`/` `!` LF] | `//`) ~LF* + | `//` EOF + | `//` _immediately followed by LF_ + +BLOCK_COMMENT -> + `/*` ^ + ( BLOCK_COMMENT | BLOCK_CHAR )* + `*/` + +INNER_LINE_DOC -> + `//!` ^ LINE_DOC_COMMENT_CONTENT (LF | EOF) + +LINE_DOC_COMMENT_CONTENT -> (!CR ~LF)* + +INNER_BLOCK_DOC -> + `/*!` ^ ( NESTED_BLOCK_DOC_COMMENT | DOC_BLOCK_CHAR )* `*/` + +OUTER_LINE_DOC -> + `///` ^ LINE_DOC_COMMENT_CONTENT (LF | EOF) + +OUTER_BLOCK_DOC -> + `/**` ![`*` `/`] + ^ + ~[`*` CR] + ( NESTED_BLOCK_DOC_COMMENT | DOC_BLOCK_CHAR )* + `*/` + +BLOCK_CHAR -> !`*/` CHAR + +DOC_BLOCK_CHAR -> (!(`*/` | CR) CHAR) + +NESTED_BLOCK_DOC_COMMENT -> + `/*` ( NESTED_BLOCK_DOC_COMMENT | DOC_BLOCK_CHAR )* `*/` +``` + +r[comments.normal] +## Non-doc comments + +r[comments.normal.intro] +Comments follow the general C++ style of line (`//`) and block (`/* ... */`) comment forms. Nested block comments are supported. + +r[comments.normal.tokenization] +Non-doc comments are interpreted as a form of whitespace. + +r[comments.doc] +## Doc comments + +r[comments.doc.syntax] +Line doc comments beginning with exactly _three_ slashes (`///`), and block doc comments (`/** ... */`), both outer doc comments, are interpreted as a special syntax for [`doc` attributes]. + +r[comments.doc.attributes] +That is, they are equivalent to writing `#[doc="..."]` around the body of the comment, i.e., `/// Foo` turns into `#[doc=" Foo"]` and `/** Bar */` turns into `#[doc=" Bar "]`. They must therefore appear before something that accepts an outer attribute. + +r[comments.doc.inner-syntax] +Line comments beginning with `//!` and block comments `/*! ... */` are doc comments that apply to the parent of the comment, rather than the item that follows. + +r[comments.doc.inner-attributes] +That is, they are equivalent to writing `#![doc="..."]` around the body of the comment. `//!` comments are usually used to document modules that occupy a source file. + +r[comments.doc.bare-crs] +The character `U+000D` (CR) is not allowed in doc comments. + +> [!NOTE] +> It is conventional for doc comments to contain Markdown, as expected by `rustdoc`. However, the comment syntax does not respect any internal Markdown. ``/** `glob = "*/*.rs";` */`` terminates the comment at the first `*/`, and the remaining code would cause a syntax error. This slightly limits the content of block doc comments compared to line doc comments. + +> [!NOTE] +> The sequence `U+000D` (CR) immediately followed by `U+000A` (LF) would have been previously transformed into a single `U+000A` (LF). + +## Examples + +```rust +//! A doc comment that applies to the implicit anonymous module of this crate + +pub mod outer_module { + + //! - Inner line doc + //!! - Still an inner line doc (but with a bang at the beginning) + + /*! - Inner block doc */ + /*!! - Still an inner block doc (but with a bang at the beginning) */ + + // - Only a comment + /// - Outer line doc (exactly 3 slashes) + //// - Only a comment + + /* - Only a comment */ + /** - Outer block doc (exactly) 2 asterisks */ + /*** - Only a comment */ + + pub mod inner_module {} + + pub mod nested_comments { + /* In Rust /* we can /* nest comments */ */ */ + + // All three types of block comments can contain or be nested inside + // any other type: + + /* /* */ /** */ /*! */ */ + /*! /* */ /** */ /*! */ */ + /** /* */ /** */ /*! */ */ + pub mod dummy_item {} + } + + pub mod degenerate_cases { + // empty inner line doc + //! + + // empty inner block doc + /*!*/ + + // empty line comment + // + + // empty outer line doc + /// + + // empty block comment + /**/ + + pub mod dummy_item {} + + // empty 2-asterisk block isn't a doc block, it is a block comment + /***/ + + } + + /* The next one isn't allowed because outer doc comments + require an item that will receive the doc */ + + /// Where is my item? +# mod boo {} +} +``` + +[`doc` attributes]: ../rustdoc/the-doc-attribute.html diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/conditional-compilation.md b/stdlib/kvlang/reference/rust/reference-repo/src/conditional-compilation.md new file mode 100644 index 00000000..700eda30 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/conditional-compilation.md @@ -0,0 +1,530 @@ +r[cfg] +# Conditional compilation + +r[cfg.syntax] +```grammar,configuration +ConfigurationPredicate -> + ConfigurationOption + | ConfigurationAll + | ConfigurationAny + | ConfigurationNot + | `true` + | `false` + +ConfigurationOption -> + IDENTIFIER ( `=` ( STRING_LITERAL | RAW_STRING_LITERAL ) )? + +ConfigurationAll -> + `all` `(` ConfigurationPredicateList? `)` + +ConfigurationAny -> + `any` `(` ConfigurationPredicateList? `)` + +ConfigurationNot -> + `not` `(` ConfigurationPredicate `)` + +ConfigurationPredicateList -> + ConfigurationPredicate (`,` ConfigurationPredicate)* `,`? +``` + +r[cfg.intro] +*Conditionally compiled source code* is source code that is compiled only under certain conditions. + +r[cfg.attributes-macro] +Source code can be made conditionally compiled using the [`cfg`] and [`cfg_attr`] [attributes] and the built-in [`cfg!`] and [`cfg_select!`] [macros]. + +r[cfg.conditional] +Whether to compile can depend on the target architecture of the compiled crate, arbitrary values passed to the compiler, and other things further described below. + +r[cfg.predicate] +Each form of conditional compilation takes a _configuration predicate_ that evaluates to true or false. The predicate is one of the following: + +r[cfg.predicate-option] +* A configuration option. The predicate is true if the option is set, and false if it is unset. + +r[cfg.predicate-all] +* `all()` with a comma-separated list of configuration predicates. It is true if all of the given predicates are true, or if the list is empty. + +r[cfg.predicate-any] +* `any()` with a comma-separated list of configuration predicates. It is true if at least one of the given predicates is true. If there are no predicates, it is false. + +r[cfg.predicate-not] +* `not()` with a configuration predicate. It is true if its predicate is false and false if its predicate is true. + +r[cfg.predicate-literal] +* `true` or `false` literals, which are always true or false respectively. + +r[cfg.option-spec] +_Configuration options_ are either names or key-value pairs, and are either set or unset. + +r[cfg.option-name] +Names are written as a single identifier, such as `unix`. + +r[cfg.option-key-value] +Key-value pairs are written as an identifier, `=`, and then a string, such as `target_arch = "x86_64"`. + +> [!NOTE] +> Whitespace around the `=` is ignored, so `foo="bar"` and `foo = "bar"` are equivalent. + +r[cfg.option-key-uniqueness] +Keys do not need to be unique. For example, both `feature = "std"` and `feature = "serde"` can be set at the same time. + +r[cfg.options.set] +## Set configuration options + +r[cfg.options.intro] +Which configuration options are set is determined statically during the compilation of the crate. + +r[cfg.options.target] +Some options are _compiler-set_ based on data about the compilation. + +r[cfg.options.other] +Other options are _arbitrarily-set_ based on input passed to the compiler outside of the code. + +r[cfg.options.crate] +It is not possible to set a configuration option from within the source code of the crate being compiled. + +> [!NOTE] +> For `rustc`, arbitrary-set configuration options are set using the [`--cfg`] flag. Configuration values for a specified target can be displayed with `rustc --print cfg --target $TARGET`. + +> [!NOTE] +> Configuration options with the key `feature` are a convention used by [Cargo][cargo-feature] for specifying compile-time options and optional dependencies. + +r[cfg.target_arch] +### `target_arch` + +r[cfg.target_arch.def] +Key-value option set once with the target's CPU architecture. The value is similar to the first element of the platform's target triple, but not identical. + +r[cfg.target_arch.values] +Example values: + +* `"x86"` +* `"x86_64"` +* `"mips"` +* `"powerpc"` +* `"powerpc64"` +* `"arm"` +* `"aarch64"` + +r[cfg.target_feature] +### `target_feature` + +r[cfg.target_feature.def] +Key-value option set for each platform feature available for the current compilation target. + +r[cfg.target_feature.values] +Example values: + +* `"avx"` +* `"avx2"` +* `"crt-static"` +* `"rdrand"` +* `"sse"` +* `"sse2"` +* `"sse4.1"` + +See the [`target_feature` attribute] for more details on the available features. + +r[cfg.target_feature.crt_static] +An additional feature of `crt-static` is available to the `target_feature` option to indicate that a [static C runtime] is available. + +r[cfg.target_os] +### `target_os` + +r[cfg.target_os.def] +Key-value option set once with the target's operating system. This value is similar to the second and third element of the platform's target triple. + +r[cfg.target_os.values] +Example values: + +* `"windows"` +* `"macos"` +* `"ios"` +* `"linux"` +* `"android"` +* `"freebsd"` +* `"dragonfly"` +* `"openbsd"` +* `"netbsd"` +* `"none"` (typical for embedded targets) + +r[cfg.target_family] +### `target_family` + +r[cfg.target_family.def] +Key-value option providing a more generic description of a target, such as the family of the operating systems or architectures that the target generally falls into. Any number of `target_family` key-value pairs can be set. + +r[cfg.target_family.values] +Example values: + +* `"unix"` +* `"windows"` +* `"wasm"` +* Both `"unix"` and `"wasm"` + +r[cfg.target_family.unix] +### `unix` and `windows` + +`unix` is set if `target_family = "unix"` is set. + +r[cfg.target_family.windows] +`windows` is set if `target_family = "windows"` is set. + +r[cfg.target_env] +### `target_env` + +r[cfg.target_env.def] +Key-value option set with further disambiguating information about the target platform with information about the ABI or `libc` used. For historical reasons, this value is only defined as not the empty-string when actually needed for disambiguation. Thus, for example, on many GNU platforms, this value will be empty. This value is similar to the fourth element of the platform's target triple. One difference is that embedded ABIs such as `gnueabihf` will simply define `target_env` as `"gnu"`. + +r[cfg.target_env.values] +Example values: + +* `""` +* `"gnu"` +* `"msvc"` +* `"musl"` +* `"sgx"` +* `"sim"` +* `"macabi"` + +r[cfg.target_abi] +### `target_abi` + +r[cfg.target_abi.def] +Key-value option set to further disambiguate the target with information about the target ABI. + +r[cfg.target_abi.disambiguation] +For historical reasons, this value is only defined as not the empty-string when actually needed for disambiguation. Thus, for example, on many GNU platforms, this value will be empty. + +r[cfg.target_abi.values] +Example values: + +* `""` +* `"llvm"` +* `"eabihf"` +* `"abi64"` + +r[cfg.target_endian] +### `target_endian` + +Key-value option set once with either a value of "little" or "big" depending on the endianness of the target's CPU. + +r[cfg.target_pointer_width] +### `target_pointer_width` + +r[cfg.target_pointer_width.def] +Key-value option set once with the target's pointer width in bits. + +r[cfg.target_pointer_width.values] +Example values: + +* `"16"` +* `"32"` +* `"64"` + +r[cfg.target_vendor] +### `target_vendor` + +r[cfg.target_vendor.def] +Key-value option set once with the vendor of the target. + +r[cfg.target_vendor.values] +Example values: + +* `"apple"` +* `"fortanix"` +* `"pc"` +* `"unknown"` + +r[cfg.target_has_atomic] +### `target_has_atomic` + +r[cfg.target_has_atomic.def] +Key-value option set for each bit width that the target supports atomic loads, stores, and compare-and-swap operations. + +r[cfg.target_has_atomic.stdlib] +When this cfg is present, all of the stable [`core::sync::atomic`] APIs are available for the relevant atomic width. + +r[cfg.target_has_atomic.values] +Possible values: + +* `"8"` +* `"16"` +* `"32"` +* `"64"` +* `"128"` +* `"ptr"` + +r[cfg.target_has_atomic_primitive_alignment] +### `target_has_atomic_primitive_alignment` + +r[cfg.target_has_atomic_primitive_alignment.def] +Key-value option set for each bit width where the [atomic][core::sync::atomic] type has the same alignment as the corresponding integer type. + +> [!NOTE] +> The alignment is usually the same for a given bit width. However, on some targets such as 32-bit x86, 64-bit atomic types such as [`AtomicI64`][core::sync::atomic::AtomicI64] have an alignment of 8 bytes while `i64` is only aligned to 4 bytes. In this situation, `target_has_atomic_primitive_alignment = "64"` is not set. + +r[cfg.target_has_atomic_primitive_alignment.values] +Possible values: + +* `"8"` +* `"16"` +* `"32"` +* `"64"` +* `"128"` +* `"ptr"` + +r[cfg.test] +### `test` + +Enabled when compiling the test harness. Done with `rustc` by using the [`--test`] flag. See [Testing] for more on testing support. + +r[cfg.debug_assertions] +### `debug_assertions` + +Enabled by default when compiling without optimizations. This can be used to enable extra debugging code in development but not in production. For example, it controls the behavior of the standard library's [`debug_assert!`] macro. + +r[cfg.proc_macro] +### `proc_macro` + +Set when the crate being compiled is being compiled with the `proc_macro` [crate type]. + +r[cfg.panic] +### `panic` + +r[cfg.panic.def] +Key-value option set depending on the [panic strategy]. Note that more values may be added in the future. + +r[cfg.panic.values] +Example values: + +* `"abort"` +* `"unwind"` + +[panic strategy]: panic.md#panic-strategy + +## Forms of conditional compilation + +<!-- template:attributes --> +r[cfg.attr] +### The `cfg` attribute + +r[cfg.attr.intro] +The *`cfg` [attribute]* conditionally includes the form to which it is attached based on a configuration predicate. + +> [!EXAMPLE] +> ```rust +> // The function is only included in the build when compiling for macOS +> #[cfg(target_os = "macos")] +> fn macos_only() { +> // ... +> } +> +> // This function is only included when either foo or bar is defined +> #[cfg(any(foo, bar))] +> fn needs_foo_or_bar() { +> // ... +> } +> +> // This function is only included when compiling for a unixish OS with a 32-bit +> // architecture +> #[cfg(all(unix, target_pointer_width = "32"))] +> fn on_32bit_unix() { +> // ... +> } +> +> // This function is only included when foo is not defined +> #[cfg(not(foo))] +> fn needs_not_foo() { +> // ... +> } +> +> // This function is only included when the panic strategy is set to unwind +> #[cfg(panic = "unwind")] +> fn when_unwinding() { +> // ... +> } +> ``` + +r[cfg.attr.syntax] +The syntax for the `cfg` attribute is: + +```grammar,configuration +@root CfgAttribute -> `cfg` `(` ConfigurationPredicate `)` +``` + +r[cfg.attr.allowed-positions] +The `cfg` attribute may be used anywhere attributes are allowed. + +r[cfg.attr.duplicates] +The `cfg` attribute may be used any number of times on a form. The form to which the attributes are attached will not be included if any of the `cfg` predicates are false except as described in [cfg.attr.crate-level-attrs]. + +r[cfg.attr.effect] +If the predicates are true, the form is rewritten to not have the `cfg` attributes on it. If any predicate is false, the form is removed from the source code. + +r[cfg.attr.crate-level-attrs] +When a crate-level `cfg` has a false predicate, the crate itself still exists. Any crate attributes preceding the `cfg` are kept, and any crate attributes following the `cfg` are removed as well as removing all of the following crate contents. + +> [!EXAMPLE] +> The behavior of not removing the preceding attributes allows you to do things such as include `#![no_std]` to avoid linking `std` even if a `#![cfg(...)]` has otherwise removed the contents of the crate. For example: +> +> <!-- ignore: test infrastructure can't handle no_std --> +> ```rust,ignore +> // This `no_std` attribute is kept even though the crate-level `cfg` +> // attribute is false. +> #![no_std] +> #![cfg(false)] +> +> // This function is not included. +> pub fn example() {} +> ``` + +<!-- template:attributes --> +r[cfg.cfg_attr] +### The `cfg_attr` attribute + +r[cfg.cfg_attr.intro] +The *`cfg_attr` [attribute]* conditionally includes attributes based on a configuration predicate. + +> [!EXAMPLE] +> The following module will either be found at `linux.rs` or `windows.rs` based on the target. +> +> <!-- ignore: `mod` needs multiple files --> +> ```rust,ignore +> #[cfg_attr(target_os = "linux", path = "linux.rs")] +> #[cfg_attr(windows, path = "windows.rs")] +> mod os; +> ``` + +r[cfg.cfg_attr.syntax] +The syntax for the `cfg_attr` attribute is: + +```grammar,configuration +@root CfgAttrAttribute -> `cfg_attr` `(` ConfigurationPredicate `,` CfgAttrs? `)` + +CfgAttrs -> Attr (`,` Attr)* `,`? +``` + +r[cfg.cfg_attr.allowed-positions] +The `cfg_attr` attribute may be used anywhere attributes are allowed. + +r[cfg.cfg_attr.duplicates] +The `cfg_attr` attribute may be used any number of times on a form. + +r[cfg.cfg_attr.attr-restriction] +The [`crate_type`] and [`crate_name`] attributes cannot be used with `cfg_attr`. + +r[cfg.cfg_attr.behavior] +When the configuration predicate is true, `cfg_attr` expands out to the attributes listed after the predicate. + +r[cfg.cfg_attr.attribute-list] +Zero, one, or more attributes may be listed. Multiple attributes will each be expanded into separate attributes. + +> [!EXAMPLE] +> <!-- ignore: fake attributes --> +> ```rust,ignore +> #[cfg_attr(feature = "magic", sparkles, crackles)] +> fn bewitched() {} +> +> // When the `magic` feature flag is enabled, the above will expand to: +> #[sparkles] +> #[crackles] +> fn bewitched() {} +> ``` + +> [!NOTE] +> The `cfg_attr` can expand to another `cfg_attr`. For example, `#[cfg_attr(target_os = "linux", cfg_attr(feature = "multithreaded", some_other_attribute))]` is valid. This example would be equivalent to `#[cfg_attr(all(target_os = "linux", feature = "multithreaded"), some_other_attribute)]`. + +r[cfg.macro] +### The `cfg` macro + +The built-in `cfg` macro takes in a single configuration predicate and evaluates to the `true` literal when the predicate is true and the `false` literal when it is false. + +For example: + +```rust +let machine_kind = if cfg!(unix) { + "unix" +} else if cfg!(windows) { + "windows" +} else { + "unknown" +}; + +println!("I'm running on a {} machine!", machine_kind); +``` + +r[cfg.cfg_select] +### The `cfg_select` macro + +r[cfg.cfg_select.intro] +The built-in [`cfg_select!`][std::cfg_select] macro can be used to select code at compile-time based on multiple configuration predicates. + +> [!EXAMPLE] +> ```rust +> cfg_select! { +> unix => { +> fn foo() { /* unix specific functionality */ } +> } +> target_pointer_width = "32" => { +> fn foo() { /* non-unix, 32-bit functionality */ } +> } +> _ => { +> fn foo() { /* fallback implementation */ } +> } +> } +> +> let is_unix_str = cfg_select! { +> unix => "unix", +> _ => "not unix", +> }; +> ``` + +r[cfg.cfg_select.syntax] +```grammar,configuration +@root CfgSelect -> CfgSelectArms? + +CfgSelectArms -> + CfgSelectConfigurationPredicate `=>` + ( + `{` ^ TokenTree `}` `,`? CfgSelectArms? + | ExpressionWithBlockNoAttrs `,`? CfgSelectArms? + | ExpressionWithoutBlockNoAttrs ( `,` CfgSelectArms? )? + ) + +CfgSelectConfigurationPredicate -> + ConfigurationPredicate | `_` +``` + +r[cfg.cfg_select.first-arm] +`cfg_select` expands to the payload of the first arm whose configuration predicate evaluates to true. + +r[cfg.cfg_select.braces] +If the entire payload is wrapped in curly braces, the braces are removed during expansion. + +r[cfg.cfg_select.wildcard] +The configuration predicate `_` always evaluates to true. + +r[cfg.cfg_select.fallthrough] +It is a compile error if none of the predicates evaluate to true. + +r[cfg.cfg_select.well-formed] +Each right-hand side must be a syntactically valid expansion for the position in which the macro is invoked. + +[Testing]: attributes/testing.md +[`--cfg`]: ../rustc/command-line-arguments.html#--cfg-configure-the-compilation-environment +[`--test`]: ../rustc/command-line-arguments.html#--test-build-a-test-harness +[`cfg`]: #the-cfg-attribute +[`cfg!`]: #the-cfg-macro +[`cfg_attr`]: #the-cfg_attr-attribute +[`cfg_select!`]: #the-cfg_select-macro +[`crate_name`]: crates-and-source-files.md#the-crate_name-attribute +[`crate_type`]: linkage.md +[`target_feature` attribute]: attributes/codegen.md#the-target_feature-attribute +[attribute]: attributes.md +[attributes]: attributes.md +[cargo-feature]: ../cargo/reference/features.html +[crate type]: linkage.md +[macros]: macros.md +[static C runtime]: linkage.md#static-and-dynamic-c-runtimes diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/const_eval.md b/stdlib/kvlang/reference/rust/reference-repo/src/const_eval.md new file mode 100644 index 00000000..c06b343b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/const_eval.md @@ -0,0 +1,343 @@ +r[const-eval] +# Constant evaluation + +r[const-eval.intro] +Constant evaluation is the process of computing the result of [expressions] during compilation. Only a subset of all expressions can be evaluated at compile-time. + +r[const-eval.const-expr] +## Constant expressions + +r[const-eval.const-expr.intro] +Certain forms of expressions, called constant expressions, can be evaluated at compile time. + +r[const-eval.const-expr.const-context] +Expressions in a [const context] must be constant expressions. + +r[const-eval.const-expr.evaluation] +Expressions in const contexts are always evaluated at compile time. + +r[const-eval.const-expr.runtime-context] +Outside of const contexts, constant expressions *may* be, but are not guaranteed to be, evaluated at compile time. + +r[const-eval.const-expr.error] +Behaviors such as out of bounds [array indexing] or [overflow] are compiler errors if the value must be evaluated at compile time (i.e. in const contexts). Otherwise, these behaviors are warnings, but will likely panic at run-time. + +r[const-eval.const-expr.list] +The following expressions are constant expressions, so long as any operands are also constant expressions and do not cause any [`Drop::drop`][destructors] calls to be run. + +r[const-eval.const-expr.literal] +* [Literals]. + +r[const-eval.const-expr.parameter] +* [Const parameters]. + +r[const-eval.const-expr.path-item] +* [Paths] to [functions] and [constants]. Recursively defining constants is not allowed. + +r[const-eval.const-expr.path-static] +* Paths to [statics] with these restrictions: + * Writes to `static` items are not allowed in any constant evaluation context. + * Reads from `extern` statics are not allowed in any constant evaluation context. + * If the evaluation is *not* carried out in an initializer of a `static` item, then reads from any mutable `static` are not allowed. A mutable `static` is a `static mut` item, or a `static` item with an interior-mutable type. + + These requirements are checked only when the constant is evaluated. In other words, having such accesses syntactically occur in const contexts is allowed as long as they never get executed. + +r[const-eval.const-expr.tuple] +* [Tuple expressions]. + +r[const-eval.const-expr.array] +* [Array expressions]. + +r[const-eval.const-expr.constructor] +* [Struct expressions]. + +r[const-eval.const-expr.block] +* [Block expressions], including `unsafe` and `const` blocks. + * [let statements] and thus irrefutable [patterns], including mutable bindings + * [assignment expressions] + * [compound assignment expressions] + * [expression statements] + +r[const-eval.const-expr.field] +* [Field expressions]. + +r[const-eval.const-expr.index] +* [Array and slice indexing expressions][array indexing], where the index is a `usize`. + +r[const-eval.const-expr.range] +* [Range expressions]. + +r[const-eval.const-expr.closure] +* [Closure expressions] which don't capture variables from the environment. + +r[const-eval.const-expr.builtin-arith-logic] +* Built-in [negation], [arithmetic], [logical], [comparison] or [lazy boolean] operators used on integer and floating point types, `bool`, and `char`. + +r[const-eval.const-expr.borrows] +* All forms of [borrow]s, including raw borrows, except borrows of expressions whose temporary scopes would be extended (see [temporary lifetime extension]) to the end of the program and which are either: + * Mutable borrows. + * Shared borrows of expressions that result in values with [interior mutability]. + + ```rust,compile_fail,E0764 + // Due to being in tail position, this borrow extends the scope of the + // temporary to the end of the program. Since the borrow is mutable, + // this is not allowed in a const expression. + const C: &u8 = &mut 0; // ERROR not allowed + ``` + + ```rust,compile_fail,E0764 + // Const blocks are similar to initializers of `const` items. + let _: &u8 = const { &mut 0 }; // ERROR not allowed + ``` + + ```rust,compile_fail,E0492 + # use core::sync::atomic::AtomicU8; + // This is not allowed as 1) the temporary scope is extended to the + // end of the program and 2) the temporary has interior mutability. + const C: &AtomicU8 = &AtomicU8::new(0); // ERROR not allowed + ``` + + ```rust,compile_fail,E0492 + # use core::sync::atomic::AtomicU8; + // As above. + let _: &_ = const { &AtomicU8::new(0) }; // ERROR not allowed + ``` + + ```rust + # #![allow(static_mut_refs)] + // Even though this borrow is mutable, it's not of a temporary, so + // this is allowed. + const C: &u8 = unsafe { static mut S: u8 = 0; &mut S }; // OK + ``` + + ```rust + # use core::sync::atomic::AtomicU8; + // Even though this borrow is of a value with interior mutability, + // it's not of a temporary, so this is allowed. + const C: &AtomicU8 = { + static S: AtomicU8 = AtomicU8::new(0); &S // OK + }; + ``` + + ```rust + # use core::sync::atomic::AtomicU8; + // This shared borrow of an interior mutable temporary is allowed + // because its scope is not extended. + const C: () = { _ = &AtomicU8::new(0); }; // OK + ``` + + ```rust + // Even though the borrow is mutable and the temporary lives to the + // end of the program due to promotion, this is allowed because the + // borrow is not in tail position and so the scope of the temporary + // is not extended via temporary lifetime extension. + const C: () = { let _: &'static mut [u8] = &mut []; }; // OK + // ~~ + // Promoted temporary. + ``` + + > [!NOTE] + > In other words --- to focus on what's allowed rather than what's not allowed --- shared borrows of interior mutable data and mutable borrows are only allowed in a [const context] when the borrowed [place expression] is *transient*, *indirect*, or *static*. + > + > A place expression is *transient* if it is a variable local to the current const context or an expression whose temporary scope is contained inside the current const context. + > + > ```rust + > // The borrow is of a variable local to the initializer, therefore + > // this place expression is transient. + > const C: () = { let mut x = 0; _ = &mut x; }; + > ``` + > + > ```rust + > // The borrow is of a temporary whose scope has not been extended, + > // therefore this place expression is transient. + > const C: () = { _ = &mut 0u8; }; + > ``` + > + > ```rust + > // When a temporary is promoted but not lifetime extended, its + > // place expression is still treated as transient. + > const C: () = { let _: &'static mut [u8] = &mut []; }; + > ``` + > + > A place expression is *indirect* if it is a [dereference expression]. + > + > ```rust + > const C: () = { _ = &mut *(&mut 0); }; + > ``` + > + > A place expression is *static* if it is a `static` item. + > + > ```rust + > # #![allow(static_mut_refs)] + > const C: &u8 = unsafe { static mut S: u8 = 0; &mut S }; + > ``` + + > [!NOTE] + > One surprising consequence of these rules is that we allow this, + > + > ```rust + > const C: &[u8] = { let x: &mut [u8] = &mut []; x }; // OK + > // ~~~~~~~ + > // Empty arrays are promoted even behind mutable borrows. + > ``` + > + > but we disallow this similar code: + > + > ```rust,compile_fail,E0764 + > const C: &[u8] = &mut []; // ERROR + > // ~~~~~~~ + > // Tail expression. + > ``` + > + > The difference between these is that, in the first, the empty array is [promoted] but its scope does not undergo [temporary lifetime extension], so we consider the [place expression] to be transient (even though after promotion the place indeed lives to the end of the program). In the second, the scope of the empty array temporary does undergo lifetime extension, and so it is rejected due to being a mutable borrow of a lifetime-extended temporary (and therefore borrowing a non-transient place expression). + > + > The effect is surprising because temporary lifetime extension, in this case, causes less code to compile than would without it. + > + > See [issue #143129](https://github.com/rust-lang/rust/issues/143129) for more details. + +r[const-eval.const-expr.deref] +* [Dereference expressions]. + + ```rust,no_run + # use core::cell::UnsafeCell; + const _: u8 = unsafe { + let x: *mut u8 = &raw mut *&mut 0; + // ^^^^^^^ + // Dereference of mutable reference. + *x = 1; // Dereference of mutable pointer. + *(x as *const u8) // Dereference of constant pointer. + }; + const _: u8 = unsafe { + let x = &UnsafeCell::new(0); + *x.get() = 1; // Mutation of interior mutable value. + *x.get() + }; + ``` + +r[const-eval.const-expr.group] + +* [Grouped] expressions. + +r[const-eval.const-expr.cast] +* [Cast] expressions, except + * pointer to address casts and + * function pointer to address casts. + +r[const-eval.const-expr.const-fn] +* Calls of [const functions] and const methods. + +r[const-eval.const-expr.loop] +* [loop] and [while] expressions. + +r[const-eval.const-expr.if-match] +* [if] and [match] expressions. + +r[const-eval.const-context] +## Const context +[const context]: #const-context + +r[const-eval.const-context.def] +A _const context_ is one of the following: + +r[const-eval.const-context.array-length] +* [Array type length expressions] + +r[const-eval.const-context.repeat-length] +* [Array repeat length expressions][array expressions] + +r[const-eval.const-context.init] +* The initializer of + * [constants] + * [statics] + * [enum discriminants] + +r[const-eval.const-context.generic] +* A [const generic argument] + +r[const-eval.const-context.block] +* A [const block] + +r[const-eval.const-context.outer-generics] +Array type length expressions, array repeat length expressions, and const generic arguments are restricted in their use of outer generic parameters: such an expression must either be a single const generic parameter, or an expression that does not reference any generic parameters. + +r[const-eval.const-fn] +## Const functions + +r[const-eval.const-fn.intro] +A _const function_ is a function that can be called from a const context. It is defined with the `const` qualifier, and also includes [tuple struct] and [tuple enum variant] constructors. + +> [!EXAMPLE] +> ```rust +> const fn square(x: i32) -> i32 { x * x } +> +> const VALUE: i32 = square(12); +> ``` + +r[const-eval.const-fn.const-context] +When called from a const context, a const function is interpreted by the compiler at compile time. The interpretation happens in the environment of the compilation target and not the host. So `usize` is `32` bits if you are compiling against a `32` bit system, irrelevant of whether you are building on a `64` bit or a `32` bit system. + +r[const-eval.const-fn.outside-context] +When a const function is called from outside a const context, it behaves the same as if it did not have the `const` qualifier. + +r[const-eval.const-fn.body-restriction] +The body of a const function may only use [constant expressions]. + +r[const-eval.const-fn.async] +Const functions are not allowed to be [async]. + +r[const-eval.const-fn.type-restrictions] +The types of a const function's parameters and return type are restricted to those that are compatible with a const context. +<!-- TODO: Define the type restrictions. --> + +[arithmetic]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[array expressions]: expressions/array-expr.md +[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions +[array type length expressions]: types/array.md +[assignment expressions]: expressions/operator-expr.md#assignment-expressions +[async]: items/functions.md#async-functions +[compound assignment expressions]: expressions/operator-expr.md#compound-assignment-expressions +[block expressions]: expressions/block-expr.md +[borrow]: expressions/operator-expr.md#borrow-operators +[cast]: expressions/operator-expr.md#type-cast-expressions +[closure expressions]: expressions/closure-expr.md +[comparison]: expressions/operator-expr.md#comparison-operators +[const block]: expressions/block-expr.md#const-blocks +[const functions]: items/functions.md#const-functions +[const generic argument]: items/generics.md#const-generics +[const generic parameters]: items/generics.md#const-generics +[constant expressions]: #constant-expressions +[constants]: items/constant-items.md +[Const parameters]: items/generics.md +[dereference expression]: expr.deref +[dereference expressions]: expr.deref +[destructors]: destructors.md +[enum discriminants]: items/enumerations.md#discriminants +[expression statements]: statements.md#expression-statements +[expressions]: expressions.md +[`extern` statics]: items/external-blocks.md#statics +[field expressions]: expressions/field-expr.md +[functions]: items/functions.md +[grouped]: expressions/grouped-expr.md +[interior mutability]: interior-mutability.md +[if]: expressions/if-expr.md#if-expressions +[lazy boolean]: expressions/operator-expr.md#lazy-boolean-operators +[let statements]: statements.md#let-statements +[literals]: expressions/literal-expr.md +[logical]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[loop]: expressions/loop-expr.md#infinite-loops +[match]: expressions/match-expr.md +[negation]: expressions/operator-expr.md#negation-operators +[overflow]: expressions/operator-expr.md#overflow +[paths]: expressions/path-expr.md +[patterns]: patterns.md +[place expression]: expr.place-value.place-memory-location +[promoted expression]: destructors.md#constant-promotion +[promoted]: destructors.md#constant-promotion +[range expressions]: expressions/range-expr.md +[statics]: items/static-items.md +[Struct expressions]: expressions/struct-expr.md +[temporary lifetime extension]: destructors.scope.lifetime-extension +[tuple enum variant]: items/enumerations.md +[tuple expressions]: expressions/tuple-expr.md +[tuple struct]: items/structs.md +[while]: expressions/loop-expr.md#predicate-loops diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/crates-and-source-files.md b/stdlib/kvlang/reference/rust/reference-repo/src/crates-and-source-files.md new file mode 100644 index 00000000..68dfa61b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/crates-and-source-files.md @@ -0,0 +1,142 @@ +r[crate] +# Crates and source files + +r[crate.syntax] +```grammar,items +@root Crate -> + InnerAttribute* + Item* +``` + +> [!NOTE] +> Although Rust, like any other language, can be implemented by an interpreter as well as a compiler, the only existing implementation is a compiler, and the language has always been designed to be compiled. For these reasons, this section assumes a compiler. + +r[crate.compile-time] +Rust's semantics obey a *phase distinction* between compile-time and run-time.[^phase-distinction] Semantic rules that have a *static interpretation* govern the success or failure of compilation, while semantic rules that have a *dynamic interpretation* govern the behavior of the program at run-time. + +r[crate.unit] +The compilation model centers on artifacts called _crates_. Each compilation processes a single crate in source form, and if successful, produces a single crate in binary form: either an executable or some sort of library.[^cratesourcefile] + +r[crate.module] +A _crate_ is a unit of compilation and linking, as well as versioning, distribution, and runtime loading. A crate contains a _tree_ of nested [module] scopes. The top level of this tree is a module that is anonymous (from the point of view of paths within the module) and any item within a crate has a canonical [module path] denoting its location within the crate's module tree. + +r[crate.input-source] +The Rust compiler is always invoked with a single source file as input, and always produces a single output crate. The processing of that source file may result in other source files being loaded as modules. Source files have the extension `.rs`. + +r[crate.module-def] +A Rust source file describes a module, the name and location of which — in the module tree of the current crate — are defined from outside the source file: either by an explicit [Module][grammar-Module] item in a referencing source file, or by the name of the crate itself. + +r[crate.inline-module] +Every source file is a module, but not every module needs its own source file: [module definitions][module] can be nested within one file. + +r[crate.items] +Each source file contains a sequence of zero or more [Item] definitions, and may optionally begin with any number of [attributes] that apply to the containing module, most of which influence the behavior of the compiler. + +r[crate.attributes] +The anonymous crate module can have additional attributes that apply to the crate as a whole. + +> [!NOTE] +> The file's contents may be preceded by a [shebang]. + +```rust +// Specify the crate name. +#![crate_name = "projx"] + +// Specify the type of output artifact. +#![crate_type = "lib"] + +// Turn on a warning. +// This can be done in any module, not just the anonymous crate module. +#![warn(non_camel_case_types)] +``` + +r[crate.main] +## Main functions + +r[crate.main.executable] +A crate that contains a `main` [function] can be compiled to an executable. + +r[crate.main.restriction] +If a `main` function is present, it must take no arguments, must not declare any [trait or lifetime bounds], must not have any [where clauses], and its return type must implement the [`Termination`] trait. + +```rust +fn main() {} +``` +```rust +fn main() -> ! { + std::process::exit(0); +} +``` +```rust +fn main() -> impl std::process::Termination { + std::process::ExitCode::SUCCESS +} +``` + +r[crate.main.import] +The `main` function may be an import, e.g. from an external crate or from the current one. + +```rust +mod foo { + pub fn bar() { + println!("Hello, world!"); + } +} +use foo::bar as main; +``` + +> [!NOTE] +> Types with implementations of [`Termination`] in the standard library include: +> +> * `()` +> * [`!`] +> * [`Infallible`] +> * [`ExitCode`] +> * `Result<T, E> where T: Termination, E: Debug` + +<!-- If the previous section needs updating (from "must take no arguments" + onwards, also update it in the testing.md file --> + +r[crate.uncaught-foreign-unwinding] +### Uncaught foreign unwinding + +When a "foreign" unwind (e.g. an exception thrown from C++ code, or a `panic!` in Rust code using a different panic handler) propagates beyond the `main` function, the process will be safely terminated. This may take the form of an abort, in which case it is not guaranteed that any `Drop` calls will be executed, and the error output may be less informative than if the runtime had been terminated by a "native" Rust `panic`. + +For more information, see the [panic documentation][panic-docs]. + +r[crate.no_main] +### The `no_main` attribute + +The *`no_main` [attribute]* may be applied at the crate level to disable emitting the `main` symbol for an executable binary. This is useful when some other object being linked to defines `main`. + +r[crate.crate_name] +## The `crate_name` attribute + +r[crate.crate_name.general] +The *`crate_name` [attribute]* may be applied at the crate level to specify the name of the crate with the [MetaNameValueStr] syntax. + +```rust +#![crate_name = "mycrate"] +``` + +r[crate.crate_name.restriction] +The crate name must not be empty, and must only contain [Unicode alphanumeric] or `_` (U+005F) characters. + +[^phase-distinction]: This distinction would also exist in an interpreter. Static checks like syntactic analysis, type checking, and lints should happen before the program is executed regardless of when it is executed. + +[^cratesourcefile]: A crate is somewhat analogous to an *assembly* in the ECMA-335 CLI model, a *library* in the SML/NJ Compilation Manager, a *unit* in the Owens and Flatt module system, or a *configuration* in Mesa. + +[Unicode alphanumeric]: char::is_alphanumeric +[`!`]: types/never.md +[`ExitCode`]: std::process::ExitCode +[`Infallible`]: std::convert::Infallible +[`Termination`]: std::process::Termination +[attribute]: attributes.md +[attributes]: attributes.md +[function]: items/functions.md +[module]: items/modules.md +[module path]: paths.md +[panic-docs]: panic.md#unwinding-across-ffi-boundaries +[shebang]: shebang.md +[trait or lifetime bounds]: trait-bounds.md +[where clauses]: items/generics.md#where-clauses diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/destructors.md b/stdlib/kvlang/reference/rust/reference-repo/src/destructors.md new file mode 100644 index 00000000..0103093c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/destructors.md @@ -0,0 +1,711 @@ +r[destructors] +# Destructors + +r[destructors.intro] +When an [initialized] [variable] or [temporary] goes out of [scope](#drop-scopes), its *destructor* is run or it is *dropped*. [Assignment] also runs the destructor of its left-hand operand, if it's initialized. If a variable has been partially initialized, only its initialized fields are dropped. + +r[destructors.operation] +The destructor of a type `T` consists of: + +1. If `T: Drop`, calling [`<T as core::ops::Drop>::drop`](core::ops::Drop::drop) +2. Recursively running the destructor of all of its fields. + * The fields of a [struct] are dropped in declaration order. + * The fields of the active [enum variant] are dropped in declaration order. + * The fields of a [tuple] are dropped in order. + * The elements of an [array] or owned [slice] are dropped from the first element to the last. + * The variables that a [closure] captures by move are dropped in an unspecified order. + * [Trait objects] run the destructor of the underlying type. + * Other types don't result in any further drops. + +r[destructors.drop_in_place] +If a destructor must be run manually, such as when implementing your own smart pointer, [`core::ptr::drop_in_place`] can be used. + +Some examples: + +```rust +struct PrintOnDrop(&'static str); + +impl Drop for PrintOnDrop { + fn drop(&mut self) { + println!("{}", self.0); + } +} + +let mut overwritten = PrintOnDrop("drops when overwritten"); +overwritten = PrintOnDrop("drops when scope ends"); + +let tuple = (PrintOnDrop("Tuple first"), PrintOnDrop("Tuple second")); + +let moved; +// No destructor run on assignment. +moved = PrintOnDrop("Drops when moved"); +// Drops now, but is then uninitialized. +moved; + +// Uninitialized does not drop. +let uninitialized: PrintOnDrop; + +// After a partial move, only the remaining fields are dropped. +let mut partial_move = (PrintOnDrop("first"), PrintOnDrop("forgotten")); +// Perform a partial move, leaving only `partial_move.0` initialized. +core::mem::forget(partial_move.1); +// When partial_move's scope ends, only the first field is dropped. +``` + +r[destructors.scope] +## Drop scopes + +r[destructors.scope.intro] +Each variable or temporary is associated to a *drop scope*. When control flow leaves a drop scope all variables associated to that scope are dropped in reverse order of declaration (for variables) or creation (for temporaries). + +r[destructors.scope.desugaring] +Drop scopes can be determined by replacing [`for`], [`if`], and [`while`] expressions with equivalent expressions using [`match`], [`loop`] and `break`. + +r[destructors.scope.operators] +Overloaded operators are not distinguished from built-in operators and [binding modes] are not considered. + +r[destructors.scope.list] +Given a function, or closure, there are drop scopes for: + +r[destructors.scope.function] +* The entire function + +r[destructors.scope.statement] +* Each [statement] + +r[destructors.scope.expression] +* Each [expression] + +r[destructors.scope.block] +* Each block, including the function body + * In the case of a [block expression], the scope for the block and the expression are the same scope. + +r[destructors.scope.match-arm] +* Each arm of a `match` expression + +r[destructors.scope.nesting] +Drop scopes are nested within one another as follows: + +r[destructors.scope.nesting-function] +* The entire function scope is the outer most scope. + +r[destructors.scope.nesting-function-body] +* The function body block is contained within the scope of the entire function. + +r[destructors.scope.nesting-expr-statement] +* The parent of the expression in an expression statement is the scope of the statement. + +r[destructors.scope.nesting-let-initializer] +* The parent of the initializer of a [`let` statement] is the `let` statement's scope. + +r[destructors.scope.nesting-statement] +* The parent of a statement scope is the scope of the block that contains the statement. + +r[destructors.scope.nesting-match-guard] +* The parent of the expression for a `match` guard is the scope of the arm that the guard is for. + +r[destructors.scope.nesting-match-arm] +* The parent of the expression after the `=>` in a `match` expression is the scope of the arm that it's in. + +r[destructors.scope.nesting-match] +* The parent of the arm scope is the scope of the `match` expression that it belongs to. + +r[destructors.scope.nesting-other] +* The parent of all other scopes is the scope of the immediately enclosing expression. + +r[destructors.scope.nesting-drop-order] +When multiple scopes are left at once, such as when returning from a function, variables are dropped from the inside outwards. + +r[destructors.scope.params] +### Scopes of function parameters + +All function parameters are in the scope of the entire function body, so are dropped last when evaluating the function. Each actual function parameter is dropped after any bindings introduced in that parameter's pattern. + +```rust +# struct PrintOnDrop(&'static str); +# impl Drop for PrintOnDrop { +# fn drop(&mut self) { +# println!("drop({})", self.0); +# } +# } +// Drops `y`, then the second parameter, then `x`, then the first parameter +fn patterns_in_parameters( + (x, _): (PrintOnDrop, PrintOnDrop), + (_, y): (PrintOnDrop, PrintOnDrop), +) {} + +// drop order is 3 2 0 1 +patterns_in_parameters( + (PrintOnDrop("0"), PrintOnDrop("1")), + (PrintOnDrop("2"), PrintOnDrop("3")), +); +``` + +r[destructors.scope.bindings] +### Scopes of local variables + +r[destructors.scope.bindings.let] +Local variables declared in a `let` statement are associated to the scope of the block that contains the `let` statement. + +```rust +# struct PrintOnDrop(&'static str); +# impl Drop for PrintOnDrop { +# fn drop(&mut self) { +# println!("drop({})", self.0); +# } +# } +let declared_first = PrintOnDrop("Dropped last in outer scope"); +{ + let declared_in_block = PrintOnDrop("Dropped in inner scope"); +} +let declared_last = PrintOnDrop("Dropped first in outer scope"); +``` + +r[destructors.scope.bindings.match-arm] +Local variables declared in a `match` expression or pattern-matching `match` guard are associated to the arm scope of the `match` arm that they are declared in. + +```rust +# #![allow(irrefutable_let_patterns)] +# struct PrintOnDrop(&'static str); +# impl Drop for PrintOnDrop { +# fn drop(&mut self) { +# println!("drop({})", self.0); +# } +# } +match PrintOnDrop("Dropped last in the first arm's scope") { + // When guard evaluation succeeds, control-flow stays in the arm and + // values may be moved from the scrutinee into the arm's bindings, + // causing them to be dropped in the arm's scope. + x if let y = PrintOnDrop("Dropped second in the first arm's scope") + && let z = PrintOnDrop("Dropped first in the first arm's scope") => + { + let declared_in_block = PrintOnDrop("Dropped in inner scope"); + // Pattern-matching guards' bindings and temporaries are dropped in + // reverse order, dropping each guard condition operand's bindings + // before its temporaries. Lastly, variables bound by the arm's + // pattern are dropped. + } + _ => unreachable!(), +} + +match PrintOnDrop("Dropped in the enclosing temporary scope") { + // When guard evaluation fails, control-flow leaves the arm scope, + // causing bindings and temporaries from earlier pattern-matching + // guard condition operands to be dropped. This occurs before evaluating + // the next arm's guard or body. + _ if let y = PrintOnDrop("Dropped in the first arm's scope") + && false => unreachable!(), + // When a guard is executed multiple times due to self-overlapping + // or-patterns, control-flow leaves the arm scope when the guard fails + // and re-enters the arm scope before executing the guard again. + _ | _ if let y = PrintOnDrop("Dropped in the second arm's scope twice") + && false => unreachable!(), + _ => {}, +} +``` + +r[destructors.scope.bindings.patterns] +Variables in patterns are dropped in reverse order of declaration within the pattern. + +```rust +# struct PrintOnDrop(&'static str); +# impl Drop for PrintOnDrop { +# fn drop(&mut self) { +# println!("drop({})", self.0); +# } +# } +let (declared_first, declared_last) = ( + PrintOnDrop("Dropped last"), + PrintOnDrop("Dropped first"), +); +``` + +r[destructors.scope.bindings.or-patterns] +For the purpose of drop order, [or-patterns] declare bindings in the order given by the first subpattern. + +```rust +# struct PrintOnDrop(&'static str); +# impl Drop for PrintOnDrop { +# fn drop(&mut self) { +# println!("drop({})", self.0); +# } +# } +// Drops `x` before `y`. +fn or_pattern_drop_order<T>( + (Ok([x, y]) | Err([y, x])): Result<[T; 2], [T; 2]> +// ^^^^^^^^^^ ^^^^^^^^^^^ This is the second subpattern. +// | +// This is the first subpattern. +// +// In the first subpattern, `x` is declared before `y`. Since it is +// the first subpattern, that is the order used even if the second +// subpattern, where the bindings are declared in the opposite +// order, is matched. +) {} + +// Here we match the first subpattern, and the drops happen according +// to the declaration order in the first subpattern. +or_pattern_drop_order(Ok([ + PrintOnDrop("Declared first, dropped last"), + PrintOnDrop("Declared last, dropped first"), +])); + +// Here we match the second subpattern, and the drops still happen +// according to the declaration order in the first subpattern. +or_pattern_drop_order(Err([ + PrintOnDrop("Declared last, dropped first"), + PrintOnDrop("Declared first, dropped last"), +])); +``` + +r[destructors.scope.temporary] +### Temporary scopes + +r[destructors.scope.temporary.intro] +The *temporary scope* of an expression is the scope that is used for the temporary variable that holds the result of that expression when used in a [place context], unless it is [promoted]. + +r[destructors.scope.temporary.enclosing] +Apart from lifetime extension, the temporary scope of an expression is the smallest scope that contains the expression and is one of the following: + +* The entire function. +* A statement. +* The body of an [`if`], [`while`] or [`loop`] expression. +* The `else` block of an `if` expression. +* The non-pattern matching condition expression of an `if` or `while` expression or a non-pattern-matching `match` [guard condition operand]. +* The pattern-matching guard, if present, and body expression for a `match` arm. +* Each operand of a [lazy boolean expression]. +* The pattern-matching condition(s) and consequent body of [`if`] ([destructors.scope.temporary.edition2024]). +* The pattern-matching condition and loop body of [`while`]. +* The entirety of the tail expression of a block ([destructors.scope.temporary.edition2024]). + +> [!NOTE] +> The [scrutinee] of a `match` expression is not a temporary scope, so temporaries in the scrutinee can be dropped after the `match` expression. For example, the temporary for `1` in `match 1 { ref mut z => z };` lives until the end of the statement. + +> [!NOTE] +> The desugaring of a [destructuring assignment] restricts the temporary scope of its assigned value operand (the RHS). For details, see [expr.assign.destructure.tmp-scopes]. + +r[destructors.scope.temporary.edition2024] +> [!EDITION-2024] +> The 2024 edition added two new temporary scope narrowing rules: `if let` temporaries are dropped before the `else` block, and temporaries of tail expressions of blocks are dropped immediately after the tail expression is evaluated. + +Some examples: + +```rust +# #![allow(irrefutable_let_patterns)] +# struct PrintOnDrop(&'static str); +# impl Drop for PrintOnDrop { +# fn drop(&mut self) { +# println!("drop({})", self.0); +# } +# } +let local_var = PrintOnDrop("local var"); + +// Dropped once the condition has been evaluated +if PrintOnDrop("If condition").0 == "If condition" { + // Dropped at the end of the block + PrintOnDrop("If body").0 +} else { + unreachable!() +}; + +if let "if let scrutinee" = PrintOnDrop("if let scrutinee").0 { + PrintOnDrop("if let consequent").0 + // `if let consequent` dropped here +} +// `if let scrutinee` is dropped here +else { + PrintOnDrop("if let else").0 + // `if let else` dropped here +}; + +while let x = PrintOnDrop("while let scrutinee").0 { + PrintOnDrop("while let loop body").0; + break; + // `while let loop body` dropped here. + // `while let scrutinee` dropped here. +} + +// Dropped before the first || +(PrintOnDrop("first operand").0 == "" +// Dropped before the ) +|| PrintOnDrop("second operand").0 == "") +// Dropped before the ; +|| PrintOnDrop("third operand").0 == ""; + +// Scrutinee is dropped at the end of the function, before local variables +// (because this is the tail expression of the function body block). +match PrintOnDrop("Matched value in final expression") { + // Non-pattern-matching guards' temporaries are dropped once the + // condition has been evaluated + _ if PrintOnDrop("guard condition").0 == "" => (), + // Pattern-matching guards' temporaries are dropped when leaving the + // arm's scope + _ if let "guard scrutinee" = PrintOnDrop("guard scrutinee").0 => { + let _ = &PrintOnDrop("lifetime-extended temporary in inner scope"); + // `lifetime-extended temporary in inner scope` is dropped here + } + // `guard scrutinee` is dropped here + _ => (), +} +``` + +r[destructors.scope.operands] +### Operands + +Temporaries are also created to hold the result of operands to an expression while the other operands are evaluated. The temporaries are associated to the scope of the expression with that operand. Since the temporaries are moved from once the expression is evaluated, dropping them has no effect unless one of the operands to an expression breaks out of the expression, returns, or [panics][panic]. + +```rust +# struct PrintOnDrop(&'static str); +# impl Drop for PrintOnDrop { +# fn drop(&mut self) { +# println!("drop({})", self.0); +# } +# } +loop { + // Tuple expression doesn't finish evaluating so operands drop in reverse order + ( + PrintOnDrop("Outer tuple first"), + PrintOnDrop("Outer tuple second"), + ( + PrintOnDrop("Inner tuple first"), + PrintOnDrop("Inner tuple second"), + break, + ), + PrintOnDrop("Never created"), + ); +} +``` + +r[destructors.scope.const-promotion] +### Constant promotion + +Promotion of a value expression to a `'static` slot occurs when the expression could be written in a constant and borrowed, and that borrow could be dereferenced where the expression was originally written, without changing the runtime behavior. That is, the promoted expression can be evaluated at compile-time and the resulting value does not contain [interior mutability] or [destructors] (these properties are determined based on the value where possible, e.g. `&None` always has the type `&'static Option<_>`, as it contains nothing disallowed). + +r[destructors.scope.lifetime-extension] +### Temporary lifetime extension + +r[destructors.scope.lifetime-extension.intro] +> [!NOTE] +> The exact rules for temporary lifetime extension are subject to change. This is describing the current behavior only. + +r[destructors.scope.lifetime-extension.let] +The temporary scopes for expressions in `let` statements are sometimes *extended* to the scope of the block containing the `let` statement. This is done when the usual temporary scope would be too small, based on certain syntactic rules. For example: + +```rust +let x = &mut 0; +// Usually a temporary would be dropped by now, but the temporary for `0` lives +// to the end of the block. +println!("{}", x); +``` + +r[destructors.scope.lifetime-extension.static] +Lifetime extension also applies to `static` and `const` items, where it makes temporaries live until the end of the program. For example: + +```rust +const C: &Vec<i32> = &Vec::new(); +// Usually this would be a dangling reference as the `Vec` would only +// exist inside the initializer expression of `C`, but instead the +// borrow gets lifetime-extended so it effectively has `'static` lifetime. +println!("{:?}", C); +``` + +r[destructors.scope.lifetime-extension.sub-expressions] +If a [borrow], [dereference][dereference expression], [field][field expression], or [tuple indexing expression] has an extended temporary scope, then so does its operand. If an [indexing expression] has an extended temporary scope, then the indexed expression also has an extended temporary scope. + +r[destructors.scope.lifetime-extension.patterns] +#### Extending based on patterns + +r[destructors.scope.lifetime-extension.patterns.extending] +An *extending pattern* is either: + +* An [identifier pattern] that binds by reference or mutable reference. + + ```rust + # fn temp() {} + let ref x = temp(); // Binds by reference. + # x; + let ref mut x = temp(); // Binds by mutable reference. + # x; + ``` + +* A [struct][struct pattern], [tuple][tuple pattern], [tuple struct][tuple struct pattern], [slice][slice pattern], or [or-pattern][or-patterns] where at least one of the direct subpatterns is an extending pattern. + + ```rust + # use core::sync::atomic::{AtomicU64, Ordering::Relaxed}; + # static X: AtomicU64 = AtomicU64::new(0); + struct W<T>(T); + # impl<T> Drop for W<T> { fn drop(&mut self) { X.fetch_add(1, Relaxed); } } + let W { 0: ref x } = W(()); // Struct pattern. + # x; + let W(ref x) = W(()); // Tuple struct pattern. + # x; + let (W(ref x),) = (W(()),); // Tuple pattern. + # x; + let [W(ref x), ..] = [W(())]; // Slice pattern. + # x; + let (Ok(W(ref x)) | Err(&ref x)) = Ok(W(())); // Or pattern. + # x; + // + // All of the temporaries above are still live here. + # assert_eq!(0, X.load(Relaxed)); + ``` + +So `ref x`, `V(ref x)` and `[ref x, y]` are all extending patterns, but `x`, `&ref x` and `&(ref x,)` are not. + +r[destructors.scope.lifetime-extension.patterns.let] +If the pattern in a `let` statement is an extending pattern then the temporary scope of the initializer expression is extended. + +```rust +# fn temp() {} +// This is an extending pattern, so the temporary scope is extended. +let ref x = *&temp(); // OK +# x; +``` + +```rust,compile_fail,E0716 +# fn temp() {} +// This is neither an extending pattern nor an extending expression, +// so the temporary is dropped at the semicolon. +let &ref x = *&&temp(); // ERROR +# x; +``` + +```rust +# fn temp() {} +// This is not an extending pattern but it is an extending expression, +// so the temporary lives beyond the `let` statement. +let &ref x = &*&temp(); // OK +# x; +``` + +r[destructors.scope.lifetime-extension.exprs] +#### Extending based on expressions + +r[destructors.scope.lifetime-extension.exprs.extending] +For a let statement with an initializer, an *extending expression* is an expression which is one of the following: + +* The initializer expression. +* The operand of an extending [borrow] expression. +* The [super operands] of an extending [super macro call] expression. +* The operand(s) of an extending [array][array expression], [cast][cast expression], [braced struct][struct expression], or [tuple][tuple expression] expression. +* The arguments to an extending [tuple struct] or [tuple enum variant] constructor expression. +* The final expression of an extending [block expression] except for an [async block expression]. +* The final expression of an extending [`if`] expression's consequent, `else if`, or `else` block. +* An arm expression of an extending [`match`] expression. + +> [!NOTE] +> The desugaring of a [destructuring assignment] makes its assigned value operand (the RHS) an extending expression within a newly-introduced block. For details, see [expr.assign.destructure.tmp-ext]. + +So the borrow expressions in `&mut 0`, `(&1, &mut 2)`, and `Some(&mut 3)` are all extending expressions. The borrows in `&0 + &1` and `f(&mut 0)` are not. + +r[destructors.scope.lifetime-extension.exprs.borrows] +The operand of an extending [borrow] expression has its [temporary scope] [extended]. + +r[destructors.scope.lifetime-extension.exprs.super-macros] +The [super temporaries] of an extending [super macro call] expression have their [scopes][temporary scopes] [extended]. + +> [!NOTE] +> `rustc` does not treat [array repeat operands] of extending [array] expressions as extending expressions. Whether it should is an open question. +> +> For details, see [Rust issue #146092](https://github.com/rust-lang/rust/issues/146092). + +#### Examples + +Here are some examples where expressions have extended temporary scopes: + +```rust,edition2024 +# use core::pin::pin; +# use core::sync::atomic::{AtomicU64, Ordering::Relaxed}; +# static X: AtomicU64 = AtomicU64::new(0); +# #[derive(Debug)] struct S; +# impl Drop for S { fn drop(&mut self) { X.fetch_add(1, Relaxed); } } +# const fn temp() -> S { S } +let x = &temp(); // Operand of borrow. +# x; +let x = &raw const *&temp(); // Operand of raw borrow. +# assert_eq!(X.load(Relaxed), 0); +let x = &temp() as &dyn Send; // Operand of cast. +# x; +let x = (&*&temp(),); // Operand of tuple constructor. +# x; +struct W<T>(T); +let x = W(&temp()); // Argument to tuple struct constructor. +# x; +let x = Some(&temp()); // Argument to tuple enum variant constructor. +# x; +let x = { [Some(&temp())] }; // Final expr of block. +# x; +let x = const { &temp() }; // Final expr of `const` block. +# x; +let x = unsafe { &temp() }; // Final expr of `unsafe` block. +# x; +let x = if true { &temp() } else { &temp() }; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// Final exprs of `if`/`else` blocks. +# x; +let x = match () { _ => &temp() }; // `match` arm expression. +# x; +let x = pin!(temp()); // Super operand of super macro call expression. +# x; +let x = pin!({ &mut temp() }); // As above. +# x; +let x = format_args!("{:?}", temp()); // As above. +# x; +// +// All of the temporaries above are still live here. +# assert_eq!(0, X.load(Relaxed)); +``` + +Here are some examples where expressions don't have extended temporary scopes: + +```rust,compile_fail,E0716 +# fn temp() {} +// Arguments to function calls are not extending expressions. The +// temporary is dropped at the semicolon. +let x = core::convert::identity(&temp()); // ERROR +# x; +``` + +```rust,compile_fail,E0716 +# fn temp() {} +# trait Use { fn use_temp(&self) -> &Self { self } } +# impl Use for () {} +// Receivers of method calls are not extending expressions. +let x = (&temp()).use_temp(); // ERROR +# x; +``` + +```rust,compile_fail,E0716 +# fn temp() {} +// Scrutinees of match expressions are not extending expressions. +let x = match &temp() { x => x }; // ERROR +# x; +``` + +```rust,compile_fail,E0515 +# fn temp() {} +// Final expressions of `async` blocks are not extending expressions. +let x = async { &temp() }; // ERROR +# x; +``` + +```rust,compile_fail,E0515 +# fn temp() {} +// Final expressions of closures are not extending expressions. +let x = || &temp(); // ERROR +# x; +``` + +```rust,compile_fail,E0716 +# fn temp() {} +// Operands of loop breaks are not extending expressions. +let x = loop { break &temp() }; // ERROR +# x; +``` + +```rust,compile_fail,E0716 +# fn temp() {} +// Operands of breaks to labels are not extending expressions. +let x = 'a: { break 'a &temp() }; // ERROR +# x; +``` + +```rust,edition2024,compile_fail,E0716 +# use core::pin::pin; +# fn temp() {} +// The argument to `pin!` is only an extending expression if the call +// is an extending expression. Since it's not, the inner block is not +// an extending expression, so the temporaries in its trailing +// expression are dropped immediately. +pin!({ &temp() }); // ERROR +``` + +```rust,edition2024,compile_fail,E0716 +# fn temp() {} +// As above. +format_args!("{:?}", { &temp() }); // ERROR +``` + +r[destructors.forget] +## Not running destructors + +r[destructors.manually-suppressing] +### Manually suppressing destructors + +[`core::mem::forget`] can be used to prevent the destructor of a variable from being run, and [`core::mem::ManuallyDrop`] provides a wrapper to prevent a variable or field from being dropped automatically. + +> [!NOTE] +> Preventing a destructor from being run via [`core::mem::forget`] or other means is safe even if it has a type that isn't `'static`. Besides the places where destructors are guaranteed to run as defined by this document, types may *not* safely rely on a destructor being run for soundness. + +r[destructors.process-termination] +### Process termination without unwinding + +There are some ways to terminate the process without [unwinding], in which case destructors will not be run. + +The standard library provides [`std::process::exit`] and [`std::process::abort`] to do this explicitly. Additionally, if the [panic handler][panic.panic_handler.std] is set to `abort`, panicking will always terminate the process without destructors being run. + +There is one additional case to be aware of: when a panic reaches a [non-unwinding ABI boundary], either no destructors will run, or all destructors up until the ABI boundary will run. + +[Assignment]: expressions/operator-expr.md#assignment-expressions +[binding modes]: patterns.md#binding-modes +[closure]: types/closure.md +[destructors]: destructors.md +[destructuring assignment]: expr.assign.destructure +[expression]: expressions.md +[guard condition operand]: expressions/match-expr.md#match-guard-chains +[identifier pattern]: patterns.md#identifier-patterns +[initialized]: glossary.md#initialized +[interior mutability]: interior-mutability.md +[lazy boolean expression]: expressions/operator-expr.md#lazy-boolean-operators +[non-unwinding ABI boundary]: items/functions.md#unwinding +[panic]: panic.md +[place context]: expressions.md#place-expressions-and-value-expressions +[promoted]: destructors.md#constant-promotion +[scrutinee]: glossary.md#scrutinee +[statement]: statements.md +[temporary]: expressions.md#temporaries +[unwinding]: panic.md#unwinding +[variable]: variables.md + +[array]: types/array.md +[enum variant]: types/enum.md +[slice]: types/slice.md +[struct]: types/struct.md +[Trait objects]: types/trait-object.md +[tuple]: types/tuple.md + +[or-patterns]: patterns.md#or-patterns +[slice pattern]: patterns.md#slice-patterns +[struct pattern]: patterns.md#struct-patterns +[tuple pattern]: patterns.md#tuple-patterns +[tuple struct pattern]: patterns.md#tuple-struct-patterns +[tuple struct]: type.struct.tuple +[tuple enum variant]: type.enum.declaration + +[array expression]: expressions/array-expr.md#array-expressions +[array repeat operands]: expr.array.repeat-operand +[async block expression]: expr.block.async +[block expression]: expressions/block-expr.md +[borrow]: expr.operator.borrow +[cast expression]: expressions/operator-expr.md#type-cast-expressions +[dereference expression]: expressions/operator-expr.md#the-dereference-operator +[extended]: destructors.scope.lifetime-extension +[field expression]: expressions/field-expr.md +[indexing expression]: expressions/array-expr.md#array-and-slice-indexing-expressions +[struct expression]: expressions/struct-expr.md +[super macro call]: expr.super-macros +[super operands]: expr.super-macros +[super temporaries]: expr.super-macros +[temporary scope]: destructors.scope.temporary +[temporary scopes]: destructors.scope.temporary +[tuple expression]: expressions/tuple-expr.md#tuple-expressions +[tuple indexing expression]: expressions/tuple-expr.md#tuple-indexing-expressions + +[`for`]: expressions/loop-expr.md#iterator-loops +[`if let`]: expressions/if-expr.md#if-let-patterns +[`if`]: expressions/if-expr.md#if-expressions +[`let` statement]: statements.md#let-statements +[`loop`]: expressions/loop-expr.md#infinite-loops +[`match`]: expressions/match-expr.md +[`while let`]: expressions/loop-expr.md#while-let-patterns +[`while`]: expressions/loop-expr.md#predicate-loops diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/divergence.md b/stdlib/kvlang/reference/rust/reference-repo/src/divergence.md new file mode 100644 index 00000000..ab6ba0ab --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/divergence.md @@ -0,0 +1,91 @@ +r[divergence] +# Divergence + +r[divergence.intro] +A *diverging expression* is an expression that never completes normal execution. + +```rust +fn diverges() -> ! { + panic!("This function never returns!"); +} + +fn example() { + let x: i32 = diverges(); // This line never completes. + println!("This is never printed: {x}"); +} +``` + +See the following rules for specific expression divergence behavior: + +- [expr.block.diverging] --- Block expressions. +- [expr.if.diverging] --- `if` expressions. +- [expr.loop.block-labels.type] --- Labeled block expressions with `break`. +- [expr.loop.break-value.diverging] --- `loop` expressions with `break`. +- [expr.loop.break.diverging] --- `break` expressions. +- [expr.loop.continue.diverging] --- `continue` expressions. +- [expr.loop.infinite.diverging] --- Infinite `loop` expressions. +- [expr.match.diverging] --- `match` expressions. +- [expr.match.empty] --- Empty `match` expressions. +- [expr.return.diverging] --- `return` expressions. + +> [!NOTE] +> The [`panic!`] macro and related panic-generating macros like [`unreachable!`] also have the type [`!`] and are diverging. + +r[divergence.never] +Any expression of type [`!`] is a diverging expression. However, diverging expressions are not limited to type [`!`]; expressions of other types may also diverge (e.g., `Some(loop {})` has type `Option<!>`). + +> [!NOTE] +> Though `!` is considered an uninhabited type, a type being uninhabited is not sufficient for it to diverge. +> +> ```rust,compile_fail,E0308 +> enum Empty {} +> fn make_never() -> ! {loop{}} +> fn make_empty() -> Empty {loop{}} +> +> fn diverging() -> ! { +> // This has a type of `!`. +> // So, the entire function is considered diverging. +> make_never(); +> // OK: The type of the body is `!` which matches the return type. +> } +> fn not_diverging() -> ! { +> // This type is uninhabited. +> // However, the entire function is not considered diverging. +> make_empty(); +> // ERROR: The type of the body is `()` but expected type `!`. +> } +> ``` + +> [!NOTE] +> Divergence can propagate to the surrounding block. See [expr.block.diverging]. + +r[divergence.fallback] +## Fallback + +If a type to be inferred is only unified with diverging expressions, then that type will be inferred to be [`!`]. + +> [!EXAMPLE] +> ```rust,compile_fail,E0277 +> fn foo() -> i32 { 22 } +> match foo() { +> // ERROR: The trait bound `!: Default` is not satisfied. +> 4 => Default::default(), +> _ => return, +> }; +> ``` + +> [!NOTE] +> Importantly, type unification may happen *structurally*, so the fallback `!` may be part of a larger type. The following compiles: +> +> ```rust +> fn foo() -> i32 { 22 } +> // This has the type `Option<!>`, not `!` +> match foo() { +> 4 => Default::default(), +> _ => Some(return), +> }; +> ``` + +<!-- TODO: This last point should likely should be moved to a more general "type inference" section discussing generalization + unification. --> + +[`!`]: type.never diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/dynamically-sized-types.md b/stdlib/kvlang/reference/rust/reference-repo/src/dynamically-sized-types.md new file mode 100644 index 00000000..52c7ac3f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/dynamically-sized-types.md @@ -0,0 +1,44 @@ +r[dynamic-sized] +# Dynamically sized types + +r[dynamic-sized.intro] +Most types have a fixed size that is known at compile time and implement the trait [`Sized`][sized]. A type with a size that is known only at run-time is called a _dynamically sized type_ (_DST_) or, informally, an unsized type. [Slices], [trait objects], and [str] are examples of <abbr title="dynamically sized types">DSTs</abbr>. + +r[dynamic-sized.restriction] +Such types can only be used in certain cases: + +r[dynamic-sized.pointer-types] +* [Pointer types] to <abbr title="dynamically sized types">DSTs</abbr> are sized but have twice the size of pointers to sized types, since they also store *metadata*: + * Pointers to slices store the number of elements; pointers to `str` store the length in bytes. + * Pointers to trait objects store a pointer to a vtable. + * Pointers to a struct or tuple with an [unsized tail] store the same metadata as a pointer to that tail. + +r[dynamic-sized.question-sized] +* <abbr title="dynamically sized types">DSTs</abbr> can be provided as type arguments to generic type parameters having the special `?Sized` bound. They can also be used for associated type definitions when the corresponding associated type declaration has a `?Sized` bound. By default, any type parameter or associated type has a `Sized` bound, unless it is relaxed using `?Sized`. + +r[dynamic-sized.trait-impl] +* Traits may be implemented for <abbr title="dynamically sized + types">DSTs</abbr>. Unlike with generic type parameters, `Self: ?Sized` is the default in trait definitions. + +r[dynamic-sized.struct-field] +* Structs may contain a <abbr title="dynamically sized type">DST</abbr> as the last field; this makes the struct itself a <abbr title="dynamically sized type">DST</abbr>. + +> [!NOTE] +> [Variables], function parameters, [const] items, and [static] items must be `Sized`. + +r[dynamic-sized.tail] +The *unsized tail* of a type is the dynamically sized component that the [metadata] of a pointer to the type describes. A [slice] (`[T]`) and a [`str`] are each their own unsized tail, described by a length; a [trait object] (`dyn Trait`) is its own unsized tail, described by a pointer to a vtable. When a struct (per [dynamic-sized.struct-field]) or a tuple has an unsized last field, its unsized tail is the unsized tail of that field. A sized type has no unsized tail. + +[metadata]: dynamic-sized.pointer-types +[sized]: special-types-and-traits.md#sized +[unsized tail]: dynamic-sized.tail +[Slices]: types/slice.md +[slice]: types/slice.md +[str]: types/str.md +[`str`]: types/str.md +[trait objects]: types/trait-object.md +[trait object]: types/trait-object.md +[Pointer types]: types/pointer.md +[Variables]: variables.md +[const]: items/constant-items.md +[static]: items/static-items.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions.md new file mode 100644 index 00000000..9943384d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions.md @@ -0,0 +1,430 @@ +r[expr] +# Expressions + +r[expr.syntax] +```grammar,expressions +Expression -> + ExpressionWithoutBlock + | ExpressionWithBlock + +ExpressionWithoutBlock -> + OuterAttribute* ExpressionWithoutBlockNoAttrs + +ExpressionWithoutBlockNoAttrs -> + LiteralExpression + | PathExpression + | OperatorExpression + | GroupedExpression + | ArrayExpression + | AwaitExpression + | IndexExpression + | TupleExpression + | TupleIndexingExpression + | StructExpression + | CallExpression + | MethodCallExpression + | FieldExpression + | ClosureExpression + | AsyncBlockExpression + | ContinueExpression + | BreakExpression + | RangeExpression + | ReturnExpression + | UnderscoreExpression + | MacroInvocation + +ExpressionWithBlock -> + OuterAttribute* ExpressionWithBlockNoAttrs + +ExpressionWithBlockNoAttrs -> + BlockExpression + | ConstBlockExpression + | UnsafeBlockExpression + | LoopExpression + | IfExpression + | MatchExpression +``` + +r[expr.intro] +An expression may have two roles: it always produces a *value*, and it may have *effects* (otherwise known as "side effects"). + +r[expr.evaluation] +An expression *evaluates to* a value, and has effects during *evaluation*. + +r[expr.operands] +Many expressions contain sub-expressions, called the *operands* of the expression. + +r[expr.behavior] +The meaning of each kind of expression dictates several things: + +* Whether or not to evaluate the operands when evaluating the expression +* The order in which to evaluate the operands +* How to combine the operands' values to obtain the value of the expression + +r[expr.structure] +In this way, the structure of expressions dictates the structure of execution. Blocks are just another kind of expression, so blocks, statements, expressions, and blocks again can recursively nest inside each other to an arbitrary depth. + +> [!NOTE] +> We give names to the operands of expressions so that we may discuss them, but these names are not stable and may be changed. + +r[expr.precedence] +## Expression precedence + +The precedence of Rust operators and expressions is ordered as follows, going from strong to weak. Binary Operators at the same precedence level are grouped in the order given by their associativity. + +| Operator/Expression | Associativity | +|-----------------------------|---------------------| +| [Paths][expr.path] | | +| [Method calls][expr.method] | | +| [Field expressions][expr.field] | left to right | +| [Function calls][expr.call], [array indexing][expr.array.index] | | +| [`?`][expr.try] | | +| Unary [`-`][expr.negate] [`!`][expr.negate] [`*`][expr.deref] [borrow][expr.operator.borrow] | | +| [`as`][expr.as] | left to right | +| [`*`][expr.arith-logic] [`/`][expr.arith-logic] [`%`][expr.arith-logic] | left to right | +| [`+`][expr.arith-logic] [`-`][expr.arith-logic] | left to right | +| [`<<`][expr.arith-logic] [`>>`][expr.arith-logic] | left to right | +| [`&`][expr.arith-logic] | left to right | +| [`^`][expr.arith-logic] | left to right | +| [<code>|</code>][expr.arith-logic] | left to right | +| [`==`][expr.cmp] [`!=`][expr.cmp] [`<`][expr.cmp] [`>`][expr.cmp] [`<=`][expr.cmp] [`>=`][expr.cmp] | Require parentheses | +| [`&&`][expr.bool-logic] | left to right | +| [<code>||</code>][expr.bool-logic] | left to right | +| [`..`][expr.range] [`..=`][expr.range] | Require parentheses | +| [`=`][expr.assign] [`+=`][expr.compound-assign] [`-=`][expr.compound-assign] [`*=`][expr.compound-assign] [`/=`][expr.compound-assign] [`%=`][expr.compound-assign] <br> [`&=`][expr.compound-assign] [<code>|=</code>][expr.compound-assign] [`^=`][expr.compound-assign] [`<<=`][expr.compound-assign] [`>>=`][expr.compound-assign] | right to left | +| [`return`][expr.return] [`break`][expr.loop.break] [closures][expr.closure] | | + +r[expr.operand-order] +## Evaluation order of operands + +r[expr.operand-order.default] +The following list of expressions all evaluate their operands the same way, as described after the list. Other expressions either don't take operands or evaluate them conditionally as described on their respective pages. + +* Dereference expression +* Error propagation expression +* Negation expression +* Arithmetic and logical binary operators +* Comparison operators +* Type cast expression +* Grouped expression +* Array expression +* Await expression +* Index expression +* Tuple expression +* Tuple index expression +* Struct expression +* Call expression +* Method call expression +* Field expression +* Break expression +* Range expression +* Return expression + +r[expr.operand-order.operands-before-primary] +The operands of these expressions are evaluated prior to applying the effects of the expression. Expressions taking multiple operands are evaluated left to right as written in the source code. + +> [!NOTE] +> Which subexpressions are the operands of an expression is determined by expression precedence as per the previous section. + +For example, the two `next` method calls will always be called in the same order: + +```rust +# // Using vec instead of array to avoid references +# // since there is no stable owned array iterator +# // at the time this example was written. +let mut one_two = vec![1, 2].into_iter(); +assert_eq!( + (1, 2), + (one_two.next().unwrap(), one_two.next().unwrap()) +); +``` + +> [!NOTE] +> Since this is applied recursively, these expressions are also evaluated from innermost to outermost, ignoring siblings until there are no inner subexpressions. + +r[expr.place-value] +## Place expressions and value expressions + +r[expr.place-value.intro] +Expressions are divided into two main categories: place expressions and value expressions; there is also a third, minor category of expressions called assignee expressions. Within each expression, operands may likewise occur in either place context or value context. The evaluation of an expression depends both on its own category and the context it occurs within. + +r[expr.place-value.place-memory-location] +A *place expression* is an expression that represents a memory location. + +r[expr.place-value.place-expr-kinds] +These expressions are [paths] which refer to local variables, [static variables], [dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`), [field] references (`expr.f`) and parenthesized place expressions. + +r[expr.place-value.value-expr-kinds] +All other expressions are value expressions. + +r[expr.place-value.value-result] +A *value expression* is an expression that represents an actual value. + +r[expr.place-value.place-context] +The following contexts are *place expression* contexts: + +* The left operand of a [compound assignment] expression. +* The operand of a unary [borrow], [raw borrow] or [dereference][deref] operator. +* The operand of a [field expression]. +* The indexed operand of an [array indexing expression]. +* The tuple operand of a [tuple indexing expression]. +* The operand of any [implicit borrow]. +* The initializer of a [let statement]. +* The [scrutinee] of an [`if let`], [`match`][match], or [`while let`] expression. +* The base of a [functional update] struct expression. + +> [!NOTE] +> Historically, place expressions were called *lvalues* and value expressions were called *rvalues*. + +r[expr.place-value.assignee] +An *assignee expression* is an expression that appears in the left operand of an [assignment][assign] expression. Explicitly, the assignee expressions are: + +- Place expressions. +- [Underscores]. +- [Tuples] of assignee expressions. +- [Slices][expr.array.index] of assignee expressions. +- [Tuple structs] of assignee expressions. +- [Structs] of assignee expressions (with optionally named fields). +- [Unit structs] + +r[expr.place-value.parenthesis] +Arbitrary parenthesisation is permitted inside assignee expressions. + +r[expr.move] +### Moved and copied types + +r[expr.move.intro] +When a place expression is evaluated in a value expression context, or is bound by value in a pattern, it denotes the value held _in_ that memory location. + +r[expr.move.copy] +If the type of that value implements [`Copy`], then the value will be copied. + +r[expr.move.requires-sized] +In the remaining situations, if that type is [`Sized`], then it may be possible to move the value. + +r[expr.move.movable-place] +Only the following place expressions may be moved out of: + +* [Variables] which are not currently borrowed. +* [Temporary values](#temporaries). +* [Fields][field] of a place expression which can be moved out of and don't implement [`Drop`]. +* The result of [dereferencing][deref] an expression with type [`Box<T>`] and that can also be moved out of. + +r[expr.move.deinitialization] +After moving out of a place expression that evaluates to a local variable, the location is deinitialized and cannot be read from again until it is reinitialized. + +r[expr.move.place-invalid] +In all other cases, trying to use a place expression in a value expression context is an error. + +r[expr.mut] +### Mutability + +r[expr.mut.intro] +For a place expression to be [assigned][assign] to, mutably [borrowed][borrow], [implicitly mutably borrowed], or bound to a pattern containing `ref mut`, it must be _mutable_. We call these *mutable place expressions*. In contrast, other place expressions are called *immutable place expressions*. + +r[expr.mut.valid-places] +The following expressions can be mutable place expression contexts: + +* Mutable [variables] which are not currently borrowed. +* [Mutable `static` items]. +* [Temporary values]. +* [Fields][field]: this evaluates the subexpression in a mutable place expression context. +* [Dereferences][deref] of a `*mut T` pointer. +* Dereference of a variable, or field of a variable, with type `&mut T`. Note: This is an exception to the requirement of the next rule. +* Dereferences of a type that implements `DerefMut`: this then requires that the value being dereferenced is evaluated in a mutable place expression context. +* [Array indexing] of a type that implements `IndexMut`: this then evaluates the value being indexed, but not the index, in mutable place expression context. + +r[expr.temporary] +### Temporaries + +When using a value expression in most place expression contexts, a temporary unnamed memory location is created and initialized to that value. The expression evaluates to that location instead, except if [promoted] to a `static`. The [drop scope] of the temporary is usually the end of the enclosing statement. + +r[expr.super-macros] +### Super macros + +r[expr.super-macros.intro] +Certain built-in macros may create [temporaries] whose [scopes][temporary scopes] may be [extended]. These temporaries are *super temporaries* and these macros are *super macros*. [Invocations][macro invocations] of these macros are *super macro call expressions*. Arguments to these macros may be *super operands*. + +> [!NOTE] +> When a super macro call expression is an [extending expression], its super operands are [extending expressions] and the [scopes][temporary scopes] of the super temporaries are [extended]. See [destructors.scope.lifetime-extension.exprs]. + +r[expr.super-macros.format_args] +#### `format_args!` + +r[expr.super-macros.format_args.super-operands] +Except for the format string argument, all arguments passed to [`format_args!`] are *super operands*. + +```rust,edition2024 +# fn temp() -> String { String::from("") } +// Due to the call being an extending expression and the argument +// being a super operand, the inner block is an extending expression, +// so the scope of the temporary created in its trailing expression +// is extended. +let _ = format_args!("{}", { &temp() }); // OK +``` + +r[expr.super-macros.format_args.super-temporaries] +The super operands of [`format_args!`] are [implicitly borrowed] and are therefore [place expression contexts]. When a [value expression] is passed as an argument, it creates a *super temporary*. + +```rust +# fn temp() -> String { String::from("") } +let x = format_args!("{}", temp()); +x; // <-- The temporary is extended, allowing use here. +``` + +The expansion of a call to [`format_args!`] sometimes creates other internal *super temporaries*. + +```rust,compile_fail,E0716 +let x = { + // This call creates an internal temporary. + let x = format_args!("{:?}", 0); + x // <-- The temporary is extended, allowing its use here. +}; // <-- The temporary is dropped here. +x; // ERROR +``` + +```rust +// This call doesn't create an internal temporary. +let x = { let x = format_args!("{}", 0); x }; +x; // OK +``` + +> [!NOTE] +> The details of when [`format_args!`] does or does not create internal temporaries are currently unspecified. + +r[expr.super-macros.pin] +#### `pin!` + +r[expr.super-macros.pin.super-operands] +The argument to [`pin!`] is a *super operand*. + +```rust,edition2024 +# use core::pin::pin; +# fn temp() {} +// As above for `format_args!`. +let _ = pin!({ &temp() }); // OK +``` + +r[expr.super-macros.pin.super-temporaries] +The argument to [`pin!`] is a [value expression context] and creates a *super temporary*. + +```rust +# use core::pin::pin; +# fn temp() {} +// The argument is evaluated into a super temporary. +let x = pin!(temp()); +// The temporary is extended, allowing its use here. +x; // OK +``` + +r[expr.implicit-borrow] +### Implicit borrows + +r[expr.implicit-borrow-intro] +Certain expressions will treat an expression as a place expression by implicitly borrowing it. For example, it is possible to compare two unsized [slices][slice] for equality directly, because the `==` operator implicitly borrows its operands: + +```rust +# let c = [1, 2, 3]; +# let d = vec![1, 2, 3]; +let a: &[i32]; +let b: &[i32]; +# a = &c; +# b = &d; +// ... +*a == *b; +// Equivalent form: +::std::cmp::PartialEq::eq(&*a, &*b); +``` + +r[expr.implicit-borrow.application] +Implicit borrows may be taken in the following expressions: + +* Left operand in [method-call] expressions. +* Left operand in [field] expressions. +* Left operand in [call expressions]. +* Left operand in [array indexing] expressions. +* Operand of the [dereference operator][deref] (`*`). +* Operands of [comparison]. +* Left operands of the [compound assignment]. +* Arguments to [`format_args!`] except the format string. + +r[expr.overload] +## Overloading traits + +Many of the following operators and expressions can also be overloaded for other types using traits in `std::ops` or `std::cmp`. These traits also exist in `core::ops` and `core::cmp` with the same names. + +r[expr.attr] +## Expression attributes + +r[expr.attr.restriction] +[Outer attributes] before an expression are allowed only in a few specific cases: + +* Before an expression used as a [statement]. +* Elements of [array expressions], [tuple expressions], [call expressions], and tuple-style [struct] expressions. +* The tail expression of [block expressions]. +<!-- Keep list in sync with block-expr.md --> + +r[expr.attr.never-before] +They are never allowed before: +* [Range] expressions. +* Binary operator expressions ([ArithmeticOrLogicalExpression], [ComparisonExpression], [LazyBooleanExpression], [TypeCastExpression], [AssignmentExpression], [CompoundAssignmentExpression]). + +[`Box<T>`]: special-types-and-traits.md#boxt +[`Copy`]: special-types-and-traits.md#copy +[`Drop`]: special-types-and-traits.md#drop +[`if let`]: expressions/if-expr.md#if-let-patterns +[`format_args!`]: core::format_args +[`pin!`]: core::pin::pin +[`Sized`]: special-types-and-traits.md#sized +[`while let`]: expressions/loop-expr.md#while-let-patterns +[array expressions]: expressions/array-expr.md +[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions +[array indexing expression]: expr.array.index +[assign]: expressions/operator-expr.md#assignment-expressions +[block expressions]: expressions/block-expr.md +[borrow]: expressions/operator-expr.md#borrow-operators +[call expressions]: expressions/call-expr.md +[comparison]: expressions/operator-expr.md#comparison-operators +[compound assignment]: expressions/operator-expr.md#compound-assignment-expressions +[deref]: expressions/operator-expr.md#the-dereference-operator +[destructors]: destructors.md +[drop scope]: destructors.md#drop-scopes +[extended]: destructors.scope.lifetime-extension +[extending expression]: destructors.scope.lifetime-extension.exprs +[extending expressions]: destructors.scope.lifetime-extension.exprs +[field]: expressions/field-expr.md +[field expression]: expr.field +[functional update]: expressions/struct-expr.md#functional-update-syntax +[implicit borrow]: #implicit-borrows +[implicitly borrowed]: expr.implicit-borrow +[implicitly mutably borrowed]: #implicit-borrows +[interior mutability]: interior-mutability.md +[let statement]: statements.md#let-statements +[macro invocations]: macro.invocation +[match]: expressions/match-expr.md +[method-call]: expressions/method-call-expr.md +[Mutable `static` items]: items/static-items.md#mutable-statics +[Outer attributes]: attributes.md +[paths]: expressions/path-expr.md +[place expression contexts]: expr.place-value +[promoted]: destructors.md#constant-promotion +[Range]: expressions/range-expr.md +[raw borrow]: expressions/operator-expr.md#raw-borrow-operators +[scrutinee]: glossary.md#scrutinee +[slice]: types/slice.md +[statement]: statements.md +[static variables]: items/static-items.md +[struct]: expressions/struct-expr.md +[Structs]: expr.struct +[temporaries]: expr.temporary +[temporary scopes]: destructors.scope.temporary +[Temporary values]: #temporaries +[tuple expressions]: expressions/tuple-expr.md +[tuple indexing expression]: expr.tuple-index +[Tuple structs]: items.struct.tuple +[Tuples]: expressions/tuple-expr.md +[Underscores]: expressions/underscore-expr.md +[Unit structs]: items.struct.unit +[value expression context]: expr.place-value +[value expression]: expr.place-value +[Variables]: variables.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/array-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/array-expr.md new file mode 100644 index 00000000..d0fe2476 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/array-expr.md @@ -0,0 +1,146 @@ +r[expr.array] +# Array and array index expressions + +## Array expressions + +r[expr.array.syntax] +```grammar,expressions +ArrayExpression -> `[` ArrayElements? `]` + +ArrayElements -> + Expression ( `,` Expression )* `,`? + | Expression `;` Expression +``` + +r[expr.array.constructor] +*Array expressions* construct [arrays][array]. Array expressions come in two forms. + +r[expr.array.array] +The first form lists out every value in the array. + +r[expr.array.array-syntax] +The syntax for this form is a comma-separated list of expressions of uniform type enclosed in square brackets. + +r[expr.array.array-behavior] +This produces an array containing each of these values in the order they are written. + +r[expr.array.repeat] +The syntax for the second form is two expressions separated by a semicolon (`;`) enclosed in square brackets. + +r[expr.array.repeat-operand] +The expression before the `;` is called the *repeat operand*. + +r[expr.array.length-operand] +The expression after the `;` is called the *length operand*. + +r[expr.array.length-restriction] +The length operand must either be an [inferred const] or be a [constant expression] of type `usize` (e.g. a [literal] or a [constant item]). + +```rust +const C: usize = 1; +let _: [u8; C] = [0; 1]; // Literal. +let _: [u8; C] = [0; C]; // Constant item. +let _: [u8; C] = [0; _]; // Inferred const. +let _: [u8; C] = [0; (((_)))]; // Inferred const. +``` + +> [!NOTE] +> In an array expression, an [inferred const] is parsed as an [expression][Expression] but then semantically treated as a separate kind of [const generic argument]. + +r[expr.array.repeat-behavior] +An array expression of this form creates an array with the length of the value of the length operand with each element being a copy of the repeat operand. That is, `[a; b]` creates an array containing `b` copies of the value of `a`. + +r[expr.array.repeat-copy] +If the length operand has a value greater than 1 then this requires the repeat operand to have a type that implements [`Copy`], to be a [const block expression], or to be a [path] to a constant item. + +r[expr.array.repeat-const-item] +When the repeat operand is a const block or a path to a constant item, it is evaluated the number of times specified in the length operand. + +r[expr.array.repeat-evaluation-zero] +If that value is `0`, then the const block or constant item is not evaluated at all. + +r[expr.array.repeat-non-const] +For expressions that are neither a const block nor a path to a constant item, it is evaluated exactly once, and then the result is copied the length operand's value times. + +```rust +[1, 2, 3, 4]; +["a", "b", "c", "d"]; +[0; 128]; // array with 128 zeros +[0u8, 0u8, 0u8, 0u8,]; +[[1, 0, 0], [0, 1, 0], [0, 0, 1]]; // 2D array +const EMPTY: Vec<i32> = Vec::new(); +[EMPTY; 2]; +``` + +r[expr.array.index] +## Array and slice indexing expressions + +r[expr.array.index.syntax] +```grammar,expressions +IndexExpression -> Expression `[` Expression `]` +``` + +r[expr.array.index.array] +[Array] and [slice]-typed values can be indexed by writing a square-bracket-enclosed expression of type `usize` (the index) after them. When the array is mutable, the resulting [memory location] can be assigned to. + +r[expr.array.index.trait] +For other types an index expression `a[b]` is equivalent to `*std::ops::Index::index(&a, b)`, or `*std::ops::IndexMut::index_mut(&mut a, b)` in a mutable place expression context, except that when the index expression undergoes [temporary lifetime extension], the indexed expression `a` also has its [temporary scope] extended. Just as with methods, Rust will also insert dereference operations on `a` repeatedly to find an implementation. + +```rust +// The temporary holding the result of `vec![()]` is extended to +// live to the end of the block, so `x` may be used in subsequent +// statements. +let x = &vec![()][0]; +# x; +``` + +```rust,compile_fail,E0716 +// The temporary holding the result of `vec![()]` is dropped at the +// end of the statement, so it's an error to use `y` after. +let y = &*std::ops::Index::index(&vec![()], 0); // ERROR +# y; +``` + +r[expr.array.index.zero-index] +Indices are zero-based for arrays and slices. + +r[expr.array.index.const] +Array access is a [constant expression], so bounds can be checked at compile-time with a constant index value. Otherwise a check will be performed at run-time that will put the thread in a [_panicked state_][panic] if it fails. + +```rust,should_panic +// lint is deny by default. +#![warn(unconditional_panic)] + +([1, 2, 3, 4])[2]; // Evaluates to 3 + +let b = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; +b[1][2]; // multidimensional array indexing + +let x = (["a", "b"])[10]; // warning: index out of bounds + +let n = 10; +let y = (["a", "b"])[n]; // panics + +let arr = ["a", "b"]; +arr[10]; // warning: index out of bounds +``` + +r[expr.array.index.trait-impl] +The array index expression can be implemented for types other than arrays and slices by implementing the [Index] and [IndexMut] traits. + +[`Copy`]: ../special-types-and-traits.md#copy +[IndexMut]: std::ops::IndexMut +[Index]: std::ops::Index +[array]: ../types/array.md +[const generic argument]: items.generics.const.argument +[const block expression]: expr.block.const +[constant expression]: ../const_eval.md#constant-expressions +[constant item]: ../items/constant-items.md +[inferred const]: items.generics.const.inferred +[literal]: ../tokens.md#literals +[memory location]: ../expressions.md#place-expressions-and-value-expressions +[panic]: ../panic.md +[path]: path-expr.md +[slice]: ../types/slice.md +[temporary lifetime extension]: destructors.scope.lifetime-extension +[temporary scope]: destructors.scope.temporary diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/await-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/await-expr.md new file mode 100644 index 00000000..ee6d90f0 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/await-expr.md @@ -0,0 +1,68 @@ +r[expr.await] +# Await expressions + +r[expr.await.syntax] +```grammar,expressions +AwaitExpression -> Expression `.` `await` +``` + +r[expr.await.intro] +An `await` expression is a syntactic construct for suspending a computation provided by an implementation of `std::future::IntoFuture` until the given future is ready to produce a value. + +r[expr.await.construct] +The syntax for an await expression is an expression with a type that implements the [`IntoFuture`] trait, called the *future operand*, then the token `.`, and then the `await` keyword. + +r[expr.await.allowed-positions] +Await expressions are legal only within an [async context], like an [`async fn`], [`async` closure], or [`async` block]. + +r[expr.await.effects] +More specifically, an await expression has the following effect. + +1. Create a future by calling [`IntoFuture::into_future`] on the future operand. +2. Evaluate the future to a [future] `tmp`; +3. Pin `tmp` using [`Pin::new_unchecked`]; +4. This pinned future is then polled by calling the [`Future::poll`] method and passing it the current [task context](#task-context); +5. If the call to `poll` returns [`Poll::Pending`], then the future returns `Poll::Pending`, suspending its state so that, when the surrounding async context is re-polled, execution returns to step 3; +6. Otherwise the call to `poll` must have returned [`Poll::Ready`], in which case the value contained in the [`Poll::Ready`] variant is used as the result of the `await` expression itself. + +r[expr.await.edition2018] +> [!EDITION-2018] +> Await expressions are only available beginning with Rust 2018. + +r[expr.await.task] +## Task context + +The task context refers to the [`Context`] which was supplied to the current [async context] when the async context itself was polled. Because `await` expressions are only legal in an async context, there must be some task context available. + +r[expr.await.desugar] +## Approximate desugaring + +Effectively, an await expression is roughly equivalent to the following non-normative desugaring: + +<!-- ignore: example expansion --> +```rust,ignore +match operand.into_future() { + mut pinned => loop { + let mut pin = unsafe { Pin::new_unchecked(&mut pinned) }; + match Pin::future::poll(Pin::borrow(&mut pin), &mut current_context) { + Poll::Ready(r) => break r, + Poll::Pending => yield Poll::Pending, + } + } +} +``` + +where the `yield` pseudo-code returns `Poll::Pending` and, when re-invoked, resumes execution from that point. The variable `current_context` refers to the context taken from the async environment. + +[`async fn`]: ../items/functions.md#async-functions +[`async` closure]: closure-expr.md#async-closures +[`async` block]: block-expr.md#async-blocks +[`Context`]: std::task::Context +[`future::poll`]: std::future::Future::poll +[`pin::new_unchecked`]: std::pin::Pin::new_unchecked +[`poll::Pending`]: std::task::Poll::Pending +[`poll::Ready`]: std::task::Poll::Ready +[async context]: ../expressions/block-expr.md#async-context +[future]: std::future::Future +[`IntoFuture`]: std::future::IntoFuture +[`IntoFuture::into_future`]: std::future::IntoFuture::into_future diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/block-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/block-expr.md new file mode 100644 index 00000000..8d0cf077 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/block-expr.md @@ -0,0 +1,365 @@ +r[expr.block] +# Block expressions + +r[expr.block.syntax] +```grammar,expressions +BlockExpression -> + `{` + InnerAttribute* + Statements? + `}` + +BlockExpressionNoInnerAttributes -> + `{` + Statements? + `}` + +Statements -> + Statement+ + | Statement+ ExpressionWithoutBlock + | ExpressionWithoutBlock +``` + +r[expr.block.intro] +A *block expression*, or *block*, is a control flow expression and anonymous namespace scope for items and variable declarations. + +r[expr.block.sequential-evaluation] +As a control flow expression, a block sequentially executes its component non-item declaration statements and then its final optional expression. + +r[expr.block.namespace] +As an anonymous namespace scope, item declarations are only in scope inside the block itself and variables declared by `let` statements are in scope from the next statement until the end of the block. See the [scopes] chapter for more details. + +r[expr.block.inner-attributes] +The syntax for a block is `{`, then any [inner attributes], then any number of [statements], then an optional expression, called the final operand, and finally a `}`. + +r[expr.block.statements] +Statements are usually required to be followed by a semicolon, with two exceptions: + +1. Item declaration statements do not need to be followed by a semicolon. +2. Expression statements usually require a following semicolon except if its outer expression is a flow control expression. + +r[expr.block.null-statement] +Furthermore, extra semicolons between statements are allowed, but these semicolons do not affect semantics. + +r[expr.block.evaluation] +When evaluating a block expression, each statement, except for item declaration statements, is executed sequentially. + +r[expr.block.result] +Then the final operand is executed, if given. + +r[expr.block.value-trailing-expr] +When a block contains a [final operand], the block has the type and value of that final operand. + +```rust +let x: u8 = { 0u8 }; // `0u8` is the final operand. +assert_eq!(x, 0); +let x: u8 = { (); 0u8 }; // As above. +assert_eq!(x, 0); +``` + +r[expr.block.value-no-trailing-expr] +When a block does not contain a [final operand] and the block does not diverge, the block has [unit type] and [unit value]. + +```rust +let x: () = {}; // Has no final operand. +assert_eq!(x, ()); +let x: () = { 0u8; }; // As above. +assert_eq!(x, ()); +``` + +r[expr.block.value-diverges-no-trailing-expr] +When a block does not contain a [final operand] and the block [diverges], the block has the [never type] and has no final value (because its type is [uninhabited]). + +```rust,no_run +fn f() -> ! { loop {}; } // Diverges and has no final operand. +// ^^^^^^^^^^^^ +// The body of a function is a block expression. +``` + +> [!NOTE] +> Observe that a block having no final operand is distinct from having an explicit final operand with unit type. E.g., even though this block diverges, the type of the block is [unit] rather than [never]. +> +> ```rust,compile_fail,E0308 +> fn f() -> ! { loop {}; () } // ERROR: Mismatched types. +> // ^^^^^^^^^^^^^^^ This block has unit type. +> ``` + +> [!NOTE] +> As a control flow expression, if a block expression is the outer expression of an expression statement, the expected type is `()` unless it is followed immediately by a semicolon. + +r[expr.block.diverging] +A block is considered to be [diverging][divergence] if all reachable control flow paths contain a diverging expression, unless that expression is a [place expression] that is not read from. + +```rust,no_run +fn no_control_flow() -> ! { + // There are no conditional statements, so this entire function body is diverging. + loop {} +} + +fn control_flow_diverging() -> ! { + // All paths are diverging, so this entire function body is diverging. + if true { + loop {} + } else { + loop {} + } +} + +fn control_flow_not_diverging() -> () { + // Some paths are not diverging, so this entire block is not diverging. + if true { + () + } else { + loop {} + } +} + +fn diverging_place_read(x: !) -> ! { + // A read of a place expression produces a diverging block. + let _x = x; +} +``` + +```rust,compile_fail,E0308 +fn diverging_place_not_read(x: !) -> ! { + // Assignment to `_` means the place is not read. + let _ = x; +} // ERROR: Mismatched types. +``` + +r[expr.block.value] +Blocks are always [value expressions] and evaluate the last operand in value expression context. + +> [!NOTE] +> This can be used to force moving a value if really needed. For example, the following example fails on the call to `consume_self` because the struct was moved out of `s` in the block expression. +> +> ```rust,compile_fail +> struct Struct; +> +> impl Struct { +> fn consume_self(self) {} +> fn borrow_self(&self) {} +> } +> +> fn move_by_block_expression() { +> let s = Struct; +> +> // Move the value out of `s` in the block expression. +> (&{ s }).borrow_self(); +> +> // Fails to execute because `s` is moved out of. +> s.consume_self(); +> } +> ``` + +r[expr.block.async] +## `async` blocks + +r[expr.block.async.syntax] +```grammar,expressions +AsyncBlockExpression -> `async` `move`? BlockExpression +``` + +r[expr.block.async.intro] +An *async block* is a variant of a block expression which evaluates to a future. + +r[expr.block.async.future-result] +The final expression of the block, if present, determines the result value of the future. + +r[expr.block.async.anonymous-type] +Executing an async block is similar to executing a closure expression: its immediate effect is to produce and return an anonymous type. + +r[expr.block.async.future] +Whereas closures return a type that implements one or more of the [`std::ops::Fn`] traits, however, the type returned for an async block implements the [`std::future::Future`] trait. + +r[expr.block.async.layout-unspecified] +The actual data format for this type is unspecified. + +> [!NOTE] +> The future type that rustc generates is roughly equivalent to an enum with one variant per `await` point, where each variant stores the data needed to resume from its corresponding point. + +r[expr.block.async.edition2018] +> [!EDITION-2018] +> Async blocks are only available beginning with Rust 2018. + +r[expr.block.async.capture] +### Capture modes + +Async blocks capture variables from their environment using the same [capture modes] as closures. Like closures, when written `async { .. }` the capture mode for each variable will be inferred from the content of the block. `async move { .. }` blocks however will move all referenced variables into the resulting future. + +r[expr.block.async.context] +### Async context + +Because async blocks construct a future, they define an **async context** which can in turn contain [`await` expressions]. Async contexts are established by async blocks as well as the bodies of async functions, whose semantics are defined in terms of async blocks. + +r[expr.block.async.function] +### Control-flow operators + +r[expr.block.async.function.intro] +Async blocks act like a function boundary, much like closures. + +r[expr.block.async.function.return-try] +Therefore, the `?` operator and `return` expressions both affect the output of the future, not the enclosing function or other context. That is, `return <expr>` from within an async block will return the result of `<expr>` as the output of the future. Similarly, if `<expr>?` propagates an error, that error is propagated as the result of the future. + +r[expr.block.async.function.control-flow] +Finally, the `break` and `continue` keywords cannot be used to branch out from an async block. Therefore the following is illegal: + +```rust,compile_fail +loop { + async move { + break; // error[E0267]: `break` inside of an `async` block + } +} +``` + +r[expr.block.const] +## `const` blocks + +r[expr.block.const.syntax] +```grammar,expressions +ConstBlockExpression -> `const` BlockExpression +``` + +r[expr.block.const.intro] +A *const block* is a variant of a block expression whose body evaluates at compile-time instead of at runtime. + +r[expr.block.const.context] +Const blocks allows you to define a constant value without having to define new [constant items], and thus they are also sometimes referred as *inline consts*. It also supports type inference so there is no need to specify the type, unlike [constant items]. + +r[expr.block.const.generic-params] +Const blocks have the ability to reference generic parameters in scope, unlike [free][free item] constant items. They are desugared to constant items with generic parameters in scope (similar to associated constants, but without a trait or type they are associated with). For example, this code: + +```rust +fn foo<T>() -> usize { + const { std::mem::size_of::<T>() + 1 } +} +``` + +is equivalent to: + +```rust +fn foo<T>() -> usize { + { + struct Const<T>(T); + impl<T> Const<T> { + const CONST: usize = std::mem::size_of::<T>() + 1; + } + Const::<T>::CONST + } +} +``` + +r[expr.block.const.evaluation] + +If the const block expression is executed at runtime, then the constant is guaranteed to be evaluated, even if its return value is ignored: + +```rust +fn foo<T>() -> usize { + // If this code ever gets executed, then the assertion has definitely + // been evaluated at compile-time. + const { assert!(std::mem::size_of::<T>() > 0); } + // Here we can have unsafe code relying on the type being non-zero-sized. + /* ... */ + 42 +} +``` + +r[expr.block.const.not-executed] + +If the const block expression is not executed at runtime, it may or may not be evaluated: +```rust,compile_fail +if false { + // The panic may or may not occur when the program is built. + const { panic!(); } +} +``` + +r[expr.block.unsafe] +## `unsafe` blocks + +r[expr.block.unsafe.syntax] +```grammar,expressions +UnsafeBlockExpression -> `unsafe` BlockExpression +``` + +r[expr.block.unsafe.intro] +_See [`unsafe` blocks] for more information on when to use `unsafe`_. + +A block of code can be prefixed with the `unsafe` keyword to permit [unsafe operations]. Examples: + +```rust +unsafe { + let b = [13u8, 17u8]; + let a = &b[0] as *const u8; + assert_eq!(*a, 13); + assert_eq!(*a.offset(1), 17); +} + +# unsafe fn an_unsafe_fn() -> i32 { 10 } +let a = unsafe { an_unsafe_fn() }; +``` + +r[expr.block.label] +## Labeled block expressions + +Labeled block expressions are documented in the [Loops and other breakable expressions] section. + +r[expr.block.attributes] +## Attributes on block expressions + +r[expr.block.attributes.inner-attributes] +[Inner attributes] are allowed directly after the opening brace of a block expression in the following situations: + +* [Function] and [method] bodies. +* Loop bodies ([`loop`], [`while`], and [`for`]). +* Block expressions used as a [statement]. +* Block expressions as elements of [array expressions], [tuple expressions], [call expressions], and tuple-style [struct] expressions. +* A block expression as the tail expression of another block expression. +<!-- Keep list in sync with expressions.md --> + +r[expr.block.attributes.valid] +The attributes that have meaning on a block expression are [`cfg`] and [the lint check attributes]. + +For example, this function returns `true` on unix platforms and `false` on other platforms. + +```rust +fn is_unix_platform() -> bool { + #[cfg(unix)] { true } + #[cfg(not(unix))] { false } +} +``` + +[`await` expressions]: await-expr.md +[`cfg`]: ../conditional-compilation.md +[`for`]: loop-expr.md#iterator-loops +[`loop`]: loop-expr.md#infinite-loops +[`unsafe` blocks]: ../unsafe-keyword.md#unsafe-blocks-unsafe- +[`while`]: loop-expr.md#predicate-loops +[array expressions]: array-expr.md +[call expressions]: call-expr.md +[capture modes]: ../types/closure.md#capture-modes +[constant items]: ../items/constant-items.md +[diverges]: expr.block.diverging +[final operand]: expr.block.inner-attributes +[free item]: ../glossary.md#free-item +[function]: ../items/functions.md +[inner attributes]: ../attributes.md +[method]: ../items/associated-items.md#methods +[mutable reference]: ../types/pointer.md#mutables-references- +[never type]: type.never +[never]: type.never +[place expression]: expr.place-value.place-memory-location +[scopes]: ../names/scopes.md +[shared references]: ../types/pointer.md#shared-references- +[statement]: ../statements.md +[statements]: ../statements.md +[struct]: struct-expr.md +[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[tuple expressions]: tuple-expr.md +[uninhabited]: glossary.uninhabited +[unit type]: type.tuple.unit +[unit value]: type.tuple.unit +[unit]: type.tuple.unit +[unsafe operations]: ../unsafety.md +[value expressions]: ../expressions.md#place-expressions-and-value-expressions +[Loops and other breakable expressions]: expr.loop.block-labels diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/call-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/call-expr.md new file mode 100644 index 00000000..09b8aeac --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/call-expr.md @@ -0,0 +1,107 @@ +r[expr.call] +# Call expressions + +r[expr.call.syntax] +```grammar,expressions +CallExpression -> Expression `(` CallParams? `)` + +CallParams -> Expression ( `,` Expression )* `,`? +``` + +r[expr.call.intro] +A *call expression* calls a function. The syntax of a call expression is an expression, called the *function operand*, followed by a parenthesized comma-separated list of expression, called the *argument operands*. + +r[expr.call.convergence] +If the function eventually returns, then the expression completes. + +r[expr.call.trait] +For [non-function types], the expression `f(...)` uses the method on one of the following traits based on the function operand: + +- [`Fn`] or [`AsyncFn`] --- shared reference. +- [`FnMut`] or [`AsyncFnMut`] --- mutable reference. +- [`FnOnce`] or [`AsyncFnOnce`] --- value. + +r[expr.call.autoref-deref] +An automatic borrow will be taken if needed. The function operand will also be [automatically dereferenced] as required. + +Some examples of call expressions: + +```rust +# fn add(x: i32, y: i32) -> i32 { 0 } +let three: i32 = add(1i32, 2i32); +let name: &'static str = (|| "Rust")(); +``` + +r[expr.call.desugar] +## Disambiguating function calls + +r[expr.call.desugar.fully-qualified] +All function calls are sugar for a more explicit [fully-qualified syntax]. + +r[expr.call.desugar.ambiguity] +Function calls may need to be fully qualified, depending on the ambiguity of a call in light of in-scope items. + +> [!NOTE] +> In the past, the terms "Unambiguous Function Call Syntax", "Universal Function Call Syntax", or "UFCS", have been used in documentation, issues, RFCs, and other community writings. However, these terms lack descriptive power and potentially confuse the issue at hand. We mention them here for searchability's sake. + +r[expr.call.desugar.limits] +Several situations often occur which result in ambiguities about the receiver or referent of method or associated function calls. These situations may include: + +* Multiple in-scope traits define methods with the same name for the same types +* Auto-`deref` is undesirable; for example, distinguishing between methods on a smart pointer itself and the pointer's referent +* Methods which take no arguments, like [`default()`], and return properties of a type, like [`size_of()`] + +r[expr.call.desugar.explicit-path] +To resolve the ambiguity, the programmer may refer to their desired method or function using more specific paths, types, or traits. + +For example, + +```rust +trait Pretty { + fn print(&self); +} + +trait Ugly { + fn print(&self); +} + +struct Foo; +impl Pretty for Foo { + fn print(&self) {} +} + +struct Bar; +impl Pretty for Bar { + fn print(&self) {} +} +impl Ugly for Bar { + fn print(&self) {} +} + +fn main() { + let f = Foo; + let b = Bar; + + // we can do this because we only have one item called `print` for `Foo`s + f.print(); + // more explicit, and, in the case of `Foo`, not necessary + Foo::print(&f); + // if you're not into the whole brevity thing + <Foo as Pretty>::print(&f); + + // b.print(); // Error: multiple 'print' found + // Bar::print(&b); // Still an error: multiple `print` found + + // necessary because of in-scope items defining `print` + <Bar as Pretty>::print(&b); +} +``` + +Refer to [RFC 132] for further details and motivations. + +[RFC 132]: https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md +[`default()`]: std::default::Default::default +[`size_of()`]: std::mem::size_of +[automatically dereferenced]: field-expr.md#automatic-dereferencing +[fully-qualified syntax]: ../paths.md#qualified-paths +[non-function types]: ../types/function-item.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/closure-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/closure-expr.md new file mode 100644 index 00000000..ac9a69da --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/closure-expr.md @@ -0,0 +1,110 @@ +r[expr.closure] +# Closure expressions + +r[expr.closure.syntax] +```grammar,expressions +ClosureExpression -> + `async`?[^cl-async-edition] + `move`? + ( `||` | `|` ClosureParameters? `|` ) + (Expression | `->` TypeNoBounds BlockExpression) + +ClosureParameters -> ClosureParam (`,` ClosureParam)* `,`? + +ClosureParam -> OuterAttribute* PatternNoTopAlt ( `:` Type )? +``` + +[^cl-async-edition]: The `async` qualifier is not allowed in the 2015 edition. + +r[expr.closure.intro] +A *closure expression*, also known as a lambda expression or a lambda, defines a [closure type] and evaluates to a value of that type. The syntax for a closure expression is an optional `async` keyword, an optional `move` keyword, then a pipe-symbol-delimited (`|`) comma-separated list of [patterns], called the *closure parameters* each optionally followed by a `:` and a type, then an optional `->` and type, called the *return type*, and then an expression, called the *closure body operand*. + +r[expr.closure.param-type] +The optional type after each pattern is a type annotation for the pattern. + +r[expr.closure.explicit-type-body] +If there is a return type, the closure body must be a [block]. + +r[expr.closure.parameter-restriction] +A closure expression denotes a function that maps a list of parameters onto the expression that follows the parameters. Just like a [`let` binding], the closure parameters are irrefutable [patterns], whose type annotation is optional and will be inferred from context if not given. + +r[expr.closure.unique-type] +Each closure expression has a unique, anonymous type. + +r[expr.closure.captures] +Significantly, closure expressions _capture their environment_, which regular [function definitions] do not. + +r[expr.closure.capture-inference] +Without the `move` keyword, the closure expression [infers how it captures each variable from its environment](../types/closure.md#capture-modes), preferring to capture by shared reference, effectively borrowing all outer variables mentioned inside the closure's body. + +r[expr.closure.capture-mut-ref] +If needed the compiler will infer that instead mutable references should be taken, or that the values should be moved or copied (depending on their type) from the environment. + +r[expr.closure.capture-move] +A closure can be forced to capture its environment by copying or moving values by prefixing it with the `move` keyword. This is often used to ensure that the closure's lifetime is `'static`. + +r[expr.closure.trait-impl] +## Closure trait implementations + +Which traits the closure type implements depends on how variables are captured, the types of the captured variables, and the presence of `async`. See the [call traits and coercions] chapter for how and when a closure implements `Fn`, `FnMut`, and `FnOnce`. The closure type implements [`Send`] and [`Sync`] if the type of every captured variable also implements the trait. + +r[expr.closure.async] +## Async closures + +r[expr.closure.async.intro] +Closures marked with the `async` keyword indicate that they are asynchronous in an analogous way to an [async function][items.fn.async]. + +r[expr.closure.async.future] +Calling the async closure does not perform any work, but instead evaluates to a value that implements [`Future`] that corresponds to the computation of the body of the closure. + +```rust +async fn takes_async_callback(f: impl AsyncFn(u64)) { + f(0).await; + f(1).await; +} + +async fn example() { + takes_async_callback(async |i| { + core::future::ready(i).await; + println!("done with {i}."); + }).await; +} +``` + +r[expr.closure.async.edition2018] +> [!EDITION-2018] +> Async closures are only available beginning with Rust 2018. + +## Example + +In this example, we define a function `ten_times` that takes a higher-order function argument, and we then call it with a closure expression as an argument, followed by a closure expression that moves values from its environment. + +```rust +fn ten_times<F>(f: F) where F: Fn(i32) { + for index in 0..10 { + f(index); + } +} + +ten_times(|j| println!("hello, {}", j)); +// With type annotations +ten_times(|j: i32| -> () { println!("hello, {}", j) }); + +let word = "konnichiwa".to_owned(); +ten_times(move |j| println!("{}, {}", word, j)); +``` + +## Attributes on closure parameters + +r[expr.closure.param-attributes] +Attributes on closure parameters follow the same rules and restrictions as [regular function parameters]. + +[`let` binding]: ../statements.md#let-statements +[`Send`]: ../special-types-and-traits.md#send +[`Sync`]: ../special-types-and-traits.md#sync +[block]: block-expr.md +[call traits and coercions]: ../types/closure.md#call-traits-and-coercions +[closure type]: ../types/closure.md +[function definitions]: ../items/functions.md +[patterns]: ../patterns.md +[regular function parameters]: ../items/functions.md#attributes-on-function-parameters diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/field-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/field-expr.md new file mode 100644 index 00000000..20739796 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/field-expr.md @@ -0,0 +1,79 @@ +r[expr.field] +# Field access expressions + +r[expr.field.syntax] +```grammar,expressions +FieldExpression -> Expression `.` IDENTIFIER +``` + +r[expr.field.intro] +A *field expression* is a [place expression] that evaluates to the location of a field of a [struct] or [union]. + +r[expr.field.mut] +When the operand is [mutable], the field expression is also mutable. + +r[expr.field.form] +The syntax for a field expression is an expression, called the *container operand*, then a `.`, and finally an [identifier]. + +r[expr.field.not-method-call] +Field expressions cannot be followed by a parenthetical comma-separated list of expressions, as that is instead parsed as a [method call expression]. That is, they cannot be the function operand of a [call expression]. + +> [!NOTE] +> Wrap the field expression in a [parenthesized expression] to use it in a call expression. +> +> ```rust +> # struct HoldsCallable<F: Fn()> { callable: F } +> let holds_callable = HoldsCallable { callable: || () }; +> +> // Invalid: Parsed as calling the method "callable" +> // holds_callable.callable(); +> +> // Valid +> (holds_callable.callable)(); +> ``` + +Examples: + +<!-- ignore: needs lots of support code --> +```rust,ignore +mystruct.myfield; +foo().x; +(Struct {a: 10, b: 20}).a; +(mystruct.function_field)() // Call expression containing a field expression +``` + +r[expr.field.autoref-deref] +## Automatic dereferencing + +If the type of the container operand implements [`Deref`] or [`DerefMut`][`Deref`] depending on whether the operand is [mutable], it is *automatically dereferenced* as many times as necessary to make the field access possible. This process is also called *autoderef* for short. + +r[expr.field.borrow] +## Borrowing + +The fields of a struct or a reference to a struct are treated as separate entities when borrowing. If the struct does not implement [`Drop`] and is stored in a local variable, this also applies to moving out of each of its fields. This also does not apply if automatic dereferencing is done through user-defined types other than [`Box`]. + +```rust +struct A { f1: String, f2: String, f3: String } +let mut x: A; +# x = A { +# f1: "f1".to_string(), +# f2: "f2".to_string(), +# f3: "f3".to_string() +# }; +let a: &mut String = &mut x.f1; // x.f1 borrowed mutably +let b: &String = &x.f2; // x.f2 borrowed immutably +let c: &String = &x.f2; // Can borrow again +let d: String = x.f3; // Move out of x.f3 +``` + +[`Box`]: ../special-types-and-traits.md#boxt +[`Deref`]: ../special-types-and-traits.md#deref-and-derefmut +[`drop`]: ../special-types-and-traits.md#drop +[identifier]: ../identifiers.md +[call expression]: call-expr.md +[method call expression]: method-call-expr.md +[mutable]: ../expressions.md#mutability +[parenthesized expression]: grouped-expr.md +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[struct]: ../items/structs.md +[union]: ../items/unions.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/grouped-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/grouped-expr.md new file mode 100644 index 00000000..20f2890b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/grouped-expr.md @@ -0,0 +1,47 @@ +r[expr.paren] +# Grouped expressions + +r[expr.paren.syntax] +```grammar,expressions +GroupedExpression -> `(` Expression `)` +``` + +r[expr.paren.intro] +A *parenthesized expression* wraps a single expression, evaluating to that expression. The syntax for a parenthesized expression is a `(`, then an expression, called the *enclosed operand*, and then a `)`. + +r[expr.paren.evaluation] +Parenthesized expressions evaluate to the value of the enclosed operand. + +r[expr.paren.place-or-value] +A parenthesized expression is a [place expression][place] if the enclosed operand is a place expression, and is a value expression if the enclosed operand is a value expression. + +r[expr.paren.override-precedence] +Parentheses can be used to explicitly modify the precedence order of subexpressions within an expression. + +An example of a parenthesized expression: + +```rust +let x: i32 = 2 + 3 * 4; // not parenthesized +let y: i32 = (2 + 3) * 4; // parenthesized +assert_eq!(x, 14); +assert_eq!(y, 20); +``` + +An example of a necessary use of parentheses is when calling a function pointer that is a member of a struct: + +```rust +# struct A { +# f: fn() -> &'static str +# } +# impl A { +# fn f(&self) -> &'static str { +# "The method f" +# } +# } +# let a = A{f: || "The field f"}; +# +assert_eq!( a.f (), "The method f"); +assert_eq!((a.f)(), "The field f"); +``` + +[place]: ../expressions.md#place-expressions-and-value-expressions diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/if-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/if-expr.md new file mode 100644 index 00000000..70314c36 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/if-expr.md @@ -0,0 +1,211 @@ +r[expr.if] +# `if` expressions + +r[expr.if.syntax] +```grammar,expressions +IfExpression -> + `if` Conditions BlockExpressionNoInnerAttributes + (`else` ( BlockExpressionNoInnerAttributes | IfExpression ) )? + +Conditions -> + Expression _except [StructExpression]_ + | LetChain + +LetChain -> LetChainCondition ( `&&` LetChainCondition )* + +LetChainCondition -> + Expression _except [ExcludedConditions]_ + | OuterAttribute* `let` Pattern `=` Scrutinee _except [ExcludedConditions]_ + +@root ExcludedConditions -> + StructExpression + | LazyBooleanExpression + | RangeExpr + | RangeFromExpr + | RangeInclusiveExpr + | AssignmentExpression + | CompoundAssignmentExpression +``` +<!-- TODO: The struct exception above needs clarification, see https://github.com/rust-lang/reference/issues/1808 + The chain grammar could use some work, see https://github.com/rust-lang/reference/issues/1811 +--> + +r[expr.if.intro] +The syntax of an `if` expression is a sequence of one or more condition operands separated by `&&`, followed by a consequent block, any number of `else if` conditions and blocks, and an optional trailing `else` block. + +r[expr.if.condition] +Condition operands must be either an [Expression] with a [boolean type] or a conditional `let` match. + +r[expr.if.condition-true] +If all of the condition operands evaluate to `true` and all of the `let` patterns successfully match their [scrutinee]s, the consequent block is executed and any subsequent `else if` or `else` block is skipped. + +r[expr.if.else-if] +If any condition operand evaluates to `false` or any `let` pattern does not match its scrutinee, the consequent block is skipped and any subsequent `else if` condition is evaluated. + +r[expr.if.else] +If all `if` and `else if` conditions evaluate to `false` then any `else` block is executed. + +r[expr.if.result] +An `if` expression evaluates to the same value as the executed block, or `()` if no block is evaluated. + +r[expr.if.type] +An `if` expression must have the same type in all situations. + +```rust +# let x = 3; +if x == 4 { + println!("x is four"); +} else if x == 3 { + println!("x is three"); +} else { + println!("x is something else"); +} + +// `if` can be used as an expression. +let y = if 12 * 15 > 150 { + "Bigger" +} else { + "Smaller" +}; +assert_eq!(y, "Bigger"); +``` + +r[expr.if.diverging] +An `if` expression [diverges] if either the condition expression diverges or if all arms diverge. + +```rust,no_run +fn diverging_condition() -> ! { + // Diverges because the condition expression diverges + if loop {} { + () + } else { + () + }; + // The semicolon above is important: The type of the `if` expression is + // `()`, despite being diverging. When the final body expression is + // elided, the type of the body is inferred to ! because the function body + // diverges. Without the semicolon, the `if` would be the tail expression + // with type `()`, which would fail to match the return type `!`. +} + +fn diverging_arms() -> ! { + // Diverges because all arms diverge + if true { + loop {} + } else { + loop {} + } +} +``` + +r[expr.if.let] +## `if let` patterns + +r[expr.if.let.intro] +`let` patterns in an `if` condition allow binding new variables into scope when the pattern matches successfully. + +The following examples illustrate bindings using `let` patterns: + +```rust +let dish = ("Ham", "Eggs"); + +// This body will be skipped because the pattern is refuted. +if let ("Bacon", b) = dish { + println!("Bacon is served with {}", b); +} else { + // This block is evaluated instead. + println!("No bacon will be served"); +} + +// This body will execute. +if let ("Ham", b) = dish { + println!("Ham is served with {}", b); +} + +if let _ = 5 { + println!("Irrefutable patterns are always true"); +} +``` + +r[expr.if.let.or-pattern] +Multiple patterns may be specified with the `|` operator. This has the same semantics as with `|` in [`match` expressions]: + +```rust +enum E { + X(u8), + Y(u8), + Z(u8), +} +let v = E::Y(12); +if let E::X(n) | E::Y(n) = v { + assert_eq!(n, 12); +} +``` + +r[expr.if.chains] +## Chains of conditions + +r[expr.if.chains.intro] +Multiple condition operands can be separated with `&&`. + +r[expr.if.chains.order] +Similar to a `&&` [LazyBooleanExpression], each operand is evaluated from left-to-right until an operand evaluates as `false` or a `let` match fails, in which case the subsequent operands are not evaluated. + +r[expr.if.chains.bindings] +The bindings of each pattern are put into scope to be available for the next condition operand and the consequent block. + +The following is an example of chaining multiple expressions, mixing `let` bindings and boolean expressions, and with expressions able to reference pattern bindings from previous expressions: + +```rust +fn single() { + let outer_opt = Some(Some(1i32)); + + if let Some(inner_opt) = outer_opt + && let Some(number) = inner_opt + && number == 1 + { + println!("Peek a boo"); + } +} +``` + +The above is equivalent to the following without using chains of conditions: + +```rust +fn nested() { + let outer_opt = Some(Some(1i32)); + + if let Some(inner_opt) = outer_opt { + if let Some(number) = inner_opt { + if number == 1 { + println!("Peek a boo"); + } + } + } +} +``` + +r[expr.if.chains.or] +If any condition operand is a `let` pattern, then none of the condition operands can be a `||` [lazy boolean operator expression][expr.bool-logic] due to ambiguity and precedence with the `let` scrutinee. + +> [!EXAMPLE] +> If a `||` expression is needed, then parentheses can be used. For example: +> +> ```rust +> # let foo = Some(123); +> # let condition1 = true; +> # let condition2 = false; +> if let Some(x) = foo +> // Parentheses are required here. +> && (condition1 || condition2) +> {} +> ``` + +r[expr.if.edition2024] +> [!EDITION-2024] +> Before the 2024 edition, let chains are not supported. That is, the [LetChain] grammar is not allowed in an `if` expression. + +[`match` expressions]: match-expr.md +[boolean type]: ../types/boolean.md +[diverges]: divergence +[scrutinee]: ../glossary.md#scrutinee diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/literal-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/literal-expr.md new file mode 100644 index 00000000..2b987c5c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/literal-expr.md @@ -0,0 +1,521 @@ +r[expr.literal] +# Literal expressions + +r[expr.literal.syntax] +```grammar,expressions +LiteralExpression -> + CHAR_LITERAL + | STRING_LITERAL + | RAW_STRING_LITERAL + | BYTE_LITERAL + | BYTE_STRING_LITERAL + | RAW_BYTE_STRING_LITERAL + | C_STRING_LITERAL + | RAW_C_STRING_LITERAL + | INTEGER_LITERAL + | FLOAT_LITERAL + | `true` + | `false` +``` + +r[expr.literal.intro] +A _literal expression_ is an expression consisting of a single token, rather than a sequence of tokens, that immediately and directly denotes the value it evaluates to, rather than referring to it by name or some other evaluation rule. + +r[expr.literal.const-expr] +A literal is a form of [constant expression], so is evaluated (primarily) at compile time. + +r[expr.literal.literal-token] +Each of the lexical [literal][literal tokens] forms described earlier can make up a literal expression, as can the keywords `true` and `false`. + +```rust +"hello"; // string type +'5'; // character type +5; // integer type +``` + +r[expr.literal.string-representation] +In the descriptions below, the _string representation_ of a token is the sequence of characters from the input which matched the token's production in a *Lexer* grammar snippet. + +> [!NOTE] +> This string representation never includes a character `U+000D` (CR) immediately followed by `U+000A` (LF): this pair would have been previously transformed into a single `U+000A` (LF). + +r[expr.literal.escape] +## Escapes + +r[expr.literal.escape.intro] +The descriptions of textual literal expressions below make use of several forms of _escape_. + +r[expr.literal.escape.sequence] +Each form of escape is characterised by: + * an _escape sequence_: a sequence of characters, which always begins with `U+005C` (`\`) + * an _escaped value_: either a single character or an empty sequence of characters + +In the definitions of escapes below: + * An _octal digit_ is any of the characters in the range \[`0`-`7`]. + * A _hexadecimal digit_ is any of the characters in the ranges \[`0`-`9`], \[`a`-`f`], or \[`A`-`F`]. + +r[expr.literal.escape.simple] +### Simple escapes + +Each sequence of characters occurring in the first column of the following table is an escape sequence. + +In each case, the escaped value is the character given in the corresponding entry in the second column. + +| Escape sequence | Escaped value | +|-----------------|--------------------------| +| `\0` | U+0000 (NUL) | +| `\t` | U+0009 (HT) | +| `\n` | U+000A (LF) | +| `\r` | U+000D (CR) | +| `\"` | U+0022 (QUOTATION MARK) | +| `\'` | U+0027 (APOSTROPHE) | +| `\\` | U+005C (REVERSE SOLIDUS) | + +r[expr.literal.escape.hex-octet] +### 8-bit escapes + +The escape sequence consists of `\x` followed by two hexadecimal digits. + +The escaped value is the character whose [Unicode scalar value] is the result of interpreting the final two characters in the escape sequence as a hexadecimal integer, as if by [`u8::from_str_radix`] with radix 16. + +> [!NOTE] +> The escaped value therefore has a [Unicode scalar value] in the range of [`u8`][numeric types]. + +r[expr.literal.escape.hex-ascii] +### 7-bit escapes + +The escape sequence consists of `\x` followed by an octal digit then a hexadecimal digit. + +The escaped value is the character whose [Unicode scalar value] is the result of interpreting the final two characters in the escape sequence as a hexadecimal integer, as if by [`u8::from_str_radix`] with radix 16. + +r[expr.literal.escape.unicode] +### Unicode escapes + +The escape sequence consists of `\u{`, followed by a sequence of characters each of which is a hexadecimal digit or `_`, followed by `}`. + +The escaped value is the character whose [Unicode scalar value] is the result of interpreting the hexadecimal digits contained in the escape sequence as a hexadecimal integer, as if by [`u32::from_str_radix`] with radix 16. + +> [!NOTE] +> The permitted forms of a [CHAR_LITERAL] or [STRING_LITERAL] token ensure that there is such a character. + +r[expr.literal.continuation] +### String continuation escapes + +The escape sequence consists of `\` followed immediately by `U+000A` (LF), and all following whitespace characters before the next non-whitespace character. For this purpose, the whitespace characters are `U+0009` (HT), `U+000A` (LF), `U+000D` (CR), and `U+0020` (SPACE). + +The escaped value is an empty sequence of characters. + +> [!NOTE] +> The effect of this form of escape is that a string continuation skips following whitespace, including additional newlines. Thus `a`, `b` and `c` are equal: +> +> ```rust +> let a = "foobar"; +> let b = "foo\ +> bar"; +> let c = "foo\ +> +> bar"; +> +> assert_eq!(a, b); +> assert_eq!(b, c); +> ``` +> +> Skipping additional newlines (as in example c) is potentially confusing and unexpected. This behavior may be adjusted in the future. Until a decision is made, it is recommended to avoid relying on skipping multiple newlines with line continuations. See [this issue](https://github.com/rust-lang/reference/pull/1042) for more information. + +r[expr.literal.char] +## Character literal expressions + +r[expr.literal.char.intro] +A character literal expression consists of a single [CHAR_LITERAL] token. + +r[expr.literal.char.type] +The expression's type is the primitive [`char`] type. + +r[expr.literal.char.no-suffix] +The token must not have a suffix. + +r[expr.literal.char.literal-content] +The token's _literal content_ is the sequence of characters following the first `U+0027` (`'`) and preceding the last `U+0027` (`'`) in the string representation of the token. + +r[expr.literal.char.represented] +The literal expression's _represented character_ is derived from the literal content as follows: + +r[expr.literal.char.escape] +* If the literal content is one of the following forms of escape sequence, the represented character is the escape sequence's escaped value: + * [Simple escapes] + * [7-bit escapes] + * [Unicode escapes] + +r[expr.literal.char.single] +* Otherwise the represented character is the single character that makes up the literal content. + +r[expr.literal.char.result] +The expression's value is the [`char`] corresponding to the represented character's [Unicode scalar value]. + +> [!NOTE] +> The permitted forms of a [CHAR_LITERAL] token ensure that these rules always produce a single character. + +Examples of character literal expressions: + +```rust +'R'; // R +'\''; // ' +'\x52'; // R +'\u{00E6}'; // LATIN SMALL LETTER AE (U+00E6) +``` + +r[expr.literal.string] +## String literal expressions + +r[expr.literal.string.intro] +A string literal expression consists of a single [STRING_LITERAL] or [RAW_STRING_LITERAL] token. + +r[expr.literal.string.type] +The expression's type is a shared reference (with `static` lifetime) to the primitive [`str`] type. That is, the type is `&'static str`. + +r[expr.literal.string.no-suffix] +The token must not have a suffix. + +r[expr.literal.string.literal-content] +The token's _literal content_ is the sequence of characters following the first `U+0022` (`"`) and preceding the last `U+0022` (`"`) in the string representation of the token. + +r[expr.literal.string.represented] +The literal expression's _represented string_ is a sequence of characters derived from the literal content as follows: + +r[expr.literal.string.escape] +* If the token is a [STRING_LITERAL], each escape sequence of any of the following forms occurring in the literal content is replaced by the escape sequence's escaped value. + * [Simple escapes] + * [7-bit escapes] + * [Unicode escapes] + * [String continuation escapes] + + These replacements take place in left-to-right order. For example, the token `"\\x41"` is converted to the characters `\` `x` `4` `1`. + +r[expr.literal.string.raw] +* If the token is a [RAW_STRING_LITERAL], the represented string is identical to the literal content. + +r[expr.literal.string.result] +The expression's value is a reference to a statically allocated [`str`] containing the UTF-8 encoding of the represented string. + +Examples of string literal expressions: + +```rust +"foo"; r"foo"; // foo +"\"foo\""; r#""foo""#; // "foo" + +"foo #\"# bar"; +r##"foo #"# bar"##; // foo #"# bar + +"\x52"; "R"; r"R"; // R +"\\x52"; r"\x52"; // \x52 +``` + +r[expr.literal.byte-char] +## Byte literal expressions + +r[expr.literal.byte-char.intro] +A byte literal expression consists of a single [BYTE_LITERAL] token. + +r[expr.literal.byte-char.literal] +The expression's type is the primitive [`u8`][numeric types] type. + +r[expr.literal.byte-char.no-suffix] +The token must not have a suffix. + +r[expr.literal.byte-char.literal-content] +The token's _literal content_ is the sequence of characters following the first `U+0027` (`'`) and preceding the last `U+0027` (`'`) in the string representation of the token. + +r[expr.literal.byte-char.represented] +The literal expression's _represented character_ is derived from the literal content as follows: + +r[expr.literal.byte-char.escape] +* If the literal content is one of the following forms of escape sequence, the represented character is the escape sequence's escaped value: + * [Simple escapes] + * [8-bit escapes] + +r[expr.literal.byte-char.single] +* Otherwise the represented character is the single character that makes up the literal content. + +r[expr.literal.byte-char.result] +The expression's value is the represented character's [Unicode scalar value]. + +> [!NOTE] +> The permitted forms of a [BYTE_LITERAL] token ensure that these rules always produce a single character, whose Unicode scalar value is in the range of [`u8`][numeric types]. + +Examples of byte literal expressions: + +```rust +b'R'; // 82 +b'\''; // 39 +b'\x52'; // 82 +b'\xA0'; // 160 +``` + +r[expr.literal.byte-string] +## Byte string literal expressions + +r[expr.literal.byte-string.intro] +A byte string literal expression consists of a single [BYTE_STRING_LITERAL] or [RAW_BYTE_STRING_LITERAL] token. + +r[expr.literal.byte-string.type] +The expression's type is a shared reference (with `static` lifetime) to an array whose element type is [`u8`][numeric types]. That is, the type is `&'static [u8; N]`, where `N` is the number of bytes in the represented string described below. + +r[expr.literal.byte-string.no-suffix] +The token must not have a suffix. + +r[expr.literal.byte-string.literal-content] +The token's _literal content_ is the sequence of characters following the first `U+0022` (`"`) and preceding the last `U+0022` (`"`) in the string representation of the token. + +r[expr.literal.byte-string.represented] +The literal expression's _represented string_ is a sequence of characters derived from the literal content as follows: + +r[expr.literal.byte-string.escape] +* If the token is a [BYTE_STRING_LITERAL], each escape sequence of any of the following forms occurring in the literal content is replaced by the escape sequence's escaped value. + * [Simple escapes] + * [8-bit escapes] + * [String continuation escapes] + + These replacements take place in left-to-right order. For example, the token `b"\\x41"` is converted to the characters `\` `x` `4` `1`. + +r[expr.literal.byte-string.raw] +* If the token is a [RAW_BYTE_STRING_LITERAL], the represented string is identical to the literal content. + +r[expr.literal.byte-string.result] +The expression's value is a reference to a statically allocated array containing the [Unicode scalar values] of the characters in the represented string, in the same order. + +> [!NOTE] +> The permitted forms of [BYTE_STRING_LITERAL] and [RAW_BYTE_STRING_LITERAL] tokens ensure that these rules always produce array element values in the range of [`u8`][numeric types]. + +Examples of byte string literal expressions: + +```rust +b"foo"; br"foo"; // foo +b"\"foo\""; br#""foo""#; // "foo" + +b"foo #\"# bar"; +br##"foo #"# bar"##; // foo #"# bar + +b"\x52"; b"R"; br"R"; // R +b"\\x52"; br"\x52"; // \x52 +``` + +r[expr.literal.c-string] +## C string literal expressions + +r[expr.literal.c-string.intro] +A C string literal expression consists of a single [C_STRING_LITERAL] or [RAW_C_STRING_LITERAL] token. + +r[expr.literal.c-string.type] +The expression's type is a shared reference (with `static` lifetime) to the standard library [CStr] type. That is, the type is `&'static core::ffi::CStr`. + +r[expr.literal.c-string.no-suffix] +The token must not have a suffix. + +r[expr.literal.c-string.literal-content] +The token's _literal content_ is the sequence of characters following the first `"` and preceding the last `"` in the string representation of the token. + +r[expr.literal.c-string.represented] +The literal expression's _represented bytes_ are a sequence of bytes derived from the literal content as follows: + +r[expr.literal.c-string.escape] +* If the token is a [C_STRING_LITERAL], the literal content is treated as a sequence of items, each of which is either a single Unicode character other than `\` or an [escape]. The sequence of items is converted to a sequence of bytes as follows: + * Each single Unicode character contributes its UTF-8 representation. + * Each [simple escape] contributes the [Unicode scalar value] of its escaped value. + * Each [8-bit escape] contributes a single byte containing the [Unicode scalar value] of its escaped value. + * Each [unicode escape] contributes the UTF-8 representation of its escaped value. + * Each [string continuation escape] contributes no bytes. + +r[expr.literal.c-string.raw] +* If the token is a [RAW_C_STRING_LITERAL], the represented bytes are the UTF-8 encoding of the literal content. + +> [!NOTE] +> The permitted forms of [C_STRING_LITERAL] and [RAW_C_STRING_LITERAL] tokens ensure that the represented bytes never include a null byte. + +r[expr.literal.c-string.result] +The expression's value is a reference to a statically allocated [CStr] whose array of bytes contains the represented bytes followed by a null byte. + +Examples of C string literal expressions: + +```rust +c"foo"; cr"foo"; // foo +c"\"foo\""; cr#""foo""#; // "foo" + +c"foo #\"# bar"; +cr##"foo #"# bar"##; // foo #"# bar + +c"\x52"; c"R"; cr"R"; // R +c"\\x52"; cr"\x52"; // \x52 + +c"æ"; // LATIN SMALL LETTER AE (U+00E6) +c"\u{00E6}"; // LATIN SMALL LETTER AE (U+00E6) +c"\xC3\xA6"; // LATIN SMALL LETTER AE (U+00E6) + +c"\xE6".to_bytes(); // [230] +c"\u{00E6}".to_bytes(); // [195, 166] +``` + +r[expr.literal.int] +## Integer literal expressions + +r[expr.literal.int.intro] +An integer literal expression consists of a single [INTEGER_LITERAL] token. + +r[expr.literal.int.suffix] +If the token has a [suffix], the suffix must be the name of one of the [primitive integer types][numeric types]: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, or `isize`, and the expression has that type. + +r[expr.literal.int.infer] +If the token has no suffix, the expression's type is determined by type inference: + +r[expr.literal.int.inference-unique-type] +* If an integer type can be _uniquely_ determined from the surrounding program context, the expression has that type. + +r[expr.literal.int.inference-default] +* If the program context under-constrains the type, it defaults to the signed 32-bit integer `i32`. + +r[expr.literal.int.inference-error] +* If the program context over-constrains the type, it is considered a static type error. + +Examples of integer literal expressions: + +```rust +123; // type i32 +123i32; // type i32 +123u32; // type u32 +123_u32; // type u32 +let a: u64 = 123; // type u64 + +0xff; // type i32 +0xff_u8; // type u8 + +0o70; // type i32 +0o70_i16; // type i16 + +0b1111_1111_1001_0000; // type i32 +0b1111_1111_1001_0000i64; // type i64 + +0usize; // type usize +``` + +r[expr.literal.int.representation] +The value of the expression is determined from the string representation of the token as follows: + +r[expr.literal.int.radix] +* An integer radix is chosen by inspecting the first two characters of the string, as follows: + + * `0b` indicates radix 2 + * `0o` indicates radix 8 + * `0x` indicates radix 16 + * otherwise the radix is 10. + +r[expr.literal.int.radix-prefix-stripped] +* If the radix is not 10, the first two characters are removed from the string. + +r[expr.literal.int.type-suffix-stripped] +* Any suffix is removed from the string. + +r[expr.literal.int.separators-stripped] +* Any underscores are removed from the string. + +r[expr.literal.int.u128-value] +* The string is converted to a `u128` value as if by [`u128::from_str_radix`] with the chosen radix. If the value does not fit in `u128`, it is a compiler error. + +r[expr.literal.int.cast] +* The `u128` value is converted to the expression's type via a [numeric cast]. + +> [!NOTE] +> The final cast will truncate the value of the literal if it does not fit in the expression's type. `rustc` includes a [lint check] named `overflowing_literals`, defaulting to `deny`, which rejects expressions where this occurs. + +> [!NOTE] +> `-1i8`, for example, is an application of the [negation operator] to the literal expression `1i8`, not a single integer literal expression. See [Overflow] for notes on representing the most negative value for a signed type. + +r[expr.literal.float] +## Floating-point literal expressions + +r[expr.literal.float.intro] +A floating-point literal expression has one of two forms: + * a single [FLOAT_LITERAL] token + * a single [INTEGER_LITERAL] token which has a suffix and no radix indicator + +r[expr.literal.float.suffix] +If the token has a [suffix], the suffix must be the name of one of the [primitive floating-point types][floating-point types]: `f32` or `f64`, and the expression has that type. + +r[expr.literal.float.infer] +If the token has no suffix, the expression's type is determined by type inference: + +r[expr.literal.float.inference-unique-type] +* If a floating-point type can be _uniquely_ determined from the surrounding program context, the expression has that type. + +r[expr.literal.float.inference-default] +* If the program context under-constrains the type, it defaults to `f64`. + +r[expr.literal.float.inference-error] +* If the program context over-constrains the type, it is considered a static type error. + +Examples of floating-point literal expressions: + +```rust +123.0f64; // type f64 +0.1f64; // type f64 +0.1f32; // type f32 +12E+99_f64; // type f64 +5f32; // type f32 +let x: f64 = 2.; // type f64 +``` + +r[expr.literal.float.result] +The value of the expression is determined from the string representation of the token as follows: + +r[expr.literal.float.type-suffix-stripped] +* Any suffix is removed from the string. + +r[expr.literal.float.separators-stripped] +* Any underscores are removed from the string. + +r[expr.literal.float.value] +* The string is converted to the expression's type as if by [`f32::from_str`] or [`f64::from_str`]. + +> [!NOTE] +> `-1.0`, for example, is an application of the [negation operator] to the literal expression `1.0`, not a single floating-point literal expression. + +> [!NOTE] +> `inf` and `NaN` are not literal tokens. The [`f32::INFINITY`], [`f64::INFINITY`], [`f32::NAN`], and [`f64::NAN`] constants can be used instead of literal expressions. In `rustc`, a literal large enough to be evaluated as infinite will trigger the `overflowing_literals` lint check. + +r[expr.literal.bool] +## Boolean literal expressions + +r[expr.literal.bool.intro] +A boolean literal expression consists of one of the keywords `true` or `false`. + +r[expr.literal.bool.result] +The expression's type is the primitive [boolean type], and its value is: + * true if the keyword is `true` + * false if the keyword is `false` + +[Escape]: #escapes +[Simple escape]: #simple-escapes +[Simple escapes]: #simple-escapes +[8-bit escape]: #8-bit-escapes +[8-bit escapes]: #8-bit-escapes +[7-bit escape]: #7-bit-escapes +[7-bit escapes]: #7-bit-escapes +[Unicode escape]: #unicode-escapes +[Unicode escapes]: #unicode-escapes +[String continuation escape]: #string-continuation-escapes +[String continuation escapes]: #string-continuation-escapes +[boolean type]: ../types/boolean.md +[constant expression]: ../const_eval.md#constant-expressions +[CStr]: core::ffi::CStr +[floating-point types]: ../types/numeric.md#floating-point-types +[lint check]: ../attributes/diagnostics.md#lint-check-attributes +[literal tokens]: ../tokens.md#literals +[numeric cast]: operator-expr.md#numeric-cast +[numeric types]: ../types/numeric.md +[suffix]: ../tokens.md#suffixes +[negation operator]: operator-expr.md#negation-operators +[overflow]: operator-expr.md#overflow +[Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value +[Unicode scalar values]: http://www.unicode.org/glossary/#unicode_scalar_value +[`char`]: ../types/char.md +[`f32::from_str`]: ../../core/primitive.f32.md#method.from_str +[`f64::from_str`]: ../../core/primitive.f64.md#method.from_str +[`str`]: ../types/str.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/loop-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/loop-expr.md new file mode 100644 index 00000000..8e672954 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/loop-expr.md @@ -0,0 +1,461 @@ +r[expr.loop] +# Loops and other breakable expressions + +r[expr.loop.syntax] +```grammar,expressions +LoopExpression -> + LoopLabel? ( + InfiniteLoopExpression + | PredicateLoopExpression + | IteratorLoopExpression + | LabelBlockExpression + ) +``` + +r[expr.loop.intro] +Rust supports four loop expressions: + +* A [`loop` expression](#infinite-loops) denotes an infinite loop. +* A [`while` expression](#predicate-loops) loops until a predicate is false. +* A [`for` expression](#iterator-loops) extracts values from an iterator, looping until the iterator is empty. +* A [labeled block expression][expr.loop.block-labels] runs a loop exactly once, but allows exiting the loop early with `break`. + +r[expr.loop.break-label] +All four types of loop support [`break` expressions](#break-expressions), and [labels](#loop-labels). + +r[expr.loop.continue-label] +All except labeled block expressions support [`continue` expressions](#continue-expressions). + +r[expr.loop.explicit-result] +Only `loop` and labeled block expressions support [evaluation to non-trivial values](#break-and-loop-values). + +r[expr.loop.infinite] +## Infinite loops + +r[expr.loop.infinite.syntax] +```grammar,expressions +InfiniteLoopExpression -> `loop` BlockExpression +``` + +r[expr.loop.infinite.intro] +A `loop` expression repeats execution of its body continuously: `loop { println!("I live."); }`. + +r[expr.loop.infinite.diverging] +A `loop` expression without an associated `break` expression is [diverging] and has type [`!`]. + +r[expr.loop.infinite.break] +A `loop` expression containing associated [`break` expression(s)](#break-expressions) may terminate, and must have type compatible with the value of the `break` expression(s). + +r[expr.loop.while] +## Predicate loops + +r[expr.loop.while.syntax] +```grammar,expressions +PredicateLoopExpression -> `while` Conditions BlockExpression +``` + +r[expr.loop.while.intro] +A `while` loop expression allows repeating the evaluation of a block while a set of conditions remain true. + +r[expr.loop.while.condition] +Condition operands must be either an [Expression] with a [boolean type] or a conditional `let` match. If all of the condition operands evaluate to `true` and all of the `let` patterns successfully match their [scrutinee]s, then the loop body block executes. + +r[expr.loop.while.repeat] +After the loop body successfully executes, the condition operands are re-evaluated to determine if the body should be executed again. + +r[expr.loop.while.exit] +If any condition operand evaluates to `false` or any `let` pattern does not match its scrutinee, the body is not executed and execution continues after the `while` expression. + +r[expr.loop.while.eval] +A `while` expression evaluates to `()`. + +An example: + +```rust +let mut i = 0; + +while i < 10 { + println!("hello"); + i = i + 1; +} +``` + +r[expr.loop.while.let] +### `while let` patterns + +r[expr.loop.while.let.intro] +`let` patterns in a `while` condition allow binding new variables into scope when the pattern matches successfully. The following examples illustrate bindings using `let` patterns: + +```rust +let mut x = vec![1, 2, 3]; + +while let Some(y) = x.pop() { + println!("y = {}", y); +} + +while let _ = 5 { + println!("Irrefutable patterns are always true"); + break; +} +``` + +r[expr.loop.while.let.desugar] +A `while let` loop is equivalent to a `loop` expression containing a [`match` expression] as follows. + +<!-- ignore: expansion example --> +```rust,ignore +'label: while let PATS = EXPR { + /* loop body */ +} +``` + +is equivalent to + +<!-- ignore: expansion example --> +```rust,ignore +'label: loop { + match EXPR { + PATS => { /* loop body */ }, + _ => break, + } +} +``` + +r[expr.loop.while.let.or-pattern] +Multiple patterns may be specified with the `|` operator. This has the same semantics as with `|` in `match` expressions: + +```rust +let mut vals = vec![2, 3, 1, 2, 2]; +while let Some(v @ 1) | Some(v @ 2) = vals.pop() { + // Prints 2, 2, then 1 + println!("{}", v); +} +``` + +r[expr.loop.while.chains] +### `while` condition chains + +r[expr.loop.while.chains.intro] +Multiple condition operands can be separated with `&&`. These have the same semantics and restrictions as [`if` condition chains]. + +The following is an example of chaining multiple expressions, mixing `let` bindings and boolean expressions, and with expressions able to reference pattern bindings from previous expressions: + +```rust +fn main() { + let outer_opt = Some(Some(1i32)); + + while let Some(inner_opt) = outer_opt + && let Some(number) = inner_opt + && number == 1 + { + println!("Peek a boo"); + break; + } +} +``` + +r[expr.loop.for] +## Iterator loops + +r[expr.loop.for.syntax] +```grammar,expressions +IteratorLoopExpression -> + `for` Pattern `in` Expression _except [StructExpression]_ BlockExpression +``` +<!-- TODO: The exception above isn't accurate, see https://github.com/rust-lang/reference/issues/569 --> + +r[expr.loop.for.intro] +A `for` expression is a syntactic construct for looping over elements provided by an implementation of `std::iter::IntoIterator`. + +r[expr.loop.for.condition] +If the iterator yields a value, that value is matched against the irrefutable pattern, the body of the loop is executed, and then control returns to the head of the `for` loop. If the iterator is empty, the `for` expression completes. + +An example of a `for` loop over the contents of an array: + +```rust +let v = &["apples", "cake", "coffee"]; + +for text in v { + println!("I like {}.", text); +} +``` + +An example of a for loop over a series of integers: + +```rust +let mut sum = 0; +for n in 1..11 { + sum += n; +} +assert_eq!(sum, 55); +``` + +r[expr.loop.for.desugar] +A `for` loop is equivalent to a `loop` expression containing a [`match` expression] as follows: + +<!-- ignore: expansion example --> +```rust,ignore +'label: for PATTERN in iter_expr { + /* loop body */ +} +``` + +is equivalent to + +<!-- ignore: expansion example --> +```rust,ignore +{ + let result = match IntoIterator::into_iter(iter_expr) { + mut iter => 'label: loop { + let mut next; + match Iterator::next(&mut iter) { + Option::Some(val) => next = val, + Option::None => break, + }; + let PATTERN = next; + let () = { /* loop body */ }; + }, + }; + result +} +``` + +r[expr.loop.for.lang-items] +`IntoIterator`, `Iterator`, and `Option` are always the standard library items here, not whatever those names resolve to in the current scope. + +The variable names `next`, `iter`, and `val` are for exposition only, they do not actually have names the user can type. + +> [!NOTE] +> The outer `match` is used to ensure that any [temporary values] in `iter_expr` don't get dropped before the loop is finished. `next` is declared before being assigned because it results in types being inferred correctly more often. + +r[expr.loop.label] +## Loop labels + +r[expr.loop.label.syntax] +```grammar,expressions +LoopLabel -> LIFETIME_OR_LABEL `:` +``` + +r[expr.loop.label.intro] +A loop expression may optionally have a _label_. The label is written as a lifetime preceding the loop expression, as in `'foo: loop { break 'foo; }`, `'bar: while false {}`, `'humbug: for _ in 0..0 {}`. + +r[expr.loop.label.control-flow] +If a label is present, then labeled `break` and `continue` expressions nested within this loop may exit out of this loop or return control to its head. See [break expressions](#break-expressions) and [continue expressions](#continue-expressions). + +r[expr.loop.label.ref] +Labels follow the hygiene and shadowing rules of local variables. For example, this code will print "outer loop": + +```rust +'a: loop { + 'a: loop { + break 'a; + } + print!("outer loop"); + break 'a; +} +``` + +`'_` is not a valid loop label. + +r[expr.loop.break] +## `break` expressions + +r[expr.loop.break.syntax] +```grammar,expressions +BreakExpression -> `break` LIFETIME_OR_LABEL? Expression? +``` + +r[expr.loop.break.intro] +When `break` is encountered, execution of the associated loop body is immediately terminated, for example: + +```rust +let mut last = 0; +for x in 1..100 { + if x > 12 { + break; + } + last = x; +} +assert_eq!(last, 12); +``` + +r[expr.loop.break.diverging] +A `break` expression is [diverging] and has a type of [`!`]. + +r[expr.loop.break.label] +A `break` expression is normally associated with the innermost `loop`, `for` or `while` loop enclosing the `break` expression, but a [label](#loop-labels) can be used to specify which enclosing loop is affected. Example: + +```rust +'outer: loop { + while true { + break 'outer; + } +} +``` + +r[expr.loop.break.value] +A `break` expression is only permitted in the body of a loop, and has one of the forms `break`, `break 'label` or ([see below](#break-and-loop-values)) `break EXPR` or `break 'label EXPR`. + +r[expr.loop.break-value.implicit-value] +In a [`loop` with break expressions][expr.loop.break-value] or a [labeled block expression], a `break` without an expression is equivalent to `break ()`. + +r[expr.loop.block-labels] +## Labeled block expressions + +r[expr.loop.block-labels.syntax] +```grammar,expressions +LabelBlockExpression -> BlockExpression +``` + +r[expr.loop.block-labels.intro] +Labeled block expressions are exactly like block expressions, except that they allow using `break` expressions within the block. + +r[expr.loop.block-labels.break] +Unlike loops, `break` expressions within a labeled block expression *must* have a label (i.e. the label is not optional). + +r[expr.loop.block-labels.label-required] +Similarly, labeled block expressions *must* begin with a label. + +```rust +# fn do_thing() {} +# fn condition_not_met() -> bool { true } +# fn do_next_thing() {} +# fn do_last_thing() {} +let result = 'block: { + do_thing(); + if condition_not_met() { + break 'block 1; + } + do_next_thing(); + if condition_not_met() { + break 'block 2; + } + do_last_thing(); + 3 +}; +``` + +r[expr.loop.block-labels.type] +The type of a labeled block expression is the [least upper bound] of all of the break operands and the final operand. If the final operand is omitted, the type of the final operand defaults to the [unit type], unless the block [diverges][expr.block.diverging], in which case it is the [never type]. + +> [!EXAMPLE] +> ```rust +> fn example(condition: bool) { +> let s = String::from("owned"); +> +> let _: &str = 'block: { +> if condition { +> break 'block &s; // &String coerced to &str via Deref +> } +> break 'block "literal"; // &'static str coerced to &str +> }; +> } +> ``` + +r[expr.loop.continue] +## `continue` expressions + +r[expr.loop.continue.syntax] +```grammar,expressions +ContinueExpression -> `continue` LIFETIME_OR_LABEL? +``` + +r[expr.loop.continue.intro] +When `continue` is encountered, the current iteration of the associated loop body is immediately terminated, returning control to the loop *head*. + +r[expr.loop.continue.diverging] +A `continue` expression is [diverging] and has a type of [`!`]. + +r[expr.loop.continue.while] +In the case of a `while` loop, the head is the conditional operands controlling the loop. + +r[expr.loop.continue.for] +In the case of a `for` loop, the head is the call-expression controlling the loop. + +r[expr.loop.continue.label] +Like `break`, `continue` is normally associated with the innermost enclosing loop, but `continue 'label` may be used to specify the loop affected. + +r[expr.loop.continue.in-loop-only] +A `continue` expression is only permitted in the body of a loop. + +r[expr.loop.break-value] +## `break` and loop values + +r[expr.loop.break-value.intro] +When associated with a `loop`, a break expression may be used to return a value from that loop, via one of the forms `break EXPR` or `break 'label EXPR`, where `EXPR` is an expression whose result is returned from the `loop`. For example: + +```rust +let (mut a, mut b) = (1, 1); +let result = loop { + if b > 10 { + break b; + } + let c = a + b; + a = b; + b = c; +}; +// first number in Fibonacci sequence over 10: +assert_eq!(result, 13); +``` + +r[expr.loop.break-value.type] +The type of a `loop` with associated `break` expressions is the [least upper bound] of all of the break operands. + +> [!EXAMPLE] +> ```rust +> fn example(condition: bool) { +> let s = String::from("owned"); +> +> let _: &str = loop { +> if condition { +> break &s; // &String coerced to &str via Deref +> } +> break "literal"; // &'static str coerced to &str +> }; +> } +> ``` + +r[expr.loop.break-value.diverging] +A `loop` with associated `break` expressions does not [diverge] if any of the break operands do not diverge. If all of the `break` operands diverge, then the `loop` expression also diverges. + +> [!EXAMPLE] +> ```rust +> fn diverging_loop_with_break(condition: bool) -> ! { +> // This loop is diverging because all `break` operands are diverging. +> loop { +> if condition { +> break loop {}; +> } else { +> break panic!(); +> } +> } +> } +> ``` +> +> ```rust,compile_fail,E0308 +> fn loop_with_non_diverging_break(condition: bool) -> ! { +> // The type of this loop is i32 even though one of the breaks is +> // diverging. +> loop { +> if condition { +> break loop {}; +> } else { +> break 123i32; +> } +> } // ERROR: expected `!`, found `i32` +> } +> ``` + +[`!`]: type.never +[`if` condition chains]: if-expr.md#chains-of-conditions +[`if` expressions]: if-expr.md +[`match` expression]: match-expr.md +[boolean type]: ../types/boolean.md +[diverge]: divergence +[diverging]: divergence +[labeled block expression]: expr.loop.block-labels +[least upper bound]: coerce.least-upper-bound +[never type]: type.never +[scrutinee]: ../glossary.md#scrutinee +[temporary values]: ../expressions.md#temporaries +[unit type]: type.tuple.unit diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/match-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/match-expr.md new file mode 100644 index 00000000..2cbe38ea --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/match-expr.md @@ -0,0 +1,270 @@ +r[expr.match] +# `match` expressions + +r[expr.match.syntax] +```grammar,expressions +MatchExpression -> + `match` Scrutinee `{` + InnerAttribute* + MatchArms? + `}` + +Scrutinee -> Expression _except [StructExpression]_ + +MatchArms -> + ( MatchArm `=>` ( ExpressionWithoutBlock `,` | ExpressionWithBlock `,`? ) )* + MatchArm `=>` Expression `,`? + +MatchArm -> OuterAttribute* Pattern MatchArmGuard? + +MatchArmGuard -> `if` MatchConditions + +MatchConditions -> + MatchGuardChain + | Expression + +MatchGuardChain -> MatchGuardCondition ( `&&` MatchGuardCondition )* + +MatchGuardCondition -> + Expression _except [ExcludedMatchConditions]_ + | OuterAttribute* `let` Pattern `=` MatchGuardScrutinee + +MatchGuardScrutinee -> Expression _except [ExcludedMatchConditions]_ + +@root ExcludedMatchConditions -> + LazyBooleanExpression + | RangeExpr + | RangeFromExpr + | RangeInclusiveExpr + | AssignmentExpression + | CompoundAssignmentExpression +``` +<!-- TODO: The exception above isn't accurate, see https://github.com/rust-lang/reference/issues/569 --> + +r[expr.match.intro] +A *`match` expression* branches on a pattern. The exact form of matching that occurs depends on the [pattern]. + +r[expr.match.scrutinee] +A `match` expression has a *[scrutinee] expression*, which is the value to compare to the patterns. + +r[expr.match.scrutinee-constraint] +The scrutinee expression and the patterns must have the same type. + +r[expr.match.scrutinee-behavior] +A `match` behaves differently depending on whether or not the scrutinee expression is a [place expression or value expression][place expression]. + +r[expr.match.scrutinee-value] +If the scrutinee expression is a [value expression], it is first evaluated into a temporary location, and the resulting value is sequentially compared to the patterns in the arms until a match is found. The first arm with a matching pattern is chosen as the branch target of the `match`, any variables bound by the pattern are assigned to local variables in the arm's block, and control enters the block. + +r[expr.match.scrutinee-place] +When the scrutinee expression is a [place expression], the match does not allocate a temporary location; however, a by-value binding may copy or move from the memory location. When possible, it is preferable to match on place expressions, as the lifetime of these matches inherits the lifetime of the place expression rather than being restricted to the inside of the match. + +An example of a `match` expression: + +```rust +let x = 1; + +match x { + 1 => println!("one"), + 2 => println!("two"), + 3 => println!("three"), + 4 => println!("four"), + 5 => println!("five"), + _ => println!("something else"), +} +``` + +r[expr.match.pattern-vars] +Variables bound within the pattern are scoped to the match guard and the arm's expression. + +r[expr.match.pattern-var-binding] +The [binding mode] (move, copy, or reference) depends on the pattern. + +r[expr.match.or-pattern] +Multiple match patterns may be joined with the `|` operator. Each pattern will be tested in left-to-right sequence until a successful match is found. + +```rust +let x = 9; +let message = match x { + 0 | 1 => "not many", + 2 ..= 9 => "a few", + _ => "lots" +}; + +assert_eq!(message, "a few"); + +// Demonstration of pattern match order. +struct S(i32, i32); + +match S(1, 2) { + S(z @ 1, _) | S(_, z @ 2) => assert_eq!(z, 1), + _ => panic!(), +} +``` + +> [!NOTE] +> The `2..=9` is a [Range Pattern], not a [Range Expression]. Thus, only those types of ranges supported by range patterns can be used in match arms. + +r[expr.match.or-patterns-restriction] +Every binding in each `|` separated pattern must appear in all of the patterns in the arm. + +r[expr.match.binding-restriction] +Every binding of the same name must have the same type, and have the same binding mode. + +r[expr.match.type] +The type of the overall `match` expression is the [least upper bound] of the individual match arms. + +r[expr.match.empty] +If there are no match arms, then the `match` expression is [diverging] and the type is [`!`]. + +> [!EXAMPLE] +> ```rust +> enum Empty {} +> +> fn diverging_match_no_arms(e: Empty) -> ! { +> match e {} +> } +> ``` + + +r[expr.match.diverging] +If either the scrutinee expression or all of the match arms diverge, then the entire `match` expression also diverges. + +r[expr.match.guard] +## Match guards + +r[expr.match.guard.intro] +Match arms can accept _match guards_ to further refine the criteria for matching a case. + +r[expr.match.guard.condition] +Pattern guards appear after the pattern following the `if` keyword and consist of an [Expression] with a [boolean type][type.bool] or a conditional `let` match. + +r[expr.match.guard.behavior] +When the pattern matches successfully, the pattern guard is executed. If all of the guard condition operands evaluate to `true` and all of the `let` patterns successfully match their [scrutinee]s, the match arm is successfully matched against and the arm body is executed. + +r[expr.match.guard.next] +Otherwise, the next pattern, including other matches with the `|` operator in the same arm, is tested. + +```rust +# let maybe_digit = Some(0); +# fn process_digit(i: i32) { } +# fn process_other(i: i32) { } +let message = match maybe_digit { + Some(x) if x < 10 => process_digit(x), + Some(x) => process_other(x), + None => panic!(), +}; +``` + +> [!NOTE] +> Multiple matches using the `|` operator can cause the pattern guard and the side effects it has to execute multiple times. For example: +> +> ```rust +> # use std::cell::Cell; +> let i : Cell<i32> = Cell::new(0); +> match 1 { +> 1 | _ if { i.set(i.get() + 1); false } => {} +> _ => {} +> } +> assert_eq!(i.get(), 2); +> ``` + +r[expr.match.guard.bound-variables] +A pattern guard may refer to the variables bound within the pattern they follow. + +r[expr.match.guard.shared-ref] +Before evaluating the guard, a shared reference is taken to the part of the scrutinee the variable matches on. While evaluating the guard, this shared reference is then used when accessing the variable. + +r[expr.match.guard.value] +Only when the guard evaluates successfully is the value moved, or copied, from the scrutinee into the variable. This allows shared borrows to be used inside guards without moving out of the scrutinee in case guard fails to match. + +r[expr.match.guard.no-mutation] +Moreover, by holding a shared reference while evaluating the guard, mutation inside guards is also prevented. + +r[expr.match.guard.let] +Guards can use `let` patterns to conditionally match a scrutinee and to bind new variables into scope when the pattern matches successfully. + +> [!EXAMPLE] +> In this example, the guard condition `let Some(first_char) = name.chars().next()` is evaluated. If the `let` pattern successfully matches (i.e. the string has at least one character), the arm's body is executed. Otherwise, pattern matching continues to the next arm. +> +> The `let` pattern creates a new binding (`first_char`), which can be used alongside the original pattern bindings (`name`) in the arm's body. +> ```rust +> # enum Command { +> # Run(String), +> # Stop, +> # } +> let cmd = Command::Run("example".to_string()); +> +> match cmd { +> Command::Run(name) if let Some(first_char) = name.chars().next() => { +> // Both `name` and `first_char` are available here +> println!("Running: {name} (starts with '{first_char}')"); +> } +> Command::Run(name) => { +> println!("{name} is empty"); +> } +> _ => {} +> } +> ``` + +r[expr.match.guard.chains] +## Match guard chains + +r[expr.match.guard.chains.intro] +Multiple guard condition operands can be separated with `&&`. + +> [!EXAMPLE] +> ```rust +> # let foo = Some([123]); +> # let already_checked = false; +> match foo { +> Some(xs) if let [single] = xs && !already_checked => { dbg!(single); } +> _ => {} +> } +> ``` + +r[expr.match.guard.chains.order] +Similar to a `&&` [LazyBooleanExpression], each operand is evaluated from left-to-right until an operand evaluates as `false` or a `let` match fails, in which case the subsequent operands are not evaluated. + +r[expr.match.guard.chains.bindings] +The bindings of each `let` pattern are put into scope to be available for the next condition operand and the match arm body. + +r[expr.match.guard.chains.or] +If any guard condition operand is a `let` pattern, then none of the condition operands can be a `||` [lazy boolean operator expression][expr.bool-logic] due to ambiguity and precedence with the `let` scrutinee. + +> [!EXAMPLE] +> If a `||` expression is needed, then parentheses can be used. For example: +> +> ```rust +> # let foo = Some([123]); +> match foo { +> Some(xs) if let [x] = xs +> // Parentheses are required here. +> && (x < -100 || x > 20) => {} +> _ => {} +> } +> ``` + +r[expr.match.attributes] +## Attributes on match arms + +r[expr.match.attributes.outer] +Outer attributes are allowed on match arms. The only attributes that have meaning on match arms are [`cfg`] and the [lint check attributes]. + +r[expr.match.attributes.inner] +[Inner attributes] are allowed directly after the opening brace of the match expression in the same expression contexts as [attributes on block expressions]. + +[`!`]: type.never +[`cfg`]: ../conditional-compilation.md +[attributes on block expressions]: block-expr.md#attributes-on-block-expressions +[binding mode]: ../patterns.md#binding-modes +[diverging]: divergence +[Inner attributes]: ../attributes.md +[least upper bound]: coerce.least-upper-bound +[lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[pattern]: ../patterns.md +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[Range Expression]: range-expr.md +[Range Pattern]: ../patterns.md#range-patterns +[scrutinee]: ../glossary.md#scrutinee +[value expression]: ../expressions.md#place-expressions-and-value-expressions diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/method-call-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/method-call-expr.md new file mode 100644 index 00000000..02e96b65 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/method-call-expr.md @@ -0,0 +1,94 @@ +r[expr.method] +# Method-call expressions + +r[expr.method.syntax] +```grammar,expressions +MethodCallExpression -> Expression `.` PathExprSegment `(`CallParams? `)` +``` + +r[expr.method.intro] +A _method call_ consists of an expression (the *receiver*) followed by a single dot, an expression path segment, and a parenthesized expression-list. + +r[expr.method.target] +Method calls are resolved to associated [methods] on specific traits, either statically dispatching to a method if the exact `self`-type of the left-hand-side is known, or dynamically dispatching if the left-hand-side expression is an indirect [trait object](../types/trait-object.md). + +```rust +let pi: Result<f32, _> = "3.14".parse(); +let log_pi = pi.unwrap_or(1.0).log(2.72); +# assert!(1.14 < log_pi && log_pi < 1.15) +``` + +r[expr.method.autoref-deref] +When looking up a method call, the receiver may be automatically dereferenced or borrowed in order to call a method. This requires a more complex lookup process than for other functions, since there may be a number of possible methods to call. The following procedure is used: + +r[expr.method.candidate-receivers] +The first step is to build a list of candidate receiver types. Obtain these by repeatedly [dereferencing][dereference] the receiver expression's type, adding each type encountered to the list, then finally attempting an array [unsized coercion] at the end, and adding the result type if that is successful. + +r[expr.method.candidate-receivers-refs] +Then, for each candidate `T`, add `&T` and `&mut T` to the list immediately after `T`. + +For instance, if the receiver has type `Box<[i32;2]>`, then the candidate types will be `Box<[i32;2]>`, `&Box<[i32;2]>`, `&mut Box<[i32;2]>`, `[i32; 2]` (by dereferencing), `&[i32; 2]`, `&mut [i32; 2]`, `[i32]` (by unsized coercion), `&[i32]`, and finally `&mut [i32]`. + +r[expr.method.candidate-search] +Then, for each candidate type `T`, search for a [visible] method with a receiver of that type in the following places: + +1. `T`'s inherent methods (methods implemented directly on `T`). +1. Any of the methods provided by a [visible] trait implemented by `T`. If `T` is a type parameter, methods provided by trait bounds on `T` are looked up first. Then all remaining methods in scope are looked up. + +> [!NOTE] +> The lookup is done for each type in order, which can occasionally lead to surprising results. The below code will print "In trait impl!", because `&self` methods are looked up first, the trait method is found before the struct's `&mut self` method is found. +> +> ```rust +> struct Foo {} +> +> trait Bar { +> fn bar(&self); +> } +> +> impl Foo { +> fn bar(&mut self) { +> println!("In struct impl!") +> } +> } +> +> impl Bar for Foo { +> fn bar(&self) { +> println!("In trait impl!") +> } +> } +> +> fn main() { +> let mut f = Foo{}; +> f.bar(); +> } +> ``` + +r[expr.method.ambiguous-target] +If this results in multiple possible candidates, then it is an error, and the receiver must be [converted][disambiguate call] to an appropriate receiver type to make the method call. + +r[expr.method.receiver-constraints] +This process does not take into account the mutability or lifetime of the receiver, or whether a method is `unsafe`. Once a method is looked up, if it can't be called for one (or more) of those reasons, the result is a compiler error. + +r[expr.method.ambiguous-search] +If a step is reached where there is more than one possible method, such as where generic methods or traits are considered the same, then it is a compiler error. These cases require a [disambiguating function call syntax] for method and function invocation. + +r[expr.method.edition2021] +> [!EDITION-2021] +> Before the 2021 edition, during the search for visible methods, if the candidate receiver type is an [array type], methods provided by the standard library [`IntoIterator`] trait are ignored. +> +> The edition used for this purpose is determined by the token representing the method name. +> +> This special case may be removed in the future. + +> [!WARNING] +> For [trait objects], if there is an inherent method of the same name as a trait method, it will give a compiler error when trying to call the method in a method call expression. Instead, you can call the method using [disambiguating function call syntax], in which case it calls the trait method, not the inherent method. There is no way to call the inherent method. Just don't define inherent methods on trait objects with the same name as a trait method and you'll be fine. + +[visible]: ../visibility-and-privacy.md +[array type]: ../types/array.md +[trait objects]: ../types/trait-object.md +[disambiguate call]: call-expr.md#disambiguating-function-calls +[disambiguating function call syntax]: call-expr.md#disambiguating-function-calls +[dereference]: operator-expr.md#the-dereference-operator +[methods]: ../items/associated-items.md#methods +[unsized coercion]: ../type-coercions.md#unsized-coercions +[`IntoIterator`]: std::iter::IntoIterator diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/operator-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/operator-expr.md new file mode 100644 index 00000000..c692122b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/operator-expr.md @@ -0,0 +1,1266 @@ +r[expr.operator] +# Operator expressions + +r[expr.operator.syntax] +```grammar,expressions +OperatorExpression -> + BorrowExpression + | DereferenceExpression + | TryPropagationExpression + | NegationExpression + | ArithmeticOrLogicalExpression + | ComparisonExpression + | LazyBooleanExpression + | TypeCastExpression + | AssignmentExpression + | CompoundAssignmentExpression +``` + +r[expr.operator.intro] +Operators are defined for built in types by the Rust language. + +r[expr.operator.trait] +Many of the following operators can also be overloaded using traits in `std::ops` or `std::cmp`. + +r[expr.operator.int-overflow] +## Overflow + +r[expr.operator.int-overflow.intro] +Integer operators will panic when they overflow when compiled in debug mode. The `-C debug-assertions` and `-C overflow-checks` compiler flags can be used to control this more directly. The following things are considered to be overflow: + +r[expr.operator.int-overflow.binary-arith] +* When `+`, `*` or binary `-` create a value greater than the maximum value, or less than the minimum value that can be stored. + +r[expr.operator.int-overflow.unary-neg] +* Applying unary `-` to the most negative value of any signed integer type, unless the operand is a [literal expression] (or a literal expression standing alone inside one or more [grouped expressions][grouped expression]). + +r[expr.operator.int-overflow.div] +* Using `/` or `%`, where the left-hand argument is the smallest integer of a signed integer type and the right-hand argument is `-1`. These checks occur even when `-C overflow-checks` is disabled, for legacy reasons. + +r[expr.operator.int-overflow.shift] +* Using `<<` or `>>` where the right-hand argument is greater than or equal to the number of bits in the type of the left-hand argument, or is negative. + +> [!NOTE] +> The exception for literal expressions behind unary `-` means that forms such as `-128_i8` or `let j: i8 = -(128)` never cause a panic and have the expected value of -128. +> +> In these cases, the literal expression already has the most negative value for its type (for example, `128_i8` has the value -128) because integer literals are truncated to their type per the description in [Integer literal expressions][literal expression]. +> +> Negation of these most negative values leaves the value unchanged due to two's complement overflow conventions. +> +> In `rustc`, these most negative expressions are also ignored by the `overflowing_literals` lint check. + +r[expr.operator.borrow] +## Borrow operators + +r[expr.operator.borrow.syntax] +```grammar,expressions +BorrowExpression -> + (`&`|`&&`) Expression + | (`&`|`&&`) `mut` Expression + | (`&`|`&&`) `raw` `const` Expression + | (`&`|`&&`) `raw` `mut` Expression +``` + +r[expr.operator.borrow.intro] +The `&` (shared borrow) and `&mut` (mutable borrow) operators are unary prefix operators. + +r[expr.operator.borrow.result] +When applied to a [place expression], this expressions produces a reference (pointer) to the location that the value refers to. + +r[expr.operator.borrow.lifetime] +The memory location is also placed into a borrowed state for the duration of the reference. For a shared borrow (`&`), this implies that the place may not be mutated, but it may be read or shared again. For a mutable borrow (`&mut`), the place may not be accessed in any way until the borrow expires. + +r[expr.operator.borrow.mut] +`&mut` evaluates its operand in a mutable place expression context. + +r[expr.operator.borrow.temporary] +If the `&` or `&mut` operators are applied to a [value expression], then a [temporary value] is created. + +These operators cannot be overloaded. + +```rust +{ + // a temporary with value 7 is created that lasts for this scope. + let shared_reference = &7; +} +let mut array = [-2, 3, 9]; +{ + // Mutably borrows `array` for this scope. + // `array` may only be used through `mutable_reference`. + let mutable_reference = &mut array; +} +``` + +r[expr.borrow.and-and-syntax] +Even though `&&` is a single token ([the lazy 'and' operator](#lazy-boolean-operators)), when used in the context of borrow expressions it works as two borrows: + +```rust +// same meanings: +let a = && 10; +let a = & & 10; + +// same meanings: +let a = &&&& mut 10; +let a = && && mut 10; +let a = & & & & mut 10; +``` + +r[expr.borrow.raw] +### Raw borrow operators + +r[expr.borrow.raw.intro] +`&raw const` and `&raw mut` are the *raw borrow operators*. + +r[expr.borrow.raw.place] +The operand expression of these operators is evaluated in place expression context. + +r[expr.borrow.raw.result] +`&raw const expr` then creates a const raw pointer of type `*const T` to the given place, and `&raw mut expr` creates a mutable raw pointer of type `*mut T`. + +r[expr.borrow.raw.invalid-ref] +The raw borrow operators must be used instead of a borrow operator whenever the place expression could evaluate to a place that is not properly aligned or does not store a valid value as determined by its type, or whenever creating a reference would introduce incorrect aliasing assumptions. In those situations, using a borrow operator would cause [undefined behavior] by creating an invalid reference, but a raw pointer may still be constructed. + +The following is an example of creating a raw pointer to an unaligned place through a `packed` struct: + +```rust +#[repr(packed)] +struct Packed { + f1: u8, + f2: u16, +} + +let packed = Packed { f1: 1, f2: 2 }; +// `&packed.f2` would create an unaligned reference, and thus be undefined behavior! +let raw_f2 = &raw const packed.f2; +assert_eq!(unsafe { raw_f2.read_unaligned() }, 2); +``` + +The following is an example of creating a raw pointer to a place that does not contain a valid value: + +```rust +use std::mem::MaybeUninit; + +struct Demo { + field: bool, +} + +let mut uninit = MaybeUninit::<Demo>::uninit(); +// `&uninit.as_mut().field` would create a reference to an uninitialized `bool`, +// and thus be undefined behavior! +let f1_ptr = unsafe { &raw mut (*uninit.as_mut_ptr()).field }; +unsafe { f1_ptr.write(true); } +let init = unsafe { uninit.assume_init() }; +``` + +r[expr.deref] +## The dereference operator + +r[expr.deref.syntax] +```grammar,expressions +DereferenceExpression -> `*` Expression +``` + +r[expr.deref.intro] +The `*` (dereference) operator is also a unary prefix operator. + +r[expr.deref.result] +When applied to a [pointer](../types/pointer.md) or [`Box`], it denotes the pointed-to location. + +r[expr.deref.mut] +If the expression is of type `&mut T`, `*mut T`, or `Box<T>`, and is either a local variable, a (nested) field of a local variable or is a mutable [place expression], then the resulting memory location can be assigned to. + +r[expr.deref.box] +When applied to a [`Box`], the resultant place may be [moved from]. + +r[expr.deref.safety] +Dereferencing a raw pointer requires `unsafe`. + +r[expr.deref.traits] +On non-pointer types `*x` is equivalent to `*std::ops::Deref::deref(&x)` in an [immutable place expression context](../expressions.md#mutability) and `*std::ops::DerefMut::deref_mut(&mut x)` in a mutable place expression context, except that when `*x` undergoes [temporary lifetime extension], the dereferenced expression `x` also has its [temporary scope] extended. + +```rust +# struct NoCopy; +let a = &7; +assert_eq!(*a, 7); +let b = &mut 9; +*b = 11; +assert_eq!(*b, 11); +let c = Box::new(NoCopy); +let d: NoCopy = *c; +``` + +```rust +// The temporary holding the result of `String::new()` is extended +// to live to the end of the block, so `x` may be used in subsequent +// statements. +let x = &*String::new(); +# x; +``` + +```rust,compile_fail,E0716 +// The temporary holding the result of `String::new()` is dropped at +// the end of the statement, so it's an error to use `y` after. +let y = &*std::ops::Deref::deref(&String::new()); // ERROR +# y; +``` + +r[expr.try] +## The try propagation expression + +r[expr.try.syntax] +```grammar,expressions +TryPropagationExpression -> Expression `?` +``` + +r[expr.try.intro] +The try propagation expression uses the value of the inner expression and the [`Try`] trait to decide whether to produce a value, and if so, what value to produce, or whether to return a value to the caller, and if so, what value to return. + +> [!EXAMPLE] +> ```rust +> # use std::num::ParseIntError; +> fn try_to_parse() -> Result<i32, ParseIntError> { +> let x: i32 = "123".parse()?; // `x` is `123`. +> let y: i32 = "24a".parse()?; // Returns an `Err()` immediately. +> Ok(x + y) // Doesn't run. +> } +> +> let res = try_to_parse(); +> println!("{res:?}"); +> # assert!(res.is_err()) +> ``` +> +> ```rust +> fn try_option_some() -> Option<u8> { +> let val = Some(1)?; +> Some(val) +> } +> assert_eq!(try_option_some(), Some(1)); +> +> fn try_option_none() -> Option<u8> { +> let val = None?; +> Some(val) +> } +> assert_eq!(try_option_none(), None); +> ``` +> +> ```rust +> use std::ops::ControlFlow; +> +> pub struct TreeNode<T> { +> value: T, +> left: Option<Box<TreeNode<T>>>, +> right: Option<Box<TreeNode<T>>>, +> } +> +> impl<T> TreeNode<T> { +> pub fn traverse_inorder<B>(&self, f: &mut impl FnMut(&T) -> ControlFlow<B>) -> ControlFlow<B> { +> if let Some(left) = &self.left { +> left.traverse_inorder(f)?; +> } +> f(&self.value)?; +> if let Some(right) = &self.right { +> right.traverse_inorder(f)?; +> } +> ControlFlow::Continue(()) +> } +> } +> # +> # fn main() { +> # let n = TreeNode { +> # value: 1, +> # left: Some(Box::new(TreeNode{value: 2, left: None, right: None})), +> # right: None, +> # }; +> # let v = n.traverse_inorder(&mut |t| { +> # if *t == 2 { +> # ControlFlow::Break("found") +> # } else { +> # ControlFlow::Continue(()) +> # } +> # }); +> # assert_eq!(v, ControlFlow::Break("found")); +> # } +> ``` + +> [!NOTE] +> The [`Try`] trait is currently unstable, and thus cannot be implemented for user types. +> +> The try propagation expression is currently roughly equivalent to: +> +> ```rust +> # #![ feature(try_trait_v2) ] +> # fn example() -> Result<(), ()> { +> # let expr = Ok(()); +> match core::ops::Try::branch(expr) { +> core::ops::ControlFlow::Continue(val) => val, +> core::ops::ControlFlow::Break(residual) => +> return core::ops::FromResidual::from_residual(residual), +> } +> # Ok(()) +> # } +> ``` + +> [!NOTE] +> The try propagation operator is sometimes called *the question mark operator*, *the `?` operator*, or *the try operator*. + +r[expr.try.restricted-types] +The try propagation operator can be applied to expressions with the type of: + +- [`Result<T, E>`] + - `Result::Ok(val)` evaluates to `val`. + - `Result::Err(e)` returns `Result::Err(From::from(e))`. +- [`Option<T>`] + - `Option::Some(val)` evaluates to `val`. + - `Option::None` returns `Option::None`. +- [`ControlFlow<B, C>`][core::ops::ControlFlow] + - `ControlFlow::Continue(c)` evaluates to `c`. + - `ControlFlow::Break(b)` returns `ControlFlow::Break(b)`. +- [`Poll<Result<T, E>>`][core::task::Poll] + - `Poll::Ready(Ok(val))` evaluates to `Poll::Ready(val)`. + - `Poll::Ready(Err(e))` returns `Poll::Ready(Err(From::from(e)))`. + - `Poll::Pending` evaluates to `Poll::Pending`. +- [`Poll<Option<Result<T, E>>>`][`core::task::Poll`] + - `Poll::Ready(Some(Ok(val)))` evaluates to `Poll::Ready(Some(val))`. + - `Poll::Ready(Some(Err(e)))` returns `Poll::Ready(Some(Err(From::from(e))))`. + - `Poll::Ready(None)` evaluates to `Poll::Ready(None)`. + - `Poll::Pending` evaluates to `Poll::Pending`. + +r[expr.negate] +## Negation operators + +r[expr.negate.syntax] +```grammar,expressions +NegationExpression -> + `-` Expression + | `!` Expression +``` + +r[expr.negate.intro] +These are the last two unary operators. + +r[expr.negate.results] +This table summarizes the behavior of them on primitive types and which traits are used to overload these operators for other types. Remember that signed integers are always represented using two's complement. The operands of all of these operators are evaluated in [value expression context][value expression] so are moved or copied. + +| Symbol | Integer | `bool` | Floating Point | Overloading Trait | +|--------|-------------|-------------- |----------------|--------------------| +| `-` | Negation* | | Negation | `std::ops::Neg` | +| `!` | Bitwise NOT | [Logical NOT] | | `std::ops::Not` | + +\* Only for signed integer types. + +Here are some example of these operators + +```rust +let x = 6; +assert_eq!(-x, -6); +assert_eq!(!x, -7); +assert_eq!(true, !false); +``` + +r[expr.arith-logic] +## Arithmetic and logical binary operators + +r[expr.arith-logic.syntax] +```grammar,expressions +ArithmeticOrLogicalExpression -> + Expression `+` Expression + | Expression `-` Expression + | Expression `*` Expression + | Expression `/` Expression + | Expression `%` Expression + | Expression `&` Expression + | Expression `|` Expression + | Expression `^` Expression + | Expression `<<` Expression + | Expression `>>` Expression +``` + +r[expr.arith-logic.intro] +Binary operators expressions are all written with infix notation. + +r[expr.arith-logic.behavior] +This table summarizes the behavior of arithmetic and logical binary operators on primitive types and which traits are used to overload these operators for other types. Remember that signed integers are always represented using two's complement. The operands of all of these operators are evaluated in [value expression context][value expression] so are moved or copied. + +| Symbol | Integer | `bool` | Floating Point | Overloading Trait | Overloading Compound Assignment Trait | +|--------|-------------------------|---------------|----------------|--------------------| ------------------------------------- | +| `+` | Addition | | Addition | `std::ops::Add` | `std::ops::AddAssign` | +| `-` | Subtraction | | Subtraction | `std::ops::Sub` | `std::ops::SubAssign` | +| `*` | Multiplication | | Multiplication | `std::ops::Mul` | `std::ops::MulAssign` | +| `/` | Division*† | | Division | `std::ops::Div` | `std::ops::DivAssign` | +| `%` | Remainder**† | | Remainder | `std::ops::Rem` | `std::ops::RemAssign` | +| `&` | Bitwise AND | [Logical AND] | | `std::ops::BitAnd` | `std::ops::BitAndAssign` | +| `\|` | Bitwise OR | [Logical OR] | | `std::ops::BitOr` | `std::ops::BitOrAssign` | +| `^` | Bitwise XOR | [Logical XOR] | | `std::ops::BitXor` | `std::ops::BitXorAssign` | +| `<<` | Left Shift | | | `std::ops::Shl` | `std::ops::ShlAssign` | +| `>>` | Right Shift*** | | | `std::ops::Shr` | `std::ops::ShrAssign` | + +\* Integer division rounds towards zero. + +\*\* Rust uses a remainder defined with [truncating division](https://en.wikipedia.org/wiki/Modulo_operation#Variants_of_the_definition). Given `remainder = dividend % divisor`, the remainder will have the same sign as the dividend. + +\*\*\* Arithmetic right shift on signed integer types, logical right shift on unsigned integer types. + +† For integer types, division by zero panics. + +Here are examples of these operators being used. + +```rust +assert_eq!(3 + 6, 9); +assert_eq!(5.5 - 1.25, 4.25); +assert_eq!(-5 * 14, -70); +assert_eq!(14 / 3, 4); +assert_eq!(100 % 7, 2); +assert_eq!(0b1010 & 0b1100, 0b1000); +assert_eq!(0b1010 | 0b1100, 0b1110); +assert_eq!(0b1010 ^ 0b1100, 0b110); +assert_eq!(13 << 3, 104); +assert_eq!(-10 >> 2, -3); +``` + +r[expr.cmp] +## Comparison operators + +r[expr.cmp.syntax] +```grammar,expressions +ComparisonExpression -> + Expression `==` Expression + | Expression `!=` Expression + | Expression `>` Expression + | Expression `<` Expression + | Expression `>=` Expression + | Expression `<=` Expression +``` + +r[expr.cmp.intro] +Comparison operators are also defined both for primitive types and many types in the standard library. + +r[expr.cmp.paren-chaining] +Parentheses are required when chaining comparison operators. For example, the expression `a == b == c` is invalid and may be written as `(a == b) == c`. + +r[expr.cmp.trait] +Unlike arithmetic and logical operators, the traits for overloading these operators are used more generally to show how a type may be compared and will likely be assumed to define actual comparisons by functions that use these traits as bounds. Many functions and macros in the standard library can then use that assumption (although not to ensure safety). + +r[expr.cmp.place] +Unlike the arithmetic and logical operators above, these operators implicitly take shared borrows of their operands, evaluating them in [place expression context][place expression]: + +```rust +# let a = 1; +# let b = 1; +a == b; +// is equivalent to +::std::cmp::PartialEq::eq(&a, &b); +``` + +This means that the operands don't have to be moved out of. + +r[expr.cmp.behavior] + +| Symbol | Meaning | Overloading method | +|--------|--------------------------|----------------------------| +| `==` | Equal | `std::cmp::PartialEq::eq` | +| `!=` | Not equal | `std::cmp::PartialEq::ne` | +| `>` | Greater than | `std::cmp::PartialOrd::gt` | +| `<` | Less than | `std::cmp::PartialOrd::lt` | +| `>=` | Greater than or equal to | `std::cmp::PartialOrd::ge` | +| `<=` | Less than or equal to | `std::cmp::PartialOrd::le` | + +Here are examples of the comparison operators being used. + +```rust +assert!(123 == 123); +assert!(23 != -12); +assert!(12.5 > 12.2); +assert!([1, 2, 3] < [1, 3, 4]); +assert!('A' <= 'B'); +assert!("World" >= "Hello"); +``` + +r[expr.bool-logic] +## Lazy boolean operators + +r[expr.bool-logic.syntax] +```grammar,expressions +LazyBooleanExpression -> + Expression `||` Expression + | Expression `&&` Expression +``` + +r[expr.bool-logic.intro] +The operators `||` and `&&` may be applied to operands of boolean type. The `||` operator denotes logical 'or', and the `&&` operator denotes logical 'and'. + +r[expr.bool-logic.conditional-evaluation] +They differ from `|` and `&` in that the right-hand operand is only evaluated when the left-hand operand does not already determine the result of the expression. That is, `||` only evaluates its right-hand operand when the left-hand operand evaluates to `false`, and `&&` only when it evaluates to `true`. + +```rust +let x = false || true; // true +let y = false && panic!(); // false, doesn't evaluate `panic!()` +``` + +r[expr.as] +## Type cast expressions + +r[expr.as.syntax] +```grammar,expressions +TypeCastExpression -> Expression `as` TypeNoBounds +``` + +r[expr.as.intro] +A type cast expression is denoted with the binary operator `as`. + +r[expr.as.result] +Executing an `as` expression casts the value on the left-hand side to the type on the right-hand side. + +An example of an `as` expression: + +```rust +# fn sum(values: &[f64]) -> f64 { 0.0 } +# fn len(values: &[f64]) -> i32 { 0 } +fn average(values: &[f64]) -> f64 { + let sum: f64 = sum(values); + let size: f64 = len(values) as f64; + sum / size +} +``` + +r[expr.as.coercions] +`as` can be used to explicitly perform [coercions](../type-coercions.md), as well as the following additional casts. Any cast that does not fit either a coercion rule or an entry in the table is a compiler error. Here `*T` means either `*const T` or `*mut T`. `m` stands for optional `mut` in reference types and `mut` or `const` in pointer types. + +| Type of `e` | `U` | Cast performed by `e as U` | +|-----------------------|-----------------------|-------------------------------------------------------| +| Integer or Float type | Integer or Float type | [Numeric cast][expr.as.numeric] | +| Enumeration | Integer type | [Enum cast][expr.as.enum] | +| `bool` or `char` | Integer type | [Primitive to integer cast][expr.as.bool-char-as-int] | +| `u8` | `char` | [`u8` to `char` cast][expr.as.u8-as-char] | +| `*T` | `*V` (when [compatible][expr.as.pointer]) | [Pointer to pointer cast][expr.as.pointer] | +| `*T` where `T: Sized` | Integer type | [Pointer to address cast][expr.as.pointer-as-int] | +| Integer type | `*V` where `V: Sized` | [Address to pointer cast][expr.as.int-as-pointer] | +| `&m₁ [T; n]` | `*m₂ T` [^lessmut] | Array to pointer cast | +| `*m₁ [T; n]` | `*m₂ T` [^lessmut] | Array to pointer cast | +| [Function item] | [Function pointer] | Function item to function pointer cast | +| [Function item] | `*V` where `V: Sized` | Function item to pointer cast | +| [Function item] | Integer | Function item to address cast | +| [Function pointer] | `*V` where `V: Sized` | Function pointer to pointer cast | +| [Function pointer] | Integer | Function pointer to address cast | +| Closure [^no-capture] | Function pointer | Closure to function pointer cast | + +[^lessmut]: Only when `m₁` is `mut` or `m₂` is `const`. Casting `mut` reference/pointer to `const` pointer is allowed. + +[^no-capture]: Only closures that do not capture (close over) any local variables can be cast to function pointers. + +### Semantics + +r[expr.as.numeric] +#### Numeric cast + +r[expr.as.numeric.int-same-size] +* Casting between two integers of the same size (e.g. i32 -> u32) is a no-op (Rust uses 2's complement for negative values of fixed integers) + + ```rust + assert_eq!(42i8 as u8, 42u8); + assert_eq!(-1i8 as u8, 255u8); + assert_eq!(255u8 as i8, -1i8); + assert_eq!(-1i16 as u16, 65535u16); + ``` + +r[expr.as.numeric.int-truncation] +* Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will truncate + + ```rust + assert_eq!(42u16 as u8, 42u8); + assert_eq!(1234u16 as u8, 210u8); + assert_eq!(0xabcdu16 as u8, 0xcdu8); + + assert_eq!(-42i16 as i8, -42i8); + assert_eq!(1234u16 as i8, -46i8); + assert_eq!(0xabcdi32 as i8, -51i8); + ``` + +r[expr.as.numeric.int-extension] +* Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will + * zero-extend if the source is unsigned + * sign-extend if the source is signed + + ```rust + assert_eq!(42i8 as i16, 42i16); + assert_eq!(-17i8 as i16, -17i16); + assert_eq!(0b1000_1010u8 as u16, 0b0000_0000_1000_1010u16, "Zero-extend"); + assert_eq!(0b0000_1010i8 as i16, 0b0000_0000_0000_1010i16, "Sign-extend 0"); + assert_eq!(0b1000_1010u8 as i8 as i16, 0b1111_1111_1000_1010u16 as i16, "Sign-extend 1"); + ``` + +r[expr.as.numeric.float-as-int] +* Casting from a float to an integer will round the float towards zero + * `NaN` will return `0` + * Values larger than the maximum integer value, including `INFINITY`, will saturate to the maximum value of the integer type. + * Values smaller than the minimum integer value, including `NEG_INFINITY`, will saturate to the minimum value of the integer type. + + ```rust + assert_eq!(42.9f32 as i32, 42); + assert_eq!(-42.9f32 as i32, -42); + assert_eq!(42_000_000f32 as i32, 42_000_000); + assert_eq!(std::f32::NAN as i32, 0); + assert_eq!(1_000_000_000_000_000f32 as i32, 0x7fffffffi32); + assert_eq!(std::f32::NEG_INFINITY as i32, -0x80000000i32); + ``` + +r[expr.as.numeric.int-as-float] +* Casting from an integer to float will produce the closest possible float \* + * if necessary, rounding is according to `roundTiesToEven` mode \*\*\* + * on overflow, infinity (of the same sign as the input) is produced + * note: with the current set of numeric types, overflow can only happen on `u128 as f32` for values greater or equal to `f32::MAX + (0.5 ULP)` + + ```rust + assert_eq!(1337i32 as f32, 1337f32); + assert_eq!(123_456_789i32 as f32, 123_456_790f32, "Rounded"); + assert_eq!(0xffffffff_ffffffff_ffffffff_ffffffff_u128 as f32, std::f32::INFINITY); + ``` + +r[expr.as.numeric.float-widening] +* Casting from an f32 to an f64 is perfect and lossless + + ```rust + assert_eq!(1_234.5f32 as f64, 1_234.5f64); + assert_eq!(std::f32::INFINITY as f64, std::f64::INFINITY); + assert!((std::f32::NAN as f64).is_nan()); + ``` + +r[expr.as.numeric.float-narrowing] +* Casting from an f64 to an f32 will produce the closest possible f32 \*\* + * if necessary, rounding is according to `roundTiesToEven` mode \*\*\* + * on overflow, infinity (of the same sign as the input) is produced + + ```rust + assert_eq!(1_234.5f64 as f32, 1_234.5f32); + assert_eq!(1_234_567_891.123f64 as f32, 1_234_567_890f32, "Rounded"); + assert_eq!(std::f64::INFINITY as f32, std::f32::INFINITY); + assert!((std::f64::NAN as f32).is_nan()); + ``` + +\* if integer-to-float casts with this rounding mode and overflow behavior are not supported natively by the hardware, these casts will likely be slower than expected. + +\*\* if f64-to-f32 casts with this rounding mode and overflow behavior are not supported natively by the hardware, these casts will likely be slower than expected. + +\*\*\* as defined in IEEE 754-2008 §4.3.1: pick the nearest floating point number, preferring the one with an even least significant digit if exactly halfway between two floating point numbers. + +r[expr.as.enum] +#### Enum cast + +r[expr.as.enum.discriminant] +Casts an enum to its discriminant, then uses a numeric cast if needed. Casting is limited to the following kinds of enumerations: + +* [Unit-only enums] +* [Field-less enums] without [explicit discriminants], or where only unit-variants have explicit discriminants + +```rust +enum Enum { A, B, C } +assert_eq!(Enum::A as i32, 0); +assert_eq!(Enum::B as i32, 1); +assert_eq!(Enum::C as i32, 2); +``` + +r[expr.as.enum.no-drop] +Casting is not allowed if the enum implements [`Drop`]. + +r[expr.as.bool-char-as-int] +#### Primitive to integer cast + +* `false` casts to `0`, `true` casts to `1` +* `char` casts to the value of the code point, then uses a numeric cast if needed. + +```rust +assert_eq!(false as i32, 0); +assert_eq!(true as i32, 1); +assert_eq!('A' as i32, 65); +assert_eq!('Ö' as i32, 214); +``` + +r[expr.as.u8-as-char] +#### `u8` to `char` cast + +Casts to the `char` with the corresponding code point. + +```rust +assert_eq!(65u8 as char, 'A'); +assert_eq!(214u8 as char, 'Ö'); +``` + +r[expr.as.pointer-as-int] +#### Pointer to address cast + +Casting from a raw pointer to an integer produces the machine address of the referenced memory. If the integer type is smaller than the pointer type, the address may be truncated; using `usize` avoids this. + +r[expr.as.int-as-pointer] +#### Address to pointer cast + +Casting from an integer to a raw pointer interprets the integer as a memory address and produces a pointer referencing that memory. + +> [!WARNING] +> This interacts with the Rust memory model, which is still under development. +> A pointer obtained from this cast may suffer additional restrictions even if it is bitwise equal to a valid pointer. +> Dereferencing such a pointer may be [undefined behavior] if aliasing rules are not followed. + +A trivial example of sound address arithmetic: + +```rust +let mut values: [i32; 2] = [1, 2]; +let p1: *mut i32 = values.as_mut_ptr(); +let first_address = p1 as usize; +let second_address = first_address + 4; // 4 == size_of::<i32>() +let p2 = second_address as *mut i32; +unsafe { + *p2 += 1; +} +assert_eq!(values[1], 3); +``` + +r[expr.as.pointer] +#### Pointer-to-pointer cast + +r[expr.as.pointer.behavior] +`*const T` / `*mut T` can be cast to `*const U` / `*mut U` with the following behavior: + +r[expr.as.pointer.sized] +- If `T` and `U` are both sized, the pointer is returned unchanged. + + > [!EXAMPLE] + > ```rust + > let x: i32 = 42; + > let p1: *const i32 = &x; + > let p2: *const u8 = p1 as *const u8; + > // The pointer address remains the same. + > assert_eq!(p1 as usize, p2 as usize); + > ``` + +r[expr.as.pointer.discard-metadata] +- If `T` is unsized and `U` is sized, the cast discards all [metadata] that completes the wide pointer `T` and produces a thin pointer `U` consisting of the data part of the unsized pointer. + + > [!EXAMPLE] + > ```rust + > let slice: &[i32] = &[1, 2, 3]; + > let ptr: *const [i32] = slice as *const [i32]; + > // Cast from wide pointer (*const [i32]) to thin pointer (*const i32) + > // discarding the length metadata. + > let data_ptr: *const i32 = ptr as *const i32; + > assert_eq!(unsafe { *data_ptr }, 1); + > ``` + +r[expr.as.pointer.unsized.unchanged] +- If `T` and `U` are both unsized, the pointer is also returned unchanged. In particular, the metadata is preserved exactly. The cast can only be performed if the metadata is compatible according to the below rules: + +r[expr.as.pointer.unsized.slice] +- When `T` and `U` are unsized with slice metadata, they are always compatible. The metadata of a slice is the number of elements, so casting `*[u16] -> *[u8]` is legal but will result in reducing the number of bytes by half. + + > [!EXAMPLE] + > ```rust + > let slice: &[u16] = &[1, 2, 3]; + > let ptr: *const [u16] = slice as *const [u16]; + > let byte_ptr: *const [u8] = ptr as *const [u8]; + > assert_eq!(byte_ptr.len(), 3); + > ``` + +r[expr.as.pointer.unsized.trait] +- When `T` and `U` are unsized with trait object metadata, the metadata is compatible only when all of the following holds: + 1. The principal trait must be the same. + + > [!EXAMPLE] + > ```rust,compile_fail,E0606 + > trait Foo {} + > trait Bar {} + > impl Foo for i32 {} + > impl Bar for i32 {} + > + > let x: i32 = 42; + > let ptr_foo: *const dyn Foo = &x as *const dyn Foo; + > // You can't cast to a different principal trait. + > let ptr_bar: *const dyn Bar = ptr_foo as *const dyn Bar; // ERROR + > ``` + + + 2. Auto traits may be removed. + + > [!EXAMPLE] + > ```rust + > trait Foo {} + > struct S; + > impl Foo for S {} + > unsafe impl Send for S {} + > + > let s = S; + > let ptr_send: *const (dyn Foo + Send) = &s; + > // Removing an auto trait. + > let ptr_no_send: *const dyn Foo = ptr_send as *const dyn Foo; + > ``` + + + 3. Auto traits may be added only if they are a super trait of the principal trait. + + > [!EXAMPLE] + > ```rust + > trait Foo: Send {} + > struct S; + > impl Foo for S {} + > unsafe impl Send for S {} + > + > let s = S; + > let ptr_no_send: *const dyn Foo = &s; + > // Adding an auto trait. + > let ptr_send: *const (dyn Foo + Send) = ptr_no_send as *const (dyn Foo + Send); + > ``` + > + > ```rust,compile_fail,E0804 + > trait Foo {} + > # struct S; + > # impl Foo for S {} + > # unsafe impl Send for S {} + > # + > # let s = S; + > # let ptr_no_send: *const dyn Foo = &s; + > // Same as above, except trait Foo does not have Send as a super trait. + > let ptr_send: *const (dyn Foo + Send) = ptr_no_send as *const (dyn Foo + Send); // ERROR + > ``` + + + 4. Trailing lifetimes may only be shortened. + + > [!EXAMPLE] + > ```rust + > trait Foo {} + > + > fn shorten_lifetime<'long: 'short, 'short>( + > ptr: *const (dyn Foo + 'long), + > ) -> *const (dyn Foo + 'short) { + > // Shortening the lifetime is allowed. + > ptr as *const (dyn Foo + 'short) + > } + > ``` + > + > ```rust,compile_fail + > trait Foo {} + > + > fn lengthen_lifetime<'long: 'short, 'short>( + > ptr: *const (dyn Foo + 'short), + > ) -> *const (dyn Foo + 'long) { + > // It is not allowed to cast to a longer lifetime. + > ptr as *const (dyn Foo + 'long) // ERROR + > } + > ``` + + 5. Generics (including lifetimes) and associated types must match exactly. + + > [!EXAMPLE] + > ```rust,compile_fail,E0606 + > trait Generic<T> {} + > impl Generic<i32> for () {} + > impl Generic<u32> for () {} + > + > let x = (); + > let ptr_i32: *const dyn Generic<i32> = &x; + > // You can't cast to a different generic parameter. + > let ptr_u32: *const dyn Generic<u32> = ptr_i32 as *const dyn Generic<u32>; // ERROR + > ``` + > + > ```rust + > trait HasType { + > type Output; + > } + > + > trait Generic<'x, T> {} + > + > fn cast_via_associated<'a, 'b, A, B>( + > ptr: *const dyn Generic<'a, A::Output>, + > ) -> *const dyn Generic<'b, B::Output> + > where + > 'a: 'b, + > 'b: 'a, + > A: HasType, + > B: HasType<Output = A::Output>, // Forces equality + > { + > ptr as *const dyn Generic<'b, B::Output> + > } + > ``` + + + +r[expr.as.pointer.unsized.compound] +- When `T` or `U` is a struct or tuple type whose last field is unsized, it has the same metadata and compatibility rules as its last field. + + > [!EXAMPLE] + > ```rust + > struct Wrapper(u32, [u8]); + > + > let slice: &[u8] = &[1, 2, 3]; + > let ptr: *const [u8] = slice; + > + > // The metadata (length 3) is preserved when casting to a struct + > // where the last field is the unsized type `[u8]`. + > let wrapper_ptr: *const Wrapper = ptr as *const Wrapper; + > + > // And preserved when casting back. + > let ptr_back: *const [u8] = wrapper_ptr as *const [u8]; + > assert_eq!(ptr_back.len(), 3); + > ``` + +r[expr.assign] +## Assignment expressions + +r[expr.assign.syntax] +```grammar,expressions +AssignmentExpression -> Expression `=` Expression +``` + +r[expr.assign.intro] +An *assignment expression* moves a value into a specified place. + +r[expr.assign.assignee] +An assignment expression consists of a [mutable] [assignee expression], the *assignee operand*, followed by an equals sign (`=`) and a [value expression], the *assigned value operand*. + +r[expr.assign.behavior-basic] +In its most basic form, an assignee expression is a [place expression], and we discuss this case first. + +r[expr.assign.behavior-destructuring] +The more general case of destructuring assignment is discussed below, but this case always decomposes into sequential assignments to place expressions, which may be considered the more fundamental case. + +r[expr.assign.basic] +### Basic assignments + +r[expr.assign.evaluation-order] +Evaluating assignment expressions begins by evaluating its operands. The assigned value operand is evaluated first, followed by the assignee expression. + +r[expr.assign.destructuring-order] +For destructuring assignment, subexpressions of the assignee expression are evaluated left-to-right. + +> [!NOTE] +> This is different than other expressions in that the right operand is evaluated before the left one. + +r[expr.assign.drop-target] +It then has the effect of first [dropping] the value at the assigned place, unless the place is an uninitialized local variable or an uninitialized field of a local variable. + +r[expr.assign.behavior] +Next it either [copies or moves] the assigned value to the assigned place. + +r[expr.assign.result] +An assignment expression always produces [the unit value][unit]. + +Example: + +```rust +let mut x = 0; +let y = 0; +x = y; +``` + +r[expr.assign.destructure] +### Destructuring assignments + +r[expr.assign.destructure.intro] +Destructuring assignment is a counterpart to destructuring pattern matches for variable declaration, permitting assignment to complex values, such as tuples or structs. For instance, we may swap two mutable variables: + +```rust +let (mut a, mut b) = (0, 1); +// Swap `a` and `b` using destructuring assignment. +(b, a) = (a, b); +``` + +r[expr.assign.destructure.assignee] +In contrast to destructuring declarations using `let`, patterns may not appear on the left-hand side of an assignment due to syntactic ambiguities. Instead, a group of expressions that correspond to patterns are designated to be [assignee expressions][assignee expression], and permitted on the left-hand side of an assignment. Assignee expressions are then desugared to pattern matches followed by sequential assignment. + +r[expr.assign.destructure.irrefutable] +The desugared patterns must be irrefutable: in particular, this means that only slice patterns whose length is known at compile-time, and the trivial slice `[..]`, are permitted for destructuring assignment. + +The desugaring method is straightforward, and is illustrated best by example. + +```rust +# struct Struct { x: u32, y: u32 } +# let (mut a, mut b) = (0, 0); +(a, b) = (3, 4); + +[a, b] = [3, 4]; + +Struct { x: a, y: b } = Struct { x: 3, y: 4}; + +// desugars to: + +{ + let (_a, _b) = (3, 4); + a = _a; + b = _b; +} + +{ + let [_a, _b] = [3, 4]; + a = _a; + b = _b; +} + +{ + let Struct { x: _a, y: _b } = Struct { x: 3, y: 4}; + a = _a; + b = _b; +} +``` + +r[expr.assign.destructure.repeat-ident] +Identifiers are not forbidden from being used multiple times in a single assignee expression. + +r[expr.assign.destructure.discard-value] +[Underscore expressions] and empty [range expressions] may be used to ignore certain values, without binding them. + +r[expr.assign.destructure.default-binding] +Note that default binding modes do not apply for the desugared expression. + +r[expr.assign.destructure.tmp-scopes] +> [!NOTE] +> The desugaring restricts the [temporary scope] of the assigned value operand (the RHS) of a destructuring assignment. +> +> In a basic assignment, the [temporary] is dropped at the end of the enclosing temporary scope. Below, that's the statement. Therefore, the assignment and use is allowed. +> +> ```rust +> # fn temp() {} +> fn f<T>(x: T) -> T { x } +> let x; +> (x = f(&temp()), x); // OK +> ``` +> +> Conversely, in a destructuring assignment, the temporary is dropped at the end of the `let` statement in the desugaring. As that happens before we try to assign to `x`, below, it fails. +> +> ```rust,compile_fail,E0716 +> # fn temp() {} +> # fn f<T>(x: T) -> T { x } +> # let x; +> [x] = [f(&temp())]; // ERROR +> ``` +> +> This desugars to: +> +> ```rust,compile_fail,E0716 +> # fn temp() {} +> # fn f<T>(x: T) -> T { x } +> # let x; +> { +> let [_x] = [f(&temp())]; +> // ^ +> // The temporary is dropped here. +> x = _x; // ERROR +> } +> ``` + +r[expr.assign.destructure.tmp-ext] +> [!NOTE] +> Due to the desugaring, the assigned value operand (the RHS) of a destructuring assignment is an [extending expression] within a newly-introduced block. +> +> Below, because the [temporary scope] is extended to the end of this introduced block, the assignment is allowed. +> +> ```rust +> # fn temp() {} +> # let x; +> [x] = [&temp()]; // OK +> ``` +> +> This desugars to: +> +> ```rust +> # fn temp() {} +> # let x; +> { let [_x] = [&temp()]; x = _x; } // OK +> ``` +> +> However, if we try to use `x`, even within the same statement, we'll get an error because the [temporary] is dropped at the end of this introduced block. +> +> ```rust,compile_fail,E0716 +> # fn temp() {} +> # let x; +> ([x] = [&temp()], x); // ERROR +> ``` +> +> This desugars to: +> +> ```rust,compile_fail,E0716 +> # fn temp() {} +> # let x; +> ( +> { +> let [_x] = [&temp()]; +> x = _x; +> }, // <-- The temporary is dropped here. +> x, // ERROR +> ); +> ``` + +r[expr.compound-assign] +## Compound assignment expressions + +r[expr.compound-assign.syntax] +```grammar,expressions +CompoundAssignmentExpression -> + Expression `+=` Expression + | Expression `-=` Expression + | Expression `*=` Expression + | Expression `/=` Expression + | Expression `%=` Expression + | Expression `&=` Expression + | Expression `|=` Expression + | Expression `^=` Expression + | Expression `<<=` Expression + | Expression `>>=` Expression +``` + +r[expr.compound-assign.intro] +*Compound assignment expressions* combine arithmetic and logical binary operators with assignment expressions. + +For example: + +```rust +let mut x = 5; +x += 1; +assert!(x == 6); +``` + +The syntax of compound assignment is a [mutable] [place expression], the *assigned operand*, then one of the operators followed by an `=` as a single token (no whitespace), and then a [value expression], the *modifying operand*. + +r[expr.compound-assign.place] +Unlike other place operands, the assigned place operand must be a place expression. + +r[expr.compound-assign.no-value] +Attempting to use a value expression is a compiler error rather than promoting it to a temporary. + +r[expr.compound-assign.operand-order] +Evaluation of compound assignment expressions depends on the types of the operands. + +r[expr.compound-assign.primitives] +If the types of both operands are known, prior to monomorphization, to be primitive, the right hand side is evaluated first, the left hand side is evaluated next, and the place given by the evaluation of the left hand side is mutated by applying the operator to the values of both sides. + +```rust +# use core::{num::Wrapping, ops::AddAssign}; +# +trait Equate {} +impl<T> Equate for (T, T) {} + +fn f1(x: (u8,)) { + let mut order = vec![]; + // The RHS is evaluated first as both operands are of primitive + // type. + { order.push(2); x }.0 += { order.push(1); x }.0; + assert!(order.is_sorted()); +} + +fn f2(x: (Wrapping<u8>,)) { + let mut order = vec![]; + // The LHS is evaluated first as `Wrapping<_>` is not a primitive + // type. + { order.push(1); x }.0 += { order.push(2); (0u8,) }.0; + assert!(order.is_sorted()); +} + +fn f3<T: AddAssign<u8> + Copy>(x: (T,)) where (T, u8): Equate { + let mut order = vec![]; + // The LHS is evaluated first as one of the operands is a generic + // parameter, even though that generic parameter can be unified + // with a primitive type due to the where clause bound. + { order.push(1); x }.0 += { order.push(2); (0u8,) }.0; + assert!(order.is_sorted()); +} + +fn main() { + f1((0u8,)); + f2((Wrapping(0u8),)); + // We supply a primitive type as the generic argument, but this + // does not affect the evaluation order in `f3` when + // monomorphized. + f3::<u8>((0u8,)); +} +``` + +> [!NOTE] +> This is unusual. Elsewhere left to right evaluation is the norm. +> +> See the [eval order test] for more examples. + +r[expr.compound-assign.trait] +Otherwise, this expression is syntactic sugar for using the corresponding trait for the operator (see [expr.arith-logic.behavior]) and calling its method with the left hand side as the [receiver] and the right hand side as the next argument. + +For example, the following two statements are equivalent: + +```rust +# use std::ops::AddAssign; +fn f<T: AddAssign + Copy>(mut x: T, y: T) { + x += y; // Statement 1. + x.add_assign(y); // Statement 2. +} +``` + +> [!NOTE] +> Surprisingly, desugaring this further to a fully qualified method call is not equivalent, as there is special borrow checker behavior when the mutable reference to the first operand is taken via [autoref]. +> +> ```rust +> # use std::ops::AddAssign; +> fn f<T: AddAssign + Copy>(mut x: T) { +> // Here we used `x` as both the LHS and the RHS. Because the +> // mutable borrow of the LHS needed to call the trait method +> // is taken implicitly by autoref, this is OK. +> x += x; //~ OK +> x.add_assign(x); //~ OK +> } +> ``` +> +> ```rust,compile_fail,E0503 +> # use std::ops::AddAssign; +> fn f<T: AddAssign + Copy>(mut x: T) { +> // We can't desugar the above to the below, as once we take the +> // mutable borrow of `x` to pass the first argument, we can't +> // pass `x` by value in the second argument because the mutable +> // reference is still live. +> <T as AddAssign>::add_assign(&mut x, x); +> //~^ ERROR cannot use `x` because it was mutably borrowed +> } +> ``` +> +> ```rust,compile_fail,E0503 +> # use std::ops::AddAssign; +> fn f<T: AddAssign + Copy>(mut x: T) { +> // As above. +> (&mut x).add_assign(x); +> //~^ ERROR cannot use `x` because it was mutably borrowed +> } +> ``` + +r[expr.compound-assign.result] +As with normal assignment expressions, compound assignment expressions always produce [the unit value][unit]. + +> [!WARNING] +> Avoid writing code that depends on the evaluation order of operands in compound assignments as it can be unusual and surprising. + +[`Box`]: ../special-types-and-traits.md#boxt +[`Try`]: core::ops::Try +[autoref]: expr.method.candidate-receivers-refs +[copies or moves]: ../expressions.md#moved-and-copied-types +[dropping]: ../destructors.md +[eval order test]: https://github.com/rust-lang/rust/blob/1.58.0/src/test/ui/expr/compound-assignment/eval-order.rs +[explicit discriminants]: ../items/enumerations.md#explicit-discriminants +[extending expression]: destructors.scope.lifetime-extension.exprs +[field-less enums]: ../items/enumerations.md#field-less-enum +[grouped expression]: grouped-expr.md +[literal expression]: literal-expr.md#integer-literal-expressions +[logical and]: ../types/boolean.md#logical-and +[logical not]: ../types/boolean.md#logical-not +[logical or]: ../types/boolean.md#logical-or +[logical xor]: ../types/boolean.md#logical-xor +[metadata]: dynamic-sized.pointer-types +[moved from]: expr.move.movable-place +[mutable]: ../expressions.md#mutability +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[assignee expression]: ../expressions.md#place-expressions-and-value-expressions +[undefined behavior]: ../behavior-considered-undefined.md +[unit]: ../types/tuple.md +[Unit-only enums]: ../items/enumerations.md#unit-only-enum +[value expression]: ../expressions.md#place-expressions-and-value-expressions +[temporary lifetime extension]: destructors.scope.lifetime-extension +[temporary scope]: destructors.scope.temporary +[temporary value]: ../expressions.md#temporaries +[float-float]: https://github.com/rust-lang/rust/issues/15536 +[Function pointer]: ../types/function-pointer.md +[Function item]: ../types/function-item.md +[receiver]: expr.method.intro +[temporary]: expr.temporary +[undefined behavior]: ../behavior-considered-undefined.md +[Underscore expressions]: ./underscore-expr.md +[range expressions]: ./range-expr.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/path-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/path-expr.md new file mode 100644 index 00000000..fff9b9ef --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/path-expr.md @@ -0,0 +1,42 @@ +r[expr.path] +# Path expressions + +r[expr.path.syntax] +```grammar,expressions +PathExpression -> + PathInExpression + | QualifiedPathInExpression +``` + +r[expr.path.intro] +A [path] used as an expression context denotes either a local variable or an item. + +r[expr.path.place] +Path expressions that resolve to local or static variables are [place expressions]; other paths are [value expressions]. + +r[expr.path.safety] +Using a [`static mut`] variable requires an [`unsafe` block]. + +```rust +# mod globals { +# pub static STATIC_VAR: i32 = 5; +# pub static mut STATIC_MUT_VAR: i32 = 7; +# } +# let local_var = 3; +local_var; +globals::STATIC_VAR; +unsafe { globals::STATIC_MUT_VAR }; +let some_constructor = Some::<i32>; +let push_integer = Vec::<i32>::push; +let slice_reverse = <[i32]>::reverse; +``` + +r[expr.path.const] +Evaluation of associated constants is handled the same way as [`const` blocks]. + +[place expressions]: ../expressions.md#place-expressions-and-value-expressions +[value expressions]: ../expressions.md#place-expressions-and-value-expressions +[path]: ../paths.md +[`static mut`]: ../items/static-items.md#mutable-statics +[`unsafe` block]: block-expr.md#unsafe-blocks +[`const` blocks]: block-expr.md#const-blocks diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/range-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/range-expr.md new file mode 100644 index 00000000..16ec2414 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/range-expr.md @@ -0,0 +1,67 @@ +r[expr.range] +# Range expressions + +r[expr.range.syntax] +```grammar,expressions +RangeExpression -> + RangeExpr + | RangeFromExpr + | RangeToExpr + | RangeFullExpr + | RangeInclusiveExpr + | RangeToInclusiveExpr + +RangeExpr -> Expression `..` Expression + +RangeFromExpr -> Expression `..` + +RangeToExpr -> `..` Expression + +RangeFullExpr -> `..` + +RangeInclusiveExpr -> Expression `..=` Expression + +RangeToInclusiveExpr -> `..=` Expression +``` + +r[expr.range.behavior] +The `..` and `..=` operators will construct an object of one of the `std::ops::Range` (or `core::ops::Range`) variants, according to the following table: + +| Production | Syntax | Type | Range | +|------------------------|---------------|------------------------------|-----------------------| +| [RangeExpr] | start`..`end | [std::ops::Range] | start ≤ x < end | +| [RangeFromExpr] | start`..` | [std::ops::RangeFrom] | start ≤ x | +| [RangeToExpr] | `..`end | [std::ops::RangeTo] | x < end | +| [RangeFullExpr] | `..` | [std::ops::RangeFull] | - | +| [RangeInclusiveExpr] | start`..=`end | [std::ops::RangeInclusive] | start ≤ x ≤ end | +| [RangeToInclusiveExpr] | `..=`end | [std::ops::RangeToInclusive] | x ≤ end | + +Examples: + +```rust +1..2; // std::ops::Range +3..; // std::ops::RangeFrom +..4; // std::ops::RangeTo +..; // std::ops::RangeFull +5..=6; // std::ops::RangeInclusive +..=7; // std::ops::RangeToInclusive +``` + +r[expr.range.equivalence] +The following expressions are equivalent. + +```rust +let x = std::ops::Range {start: 0, end: 10}; +let y = 0..10; + +assert_eq!(x, y); +``` + +r[expr.range.for] +Ranges can be used in `for` loops: + +```rust +for i in 1..11 { + println!("{}", i); +} +``` diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/return-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/return-expr.md new file mode 100644 index 00000000..67569d5c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/return-expr.md @@ -0,0 +1,30 @@ +r[expr.return] +# `return` expressions + +r[expr.return.syntax] +```grammar,expressions +ReturnExpression -> `return` Expression? +``` + +r[expr.return.intro] +Return expressions are denoted with the keyword `return`. + +r[expr.return.behavior] +Evaluating a `return` expression moves its argument into the designated output location for the current function call, destroys the current function activation frame, and transfers control to the caller frame. + +r[expr.return.diverging] +A `return` expression is [diverging] and has a type of [`!`]. + +An example of a `return` expression: + +```rust +fn max(a: i32, b: i32) -> i32 { + if a > b { + return a; + } + return b; +} +``` + +[`!`]: type.never +[diverging]: divergence diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/struct-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/struct-expr.md new file mode 100644 index 00000000..0046a7db --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/struct-expr.md @@ -0,0 +1,151 @@ +r[expr.struct] +# Struct expressions + +r[expr.struct.syntax] +```grammar,expressions +StructExpression -> + PathInExpression `{` (StructExprFields | StructBase)? `}` + +StructExprFields -> + StructExprField (`,` StructExprField)* (`,` StructBase | `,`?) + +StructExprField -> + OuterAttribute* + ( + IDENTIFIER + | (IDENTIFIER | TUPLE_INDEX) `:` Expression + ) + +StructBase -> `..` Expression +``` + +r[expr.struct.intro] +A *struct expression* creates a struct, enum, or union value. It consists of a path to a [struct], [enum variant], or [union] item followed by the values for the fields of the item. + +The following are examples of struct expressions: + +```rust +# struct Point { x: f64, y: f64 } +# struct NothingInMe { } +# mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } } +# enum Enum { Variant {} } +Point {x: 10.0, y: 20.0}; +NothingInMe {}; +let u = game::User {name: "Joe", age: 35, score: 100_000}; +Enum::Variant {}; +``` + +> [!NOTE] +> Tuple structs and tuple enum variants are typically instantiated using a [call expression][expr.call] referring to the [constructor in the value namespace][items.struct.tuple]. These are distinct from a struct expression using curly braces referring to the constructor in the type namespace. +> +> ```rust +> struct Position(i32, i32, i32); +> Position(0, 0, 0); // Typical way of creating a tuple struct. +> let c = Position; // `c` is a function that takes 3 arguments. +> let pos = c(8, 6, 7); // Creates a `Position` value. +> +> enum Version { Triple(i32, i32, i32) }; +> Version::Triple(0, 0, 0); +> let f = Version::Triple; +> let ver = f(8, 6, 7); +> ``` +> +> The last segment of the call path cannot refer to a type alias: +> +> ```rust +> trait Tr { type T; } +> impl<T> Tr for T { type T = T; } +> +> struct Tuple(); +> enum Enum { Tuple() } +> +> // <Unit as Tr>::T(); // causes an error -- `::T` is a type, not a value +> <Enum as Tr>::T::Tuple(); // OK +> ``` +> +> ---- +> +> Unit structs and unit enum variants are typically instantiated using a [path expression][expr.path] referring to the [constant in the value namespace][items.struct.unit]. +> +> ```rust +> struct Gamma; +> // Gamma unit value, referring to the const in the value namespace. +> let a = Gamma; +> // Exact same value as `a`, but constructed using a struct expression +> // referring to the type namespace. +> let b = Gamma {}; +> +> enum ColorSpace { Oklch } +> let c = ColorSpace::Oklch; +> let d = ColorSpace::Oklch {}; +> ``` + +r[expr.struct.field] +## Field struct expression + +r[expr.struct.field.intro] +A struct expression with fields enclosed in curly braces allows you to specify the value for each individual field in any order. The field name is separated from its value with a colon. + +r[expr.struct.field.union-constraint] +A value of a [union] type can only be created using this syntax, and it must specify exactly one field. + +r[expr.struct.update] +## Functional update syntax + +r[expr.struct.update.intro] +A struct expression that constructs a value of a struct type can terminate with the syntax `..` followed by an expression to denote a functional update. + +r[expr.struct.update.base-same-type] +The expression following `..` (the base) must have the same struct type as the new struct type being formed. + +r[expr.struct.update.fields] +The entire expression uses the given values for the fields that were specified and moves or copies the remaining fields from the base expression. + +r[expr.struct.update.visibility-constraint] +As with all struct expressions, all of the fields of the struct must be [visible], even those not explicitly named. + +```rust +# struct Point3d { x: i32, y: i32, z: i32 } +let mut base = Point3d {x: 1, y: 2, z: 3}; +let y_ref = &mut base.y; +Point3d {y: 0, z: 10, .. base}; // OK, only base.x is accessed +drop(y_ref); +``` + +r[expr.struct.brace-restricted-positions] +Struct expressions can't be used directly in a [loop] or [if] expression's head, or in the [scrutinee] of an [if let] or [match] expression. However, struct expressions can be used in these situations if they are within another expression, for example inside [parentheses]. + +r[expr.struct.tuple-field] +The field names can be decimal integer values to specify indices for constructing tuple structs. This can be used with base structs to fill out the remaining indices not specified: + +```rust +struct Color(u8, u8, u8); +let c1 = Color(0, 0, 0); // Typical way of creating a tuple struct. +let c2 = Color{0: 255, 1: 127, 2: 0}; // Specifying fields by index. +let c3 = Color{1: 0, ..c2}; // Fill out all other fields using a base struct. +``` + +r[expr.struct.field.named] +### Struct field init shorthand + +When initializing a data structure (struct, enum, union) with named (but not numbered) fields, it is allowed to write `fieldname` as a shorthand for `fieldname: fieldname`. This allows a compact syntax with less duplication. For example: + +```rust +# struct Point3d { x: i32, y: i32, z: i32 } +# let x = 0; +# let y_value = 0; +# let z = 0; +Point3d { x: x, y: y_value, z: z }; +Point3d { x, y: y_value, z }; +``` + +[enum variant]: ../items/enumerations.md +[if let]: if-expr.md#if-let-patterns +[if]: if-expr.md#if-expressions +[loop]: loop-expr.md +[match]: match-expr.md +[parentheses]: grouped-expr.md +[struct]: ../items/structs.md +[union]: ../items/unions.md +[visible]: ../visibility-and-privacy.md +[scrutinee]: ../glossary.md#scrutinee diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/tuple-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/tuple-expr.md new file mode 100644 index 00000000..f96dfa5c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/tuple-expr.md @@ -0,0 +1,98 @@ +r[expr.tuple] +# Tuple and tuple indexing expressions + +## Tuple expressions + +r[expr.tuple.syntax] +```grammar,expressions +TupleExpression -> `(` TupleElements? `)` + +TupleElements -> ( Expression `,` )+ Expression? +``` + +r[expr.tuple.result] +A *tuple expression* constructs [tuple values][tuple type]. + +r[expr.tuple.intro] +The syntax for tuple expressions is a parenthesized, comma separated list of expressions, called the *tuple initializer operands*. + +r[expr.tuple.unary-tuple-restriction] +1-ary tuple expressions require a comma after their tuple initializer operand to be disambiguated with a [parenthetical expression]. + +r[expr.tuple.value] +Tuple expressions are a [value expression] that evaluate into a newly constructed value of a tuple type. + +r[expr.tuple.type] +The number of tuple initializer operands is the arity of the constructed tuple. + +r[expr.tuple.unit] +Tuple expressions without any tuple initializer operands produce the unit tuple. + +r[expr.tuple.fields] +For other tuple expressions, the first written tuple initializer operand initializes the field `0` and subsequent operands initializes the next highest field. For example, in the tuple expression `('a', 'b', 'c')`, `'a'` initializes the value of the field `0`, `'b'` field `1`, and `'c'` field `2`. + +Examples of tuple expressions and their types: + +| Expression | Type | +| -------------------- | ------------ | +| `()` | `()` (unit) | +| `(0.0, 4.5)` | `(f64, f64)` | +| `("x".to_string(), )` | `(String, )` | +| `("a", 4usize, true)`| `(&'static str, usize, bool)` | + +r[expr.tuple-index] +## Tuple indexing expressions + +r[expr.tuple-index.syntax] +```grammar,expressions +TupleIndexingExpression -> Expression `.` TUPLE_INDEX +``` + +r[expr.tuple-index.intro] +A *tuple indexing expression* accesses fields of [tuples][tuple type] and [tuple structs][tuple struct]. + +The syntax for a tuple index expression is an expression, called the *tuple operand*, then a `.`, then finally a tuple index. + +r[expr.tuple-index.index-syntax] +The syntax for the *tuple index* is a [decimal literal] with no leading zeros, underscores, or suffix. For example `0` and `2` are valid tuple indices but not `01`, `0_`, nor `0i32`. + +r[expr.tuple-index.required-type] +The type of the tuple operand must be a [tuple type] or a [tuple struct]. + +r[expr.tuple-index.index-name-operand] +The tuple index must be a name of a field of the type of the tuple operand. + +r[expr.tuple-index.result] +Evaluation of tuple index expressions has no side effects beyond evaluation of its tuple operand. As a [place expression], it evaluates to the location of the field of the tuple operand with the same name as the tuple index. + +Examples of tuple indexing expressions: + +```rust +// Indexing a tuple +let pair = ("a string", 2); +assert_eq!(pair.1, 2); + +// Indexing a tuple struct +# struct Point(f32, f32); +let point = Point(1.0, 0.0); +assert_eq!(point.0, 1.0); +assert_eq!(point.1, 0.0); +``` + +> [!NOTE] +> Unlike field access expressions, tuple index expressions can be the function operand of a [call expression] as it cannot be confused with a method call since method names cannot be numbers. + +> [!NOTE] +> Although arrays and slices also have elements, you must use an [array or slice indexing expression] or a [slice pattern] to access their elements. + +[array or slice indexing expression]: array-expr.md#array-and-slice-indexing-expressions +[call expression]: ./call-expr.md +[decimal literal]: ../tokens.md#integer-literals +[field access expressions]: ./field-expr.html#field-access-expressions +[operands]: ../expressions.md +[parenthetical expression]: grouped-expr.md +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[slice pattern]: ../patterns.md#slice-patterns +[tuple type]: ../types/tuple.md +[tuple struct]: ../types/struct.md +[value expression]: ../expressions.md#place-expressions-and-value-expressions diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/expressions/underscore-expr.md b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/underscore-expr.md new file mode 100644 index 00000000..d7172132 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/expressions/underscore-expr.md @@ -0,0 +1,39 @@ +r[expr.placeholder] +# `_` expressions + +r[expr.placeholder.syntax] +```grammar,expressions +UnderscoreExpression -> `_` +``` + +r[expr.placeholder.intro] +Underscore expressions, denoted with the symbol `_`, are used to signify a placeholder in a destructuring assignment. + +r[expr.placeholder.lhs-assignment-only] +They may only appear in the left-hand side of an assignment. + +r[expr.placeholder.pattern] +Note that this is distinct from the [wildcard pattern](../patterns.md#wildcard-pattern). + +Examples of `_` expressions: + +```rust +let p = (1, 2); +let mut a = 0; +(_, a) = p; + +struct Position { + x: u32, + y: u32, +} + +Position { x: a, y: _ } = Position{ x: 2, y: 3 }; + +// unused result, assignment to `_` used to declare intent and remove a warning +_ = 2 + 2; +// triggers unused_must_use warning +// 2 + 2; + +// equivalent technique using a wildcard pattern in a let-binding +let _ = 2 + 2; +``` diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/glossary.md b/stdlib/kvlang/reference/rust/reference-repo/src/glossary.md new file mode 100644 index 00000000..80cf0f26 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/glossary.md @@ -0,0 +1,368 @@ +# Glossary + +r[glossary.ast] +### Abstract syntax tree + +An ‘abstract syntax tree’, or ‘AST’, is an intermediate representation of the structure of the program when the compiler is compiling it. + +### Alignment + +The alignment of a value specifies what addresses values are preferred to start at. Always a power of two. References to a value must be aligned. [More][alignment]. + +r[glossary.abi] +### Application binary interface (ABI) + +An *application binary interface* (ABI) defines how compiled code interacts with other compiled code. With [`extern` blocks] and [`extern fn`], *ABI strings* affect: + +- **Calling convention**: How function arguments are passed, values are returned (e.g., in registers or on the stack), and who is responsible for cleaning up the stack. +- **Unwinding**: Whether stack unwinding is allowed. For example, the `"C-unwind"` ABI allows unwinding across the FFI boundary, while the `"C"` ABI does not. + +### Arity + +Arity refers to the number of arguments a function or operator takes. For some examples, `f(2, 3)` and `g(4, 6)` have arity 2, while `h(8, 2, 6)` has arity 3. The `!` operator has arity 1. + +### Array + +An array, sometimes also called a fixed-size array or an inline array, is a value describing a collection of elements, each selected by an index that can be computed at run time by the program. It occupies a contiguous region of memory. + +### Associated item + +An associated item is an item that is associated with another item. Associated items are defined in [implementations] and declared in [traits]. Only functions, constants, and type aliases can be associated. Contrast to a [free item]. + +### Blanket implementation + +Any implementation where a type appears [uncovered](#uncovered-type). `impl<T> Foo for T`, `impl<T> Bar<T> for T`, `impl<T> Bar<Vec<T>> for T`, and `impl<T> Bar<T> for Vec<T>` are considered blanket impls. However, `impl<T> Bar<Vec<T>> for Vec<T>` is not a blanket impl, as all instances of `T` which appear in this `impl` are covered by `Vec`. + +### Bound + +Bounds are constraints on a type or trait. For example, if a bound is placed on the argument a function takes, types passed to that function must abide by that constraint. + +### Combinator + +Combinators are higher-order functions that apply only functions and earlier defined combinators to provide a result from its arguments. They can be used to manage control flow in a modular fashion. + +### Crate + +A crate is the unit of compilation and linking. There are different [types of crates], such as libraries or executables. Crates may link and refer to other library crates, called external crates. A crate has a self-contained tree of [modules], starting from an unnamed root module called the crate root. [Items] may be made visible to other crates by marking them as public in the crate root, including through [paths] of public modules. [More][crate]. + +### Dispatch + +Dispatch is the mechanism to determine which specific version of code is actually run when it involves polymorphism. Two major forms of dispatch are static dispatch and dynamic dispatch. Rust supports dynamic dispatch through the use of [trait objects][type.trait-object]. + +### Dynamically sized type + +A dynamically sized type (DST) is a type without a statically known size or alignment. + +### Entity + +An [*entity*] is a language construct that can be referred to in some way within the source program, usually via a [path][paths]. Entities include [types], [items], [generic parameters], [variable bindings], [loop labels], [lifetimes], [fields], [attributes], and [lints]. + +### Expression + +An expression is a combination of values, constants, variables, operators and functions that evaluate to a single value, with or without side-effects. + +For example, `2 + (3 * 4)` is an expression that returns the value 14. + +### Free item + +An [item] that is not a member of an [implementation], such as a *free function* or a *free const*. Contrast to an [associated item]. + +### Fundamental traits + +A fundamental trait is one where adding an impl of it for an existing type is a breaking change. The `Fn` traits and `Sized` are fundamental. + +### Fundamental type constructors + +A fundamental type constructor is a type where implementing a [blanket implementation](#blanket-implementation) over it is a breaking change. `&`, `&mut`, `Box`, and `Pin` are fundamental. + +Any time a type `T` is considered [local](#local-type), `&T`, `&mut T`, `Box<T>`, and `Pin<T>` are also considered local. Fundamental type constructors cannot [cover](#uncovered-type) other types. Any time the term "covered type" is used, the `T` in `&T`, `&mut T`, `Box<T>`, and `Pin<T>` is not considered covered. + +### Inhabited + +A type is inhabited if it has constructors and therefore can be instantiated. An inhabited type is not "empty" in the sense that there can be values of the type. Opposite of [Uninhabited](#uninhabited). + +### Inherent implementation + +An [implementation] that applies to a nominal type, not to a trait-type pair. [More][inherent implementation]. + +### Inherent method + +A [method] defined in an [inherent implementation], not in a trait implementation. + +### Initialized + +A variable is initialized if it has been assigned a value and hasn't since been moved from. All other memory locations are assumed to be uninitialized. Only unsafe Rust can create a memory location without initializing it. + +### Local trait + +A `trait` which was defined in the current crate. A trait definition is local or not independent of applied type arguments. Given `trait Foo<T, U>`, `Foo` is always local, regardless of the types substituted for `T` and `U`. + +### Local type + +A `struct`, `enum`, or `union` which was defined in the current crate. This is not affected by applied type arguments. `struct Foo` is considered local, but `Vec<Foo>` is not. `LocalType<ForeignType>` is local. Type aliases do not affect locality. + +### Module + +A module is a container for zero or more [items]. Modules are organized in a tree, starting from an unnamed module at the root called the crate root or the root module. [Paths] may be used to refer to items from other modules, which may be restricted by [visibility rules]. [More][modules] + +### Name + +A [*name*] is an [identifier] or [lifetime or loop label] that refers to an [entity](#entity). A *name binding* is when an entity declaration introduces an identifier or label associated with that entity. [Paths], identifiers, and labels are used to refer to an entity. + +### Name resolution + +[*Name resolution*] is the compile-time process of tying [paths], [identifiers], and [labels] to [entity](#entity) declarations. + +### Namespace + +A *namespace* is a logical grouping of declared [names](#name) based on the kind of [entity](#entity) the name refers to. Namespaces allow the occurrence of a name in one namespace to not conflict with the same name in another namespace. + +Within a namespace, names are organized in a hierarchy, where each level of the hierarchy has its own collection of named entities. + +### Nominal types + +Types that can be referred to by a path directly. Specifically [enums], [structs], [unions], and [trait object types]. + +### Dyn-compatible traits + +[Traits] that can be used in [trait object types] (`dyn Trait`). Only traits that follow specific [rules][dyn compatibility] are *dyn compatible*. + +These were formerly known as *object safe* traits. + +### Path + +A [*path*] is a sequence of one or more path segments used to refer to an [entity](#entity) in the current scope or other levels of a [namespace](#namespace) hierarchy. + +### Prelude + +Prelude, or The Rust Prelude, is a small collection of items - mostly traits - that are imported into every module of every crate. The traits in the prelude are pervasive. + +### Scope + +A [*scope*] is the region of source text where a named [entity](#entity) may be referenced with that name. + +### Scrutinee + +A scrutinee is the expression that is matched on in `match` expressions and similar pattern matching constructs. For example, in `match x { A => 1, B => 2 }`, the expression `x` is the scrutinee. + +### Size + +The size of a value has two definitions. + +The first is that it is how much memory must be allocated to store that value. + +The second is that it is the offset in bytes between successive elements in an array with that item type. + +It is a multiple of the alignment, including zero. The size can change depending on compiler version (as new optimizations are made) and target platform (similar to how `usize` varies per-platform). + +[More][alignment]. + +### Slice + +A slice is dynamically-sized view into a contiguous sequence, written as `[T]`. + +It is often seen in its borrowed forms, either mutable or shared. The shared slice type is `&[T]`, while the mutable slice type is `&mut [T]`, where `T` represents the element type. + +### Statement + +A statement is the smallest standalone element of a programming language that commands a computer to perform an action. + +### String literal + +A string literal is a string stored directly in the final binary, and so will be valid for the `'static` duration. + +Its type is `'static` duration borrowed string slice, `&'static str`. + +### String slice + +A string slice is the most primitive string type in Rust, written as `str`. It is often seen in its borrowed forms, either mutable or shared. The shared string slice type is `&str`, while the mutable string slice type is `&mut str`. + +Strings slices are always valid UTF-8. + +### Trait + +A trait is a language item that is used for describing the functionalities a type must provide. It allows a type to make certain promises about its behavior. + +Generic functions and generic structs can use traits to constrain, or bound, the types they accept. + +### Turbofish + +Paths with generic parameters in expressions must prefix the opening brackets with a `::`. Combined with the angular brackets for generics, this looks like a fish `::<>`. As such, this syntax is colloquially referred to as turbofish syntax. + +Examples: + +```rust +let ok_num = Ok::<_, ()>(5); +let vec = [1, 2, 3].iter().map(|n| n * 2).collect::<Vec<_>>(); +``` + +This `::` prefix is required to disambiguate generic paths with multiple comparisons in a comma-separate list. See [the bastion of the turbofish][turbofish test] for an example where not having the prefix would be ambiguous. + +### Uncovered type + +A type which does not appear as an argument to another type. For example, `T` is uncovered, but the `T` in `Vec<T>` is covered. This is only relevant for type arguments. + +### Undefined behavior + +Compile-time or run-time behavior that is not specified. This may result in, but is not limited to: process termination or corruption; improper, incorrect, or unintended computation; or platform-specific results. [More][undefined-behavior]. + +r[glossary.uninhabited] +### Uninhabited + +A type is uninhabited if it has no constructors and therefore can never be instantiated. An uninhabited type is "empty" in the sense that there are no values of the type. The canonical example of an uninhabited type is the [never type] `!`, or an enum with no variants `enum Never { }`. Opposite of [Inhabited](#inhabited). + +> [!NOTE] +> Uninhabited types are not necessarily [zero sized]. For example, `enum Never { }` is uninhabited and zero sized, but `(u8, Never)` is uninhabited and not zero sized. + +r[glossary.zst] +### Zero-sized type (ZST) + +A type is zero sized (a ZST) if its size is 0. Such types have at most one possible value. Examples include: + +- The [unit type] (see [layout.tuple.unit]). +- [Function items] (see [type.fn-item.intro]). +- The constructors of [tuple-like structs] (see [type.fn-item.intro]). +- The constructors of [tuple-like enum variants] (see [type.fn-item.intro]). +- `repr(Rust)` [structs] with no fields or where all fields are zero sized (see [layout.repr.rust.struct-zst]). +- `repr(C)` [structs] with no fields or where all fields are zero-sized (see [layout.repr.c.struct.size-field-offset]). +- `repr(transparent)` [structs] with no fields or where all fields are zero-sized (see [layout.repr.transparent.layout-abi]). +- `repr(Rust)` [enums] (without a [primitive representation] specified) with no variants (see [layout.repr.rust.enum-empty-zst]). +- `repr(Rust)` [enums] (without a [primitive representation] specified) with a single [field-struct-like variant], a single [unit-struct-like variant], or a single [tuple-struct-like variant] and where the struct-like thing has no fields or where all of the fields are zero sized (see [layout.repr.rust.enum-struct-like-zst]). +- [Arrays] of zero-sized types (see [layout.array]). +- [Arrays] of length zero (see [layout.array]). +- [Unions] of zero-sized types (see [items.union.common-storage]). + +```rust +# use core::mem::{size_of, size_of_val}; +fn f() {} +struct S(u8); +enum E { V(u8) } +struct UnitLike; +struct NoFields {} +struct OnlyZST { + f1: (), + f2: [(); 10], + f3: [u8; 0], +} +#[repr(C)] +struct C1 {} +#[repr(C)] +struct C2 { + f1: (), + f2: [(); 10], + f3: [u8; 0], + f4: C1, +} +#[repr(transparent)] +struct T1 {} +#[repr(transparent)] +struct T2 { + f1: (), + f2: [(); 10], + f3: [u8; 0], +} +union U { + f1: (), + f2: [(); 10], + f3: [u8; 0], +} +# /// An enum with a single field-struct-like variant with all fields +# /// being ZSTs. +enum E2 { + V1 { f1: (), f2: [(); 10] }, +} +# /// An enum with a single field-struct-like variant with no fields. +enum E3 { + V1 {}, +} +# /// An enum with a single unit-struct-like variant. +enum E4 { + V1, +} +# /// An enum with a single tuple-struct-like variant with all fields +# /// being ZSTs. +enum E5 { + V1 ((), [(); 10]), +} +# /// An enum with a single tuple-struct-like variant with no fields. +enum E6 { + V1 (), +} +# /// An enum with no variants. +enum E7 {} + +assert_eq!(0, size_of::<()>()); +assert_eq!(0, size_of_val(&f)); +assert_eq!(0, size_of_val(&S)); +assert_eq!(0, size_of_val(&E::V)); +assert_eq!(0, size_of::<UnitLike>()); +assert_eq!(0, size_of::<NoFields>()); +assert_eq!(0, size_of::<OnlyZST>()); +assert_eq!(0, size_of::<C1>()); +assert_eq!(0, size_of::<C2>()); +assert_eq!(0, size_of::<T1>()); +assert_eq!(0, size_of::<T2>()); +assert_eq!(0, size_of::<[(); 10]>()); +assert_eq!(0, size_of::<[u8; 0]>()); +assert_eq!(0, size_of::<U>()); +assert_eq!(0, size_of::<E2>()); +assert_eq!(0, size_of::<E3>()); +assert_eq!(0, size_of::<E4>()); +assert_eq!(0, size_of::<E5>()); +assert_eq!(0, size_of::<E6>()); +assert_eq!(0, size_of::<E7>()); +``` + +[`extern` blocks]: items.extern +[`extern fn`]: items.fn.extern +[alignment]: type-layout.md#size-and-alignment +[arrays]: type.array +[associated item]: #associated-item +[attributes]: attributes.md +[*entity*]: names.md +[crate]: crates-and-source-files.md +[dyn compatibility]: items/traits.md#dyn-compatibility +[enums]: items/enumerations.md +[field-struct-like variant]: EnumVariantStruct +[fields]: expressions/field-expr.md +[free item]: #free-item +[function items]: type.fn-item +[generic parameters]: items/generics.md +[identifier]: identifiers.md +[identifiers]: identifiers.md +[implementation]: items/implementations.md +[implementations]: items/implementations.md +[inherent implementation]: items/implementations.md#inherent-implementations +[item]: items.md +[items]: items.md +[labels]: tokens.md#lifetimes-and-loop-labels +[lifetime or loop label]: tokens.md#lifetimes-and-loop-labels +[lifetimes]: tokens.md#lifetimes-and-loop-labels +[lints]: attributes/diagnostics.md#lint-check-attributes +[loop labels]: tokens.md#lifetimes-and-loop-labels +[method]: items/associated-items.md#methods +[modules]: items/modules.md +[*Name resolution*]: names/name-resolution.md +[*name*]: names.md +[*namespace*]: names/namespaces.md +[never type]: types/never.md +[*path*]: paths.md +[Paths]: paths.md +[primitive representation]: layout.repr.primitive +[*scope*]: names/scopes.md +[structs]: items/structs.md +[tuple-like enum variants]: items.enum.constructor-namespace +[tuple-like structs]: items.struct.tuple +[tuple-struct-like variant]: EnumVariantTuple +[trait object types]: types/trait-object.md +[traits]: items/traits.md +[turbofish test]: https://github.com/rust-lang/rust/blob/1.58.0/src/test/ui/parser/bastion-of-the-turbofish.rs +[types of crates]: linkage.md +[types]: types.md +[undefined-behavior]: behavior-considered-undefined.md +[unions]: items/unions.md +[unit type]: type.tuple.unit +[unit-struct-like variant]: EnumVariant +[variable bindings]: patterns.md +[visibility rules]: visibility-and-privacy.md +[zero sized]: glossary.zst diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/grammar.md b/stdlib/kvlang/reference/rust/reference-repo/src/grammar.md new file mode 100644 index 00000000..e27d7393 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/grammar.md @@ -0,0 +1,5 @@ +# Grammar summary + +The following is a summary of the grammar production rules. For details on the syntax of this grammar, see *[notation.grammar.syntax]*. + +{{ grammar-summary }} diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/identifiers.md b/stdlib/kvlang/reference/rust/reference-repo/src/identifiers.md new file mode 100644 index 00000000..5abe303c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/identifiers.md @@ -0,0 +1,89 @@ +r[ident] +# Identifiers + +r[ident.syntax] +```grammar,lexer +IDENTIFIER_OR_KEYWORD -> ( XID_Start | `_` ) XID_Continue* + +XID_Start -> <`XID_Start` defined by Unicode> + +XID_Continue -> <`XID_Continue` defined by Unicode> + +RAW_IDENTIFIER -> `r#` IDENTIFIER_OR_KEYWORD + +NON_KEYWORD_IDENTIFIER -> IDENTIFIER_OR_KEYWORD _except a [strict][lex.keywords.strict] or [reserved][lex.keywords.reserved] keyword_ + +IDENTIFIER -> NON_KEYWORD_IDENTIFIER | RAW_IDENTIFIER + +RESERVED_RAW_IDENTIFIER -> + `r#` (`_` | `crate` | `self` | `Self` | `super`) !XID_Continue +``` + +<!-- When updating the version, update the UAX links, too. --> +r[ident.unicode] +Identifiers follow the specification in [Unicode Standard Annex #31][UAX31] for Unicode version 17.0, with the additions described below. Some examples of identifiers: + +* `foo` +* `_identifier` +* `r#true` +* `Москва` +* `東京` + +r[ident.profile] +The profile used from UAX #31 is: + +* Start := [`XID_Start`], plus the underscore character (U+005F) +* Continue := [`XID_Continue`] +* Medial := empty + +> [!NOTE] +> Identifiers starting with an underscore are typically used to indicate an identifier that is intentionally unused, and will silence the unused warning in `rustc`. + +r[ident.keyword] +Identifiers may not be a [strict] or [reserved] keyword without the `r#` prefix described below in [raw identifiers](#raw-identifiers). + +r[ident.zero-width-chars] +Zero width non-joiner (ZWNJ U+200C) and zero width joiner (ZWJ U+200D) characters are not allowed in identifiers. + +r[ident.ascii-limitations] +Identifiers are restricted to the ASCII subset of [`XID_Start`] and [`XID_Continue`] in the following situations: + +* [`extern crate`] declarations (except the [AsClause] identifier) +* External crate names referenced in a [path] +* [Module] names loaded from the filesystem without a [`path` attribute] +* [`no_mangle`] attributed items +* Item names in [external blocks] + +r[ident.normalization] +## Normalization + +Identifiers are normalized using Normalization Form C (NFC) as defined in [Unicode Standard Annex #15][UAX15]. Two identifiers are equal if their NFC forms are equal. + +[Procedural][proc-macro] and [declarative][mbe] macros receive normalized identifiers in their input. + +r[ident.raw] +## Raw identifiers + +r[ident.raw.intro] +A raw identifier is like a normal identifier, but prefixed by `r#`. (Note that the `r#` prefix is not included as part of the actual identifier.) + +r[ident.raw.allowed] +Unlike a normal identifier, a raw identifier may be any strict or reserved keyword except the ones listed above for `RAW_IDENTIFIER`. + +r[ident.raw.reserved] +It is an error to use the [RESERVED_RAW_IDENTIFIER] token. + +[`extern crate`]: items/extern-crates.md +[`no_mangle`]: abi.md#the-no_mangle-attribute +[`path` attribute]: items/modules.md#the-path-attribute +[`XID_Continue`]: http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Continue%3A%5D&abb=on&g=&i= +[`XID_Start`]: http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Start%3A%5D&abb=on&g=&i= +[external blocks]: items/external-blocks.md +[mbe]: macros-by-example.md +[module]: items/modules.md +[path]: paths.md +[proc-macro]: procedural-macros.md +[reserved]: keywords.md#reserved-keywords +[strict]: keywords.md#strict-keywords +[UAX15]: https://www.unicode.org/reports/tr15/tr15-57.html +[UAX31]: https://www.unicode.org/reports/tr31/tr31-43.html diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/influences.md b/stdlib/kvlang/reference/rust/reference-repo/src/influences.md new file mode 100644 index 00000000..359c292a --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/influences.md @@ -0,0 +1,16 @@ +# Influences + +Rust is not a particularly original language, with design elements coming from a wide range of sources. Some of these are listed below (including elements that have since been removed): + +* SML, OCaml: algebraic data types, pattern matching, type inference, semicolon statement separation +* C++: references, RAII, smart pointers, move semantics, monomorphization, memory model +* ML Kit, Cyclone: region based memory management +* Haskell (GHC): typeclasses, type families +* Newsqueak, Alef, Limbo: channels, concurrency +* Erlang: message passing, thread failure, ~~linked thread failure~~, ~~lightweight concurrency~~ +* Swift: optional bindings +* Scheme: hygienic macros +* C#: attributes +* Ruby: closure syntax, ~~block syntax~~ +* NIL, Hermes: ~~typestate~~ +* [Unicode Annex #31](http://www.unicode.org/reports/tr31/): identifier and pattern syntax diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/inline-assembly.md b/stdlib/kvlang/reference/rust/reference-repo/src/inline-assembly.md new file mode 100644 index 00000000..8f7e5355 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/inline-assembly.md @@ -0,0 +1,1728 @@ +r[asm] +# Inline assembly + +r[asm.intro] +Support for inline assembly is provided via the [`asm!`], [`naked_asm!`], and [`global_asm!`] macros. It can be used to embed handwritten assembly in the assembly output generated by the compiler. + +[`asm!`]: core::arch::asm +[`naked_asm!`]: core::arch::naked_asm +[`global_asm!`]: core::arch::global_asm + +r[asm.stable-targets] +Support for inline assembly is stable on the following architectures: +- x86 and x86-64 +- ARM +- AArch64 and Arm64EC +- RISC-V +- LoongArch +- s390x +- PowerPC and PowerPC64 + +The compiler will emit an error if an assembly macro is used on an unsupported target. + +r[asm.example] +## Example + +```rust +# #[cfg(target_arch = "x86_64")] { +use std::arch::asm; + +// Multiply x by 6 using shifts and adds +let mut x: u64 = 4; +unsafe { + asm!( + "mov {tmp}, {x}", + "shl {tmp}, 1", + "shl {x}, 2", + "add {x}, {tmp}", + x = inout(reg) x, + tmp = out(reg) _, + ); +} +assert_eq!(x, 4 * 6); +# } +``` + +r[asm.syntax] +## Syntax + +The following grammar specifies the arguments that can be passed to the `asm!`, `global_asm!` and `naked_asm!` macros. + +```grammar,assembly +@root AsmArgs -> AsmAttrFormatString (`,` AsmAttrFormatString)* (`,` AsmAttrOperand)* `,`? + +FormatString -> STRING_LITERAL | RAW_STRING_LITERAL | MacroInvocation + +AsmAttrFormatString -> (OuterAttribute)* FormatString + +AsmOperand -> + ClobberAbi + | AsmOptions + | RegOperand + +AsmAttrOperand -> (OuterAttribute)* AsmOperand + +ClobberAbi -> `clobber_abi` `(` Abi (`,` Abi)* `,`? `)` + +AsmOptions -> + `options` `(` ( AsmOption (`,` AsmOption)* `,`? )? `)` + +AsmOption -> + `pure` + | `nomem` + | `readonly` + | `preserves_flags` + | `noreturn` + | `nostack` + | `att_syntax` + | `raw` + +RegOperand -> (ParamName `=`)? + ( + DirSpec `(` RegSpec `)` Expression + | DualDirSpec `(` RegSpec `)` DualDirSpecExpression + | `sym` PathExpression + | `const` Expression + | `label` `{` Statements? `}` + ) + +ParamName -> IDENTIFIER_OR_KEYWORD | RAW_IDENTIFIER + +DualDirSpecExpression -> + Expression + | Expression `=>` Expression + +RegSpec -> RegisterClass | ExplicitRegister + +RegisterClass -> IDENTIFIER_OR_KEYWORD + +ExplicitRegister -> STRING_LITERAL + +DirSpec -> + `in` + | `out` + | `lateout` + +DualDirSpec -> + `inout` + | `inlateout` +``` + +r[asm.scope] +## Scope + +r[asm.scope.intro] +Inline assembly can be used in one of three ways. + +r[asm.scope.asm] +With the `asm!` macro, the assembly code is emitted in a function scope and integrated into the compiler-generated assembly code of a function. This assembly code must obey [strict rules](#rules-for-inline-assembly) to avoid undefined behavior. Note that in some cases the compiler may choose to emit the assembly code as a separate function and generate a call to it. + +```rust +# #[cfg(target_arch = "x86_64")] { +unsafe { core::arch::asm!("/* {} */", in(reg) 0); } +# } +``` + +r[asm.scope.naked_asm] +With the `naked_asm!` macro, the assembly code is emitted in a function scope and constitutes the full assembly code of a function. The `naked_asm!` macro is only allowed in [naked functions](attributes/codegen.md#the-naked-attribute). + +```rust +# #[cfg(target_arch = "x86_64")] { +# #[unsafe(naked)] +# extern "C" fn wrapper() { +core::arch::naked_asm!("/* {} */", const 0); +# } +# } +``` + +r[asm.scope.global_asm] +With the `global_asm!` macro, the assembly code is emitted in a global scope, outside a function. This can be used to hand-write entire functions using assembly code, and generally provides much more freedom to use arbitrary registers and assembler directives. + +```rust +# fn main() {} +# #[cfg(target_arch = "x86_64")] +core::arch::global_asm!("/* {} */", const 0); +``` + +r[asm.ts-args] +## Template string arguments + +r[asm.ts-args.syntax] +The assembler template uses the same syntax as [format strings][format-syntax] (i.e. placeholders are specified by curly braces). + +r[asm.ts-args.order] +The corresponding arguments are accessed in order, by index, or by name. + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i64; +let y: i64; +let z: i64; +// This +unsafe { core::arch::asm!("mov {}, {}", out(reg) x, in(reg) 5); } +// ... this +unsafe { core::arch::asm!("mov {0}, {1}", out(reg) y, in(reg) 5); } +// ... and this +unsafe { core::arch::asm!("mov {out}, {in}", out = out(reg) z, in = in(reg) 5); } +// all have the same behavior +assert_eq!(x, y); +assert_eq!(y, z); +# } +``` + +r[asm.ts-args.no-implicit] +However, implicit named arguments (introduced by [RFC #2795][rfc-2795]) are not supported. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +let x = 5; +// We can't refer to `x` from the scope directly, we need an operand like `in(reg) x` +unsafe { core::arch::asm!("/* {x} */"); } // ERROR: no argument named x +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.ts-args.one-or-more] +An `asm!` invocation may have one or more template string arguments; an `asm!` with multiple template string arguments is treated as if all the strings were concatenated with a `\n` between them. The expected use is for each template string argument to correspond to a line of assembly code. + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i64; +let y: i64; +// We can separate multiple strings as if they were written together +unsafe { core::arch::asm!("mov eax, 5", "mov ecx, eax", out("rax") x, out("rcx") y); } +assert_eq!(x, y); +# } +``` + +r[asm.ts-args.before-other-args] +All template string arguments must appear before any other arguments. + +```rust,compile_fail +let x = 5; +# #[cfg(target_arch = "x86_64")] { +// The template strings need to appear first in the asm invocation +unsafe { core::arch::asm!("/* {x} */", x = const 5, "ud2"); } // ERROR: unexpected token +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.ts-args.positional-first] +As with format strings, positional arguments must appear before named arguments and explicit [register operands](#register-operands). + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// Named operands need to come after positional ones +unsafe { core::arch::asm!("/* {x} {} */", x = const 5, in(reg) 5); } +// ERROR: positional arguments cannot follow named arguments or explicit register arguments +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// We also can't put explicit registers before positional operands +unsafe { core::arch::asm!("/* {} */", in("eax") 0, in(reg) 5); } +// ERROR: positional arguments cannot follow named arguments or explicit register arguments +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.ts-args.register-operands] +Explicit register operands cannot be used by placeholders in the template string. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// Explicit register operands don't get substituted, use `eax` explicitly in the string +unsafe { core::arch::asm!("/* {} */", in("eax") 5); } +// ERROR: invalid reference to argument at index 0 +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.ts-args.at-least-once] +All other named and positional operands must appear at least once in the template string, otherwise a compiler error is generated. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// We have to name all of the operands in the format string +unsafe { core::arch::asm!("", in(reg) 5, x = const 5); } +// ERROR: multiple unused asm arguments +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.ts-args.opaque] +The exact assembly code syntax is target-specific and opaque to the compiler except for the way operands are substituted into the template string to form the code passed to the assembler. + +r[asm.ts-args.llvm-syntax] +Currently, all supported targets follow the assembly code syntax used by LLVM's internal assembler which usually corresponds to that of the GNU assembler (GAS). On x86, the `.intel_syntax noprefix` mode of GAS is used by default. On ARM, the `.syntax unified` mode is used. These targets impose an additional restriction on the assembly code: any assembler state (e.g. the current section which can be changed with `.section`) must be restored to its original value at the end of the asm string. Assembly code that does not conform to the GAS syntax will result in assembler-specific behavior. Further constraints on the directives used by inline assembly are indicated by [Directives Support](#directives-support). + +[format-syntax]: std::fmt#syntax +[rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795 + +r[asm.attributes] +## Attributes + +r[asm.attributes.supported-attributes] +Only the [`cfg`] and [`cfg_attr`] attributes are accepted semantically on inline assembly template strings and operands. Other attributes are parsed but rejected when the assembly macro is expanded. + +```rust +# fn main() {} +# #[cfg(target_arch = "x86_64")] +core::arch::global_asm!( + #[cfg(not(panic = "abort"))] + ".cfi_startproc", + // ... + "ret", + #[cfg(not(panic = "abort"))] + ".cfi_endproc", +); +``` + +> [!NOTE] +> In `rustc`, the assembly macros implement handling of these attributes separately from the normal system that handles similar attributes in the language. This accounts for the limited kinds of attributes supported and may give rise to subtle differences in behavior. + +r[asm.attributes.starts-with-template] +Syntactically there must be at least one template string before the first operand. + +```rust,compile_fail +// This is rejected because `a = out(reg) x` does not parse as a +// template string. +core::arch::asm!( + #[cfg(false)] + a = out(reg) x, // ERROR. + "", +); +``` + +[`cfg`]: conditional-compilation.md#the-cfg-attribute +[`cfg_attr`]: conditional-compilation.md#the-cfg_attr-attribute + +r[asm.operand-type] +## Operand type + +r[asm.operand-type.supported-operands] +Several types of operands are supported: + +r[asm.operand-type.supported-operands-in] +* `in(<reg>) <expr>` + - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string. + - The allocated register will contain the value of `<expr>` at the start of the assembly code. + - The allocated register must contain the same value at the end of the assembly code (except if a `lateout` is allocated to the same register). + +```rust +# #[cfg(target_arch = "x86_64")] { +// ``in` can be used to pass values into inline assembly... +unsafe { core::arch::asm!("/* {} */", in(reg) 5); } +# } +``` + +> [!NOTE] +> If the value's type is smaller than the register, the value of the upper bits is platform-specific. Some targets zero out the upper bits, while others leave them untouched. + +r[asm.operand-type.supported-operands-out] +* `out(<reg>) <expr>` + - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string. + - The allocated register will contain an undefined value at the start of the assembly code. + - `<expr>` must be a (possibly uninitialized) place expression, to which the contents of the allocated register are written at the end of the assembly code. + - An underscore (`_`) may be specified instead of an expression, which will cause the contents of the register to be discarded at the end of the assembly code (effectively acting as a clobber). + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i64; +// and `out` can be used to pass values back to rust. +unsafe { core::arch::asm!("/* {} */", out(reg) x); } +# } +``` + +r[asm.operand-type.supported-operands-lateout] +* `lateout(<reg>) <expr>` + - Identical to `out` except that the register allocator can reuse a register allocated to an `in`. + - You should only write to the register after all inputs are read, otherwise you may clobber an input. + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i64; +// `lateout` is the same as `out` +// but the compiler knows we don't care about the value of any inputs by the +// time we overwrite it. +unsafe { core::arch::asm!("mov {}, 5", lateout(reg) x); } +assert_eq!(x, 5) +# } +``` + +r[asm.operand-type.supported-operands-inout] +* `inout(<reg>) <expr>` + - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string. + - The allocated register will contain the value of `<expr>` at the start of the assembly code. + - `<expr>` must be a mutable initialized place expression, to which the contents of the allocated register are written at the end of the assembly code. + +```rust +# #[cfg(target_arch = "x86_64")] { +let mut x: i64 = 4; +// `inout` can be used to modify values in-register +unsafe { core::arch::asm!("inc {}", inout(reg) x); } +assert_eq!(x, 5); +# } +``` + +r[asm.operand-type.supported-operands-inout-arrow] +* `inout(<reg>) <in expr> => <out expr>` + - Same as `inout` except that the initial value of the register is taken from the value of `<in expr>`. + - `<out expr>` must be a (possibly uninitialized) place expression, to which the contents of the allocated register are written at the end of the assembly code. + - An underscore (`_`) may be specified instead of an expression for `<out expr>`, which will cause the contents of the register to be discarded at the end of the assembly code (effectively acting as a clobber). + - `<in expr>` and `<out expr>` may have different types. + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i64; +// `inout` can also move values to different places +unsafe { core::arch::asm!("inc {}", inout(reg) 4u64=>x); } +assert_eq!(x, 5); +# } +``` + +r[asm.operand-type.supported-operands-inlateout] +* `inlateout(<reg>) <expr>` / `inlateout(<reg>) <in expr> => <out expr>` + - Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`). + - You should only write to the register after all inputs are read, otherwise you may clobber an input. + +```rust +# #[cfg(target_arch = "x86_64")] { +let mut x: i64 = 4; +// `inlateout` is `inout` using `lateout` +unsafe { core::arch::asm!("inc {}", inlateout(reg) x); } +assert_eq!(x, 5); +# } +``` + +r[asm.operand-type.supported-operands-sym] +* `sym <path>` + - `<path>` must refer to a `fn` or `static`. + - A mangled symbol name referring to the item is substituted into the asm template string. + - The substituted string does not include any modifiers (e.g. GOT, PLT, relocations, etc). + - `<path>` is allowed to point to a `#[thread_local]` static, in which case the assembly code can combine the symbol with relocations (e.g. `@plt`, `@TPOFF`) to read from thread-local data. + +```rust +# #[cfg(target_arch = "x86_64")] { +extern "C" fn foo() { + println!("Hello from inline assembly") +} +// `sym` can be used to refer to a function (even if it doesn't have an +// external name we can directly write) +unsafe { core::arch::asm!("call {}", sym foo, clobber_abi("C")); } +# } +``` + +r[asm.operand-type.supported-operands-const] +* `const <expr>` + - `<expr>` must be an integer constant expression. This expression follows the same rules as inline `const` blocks. + - The type of the expression may be any integer type, but defaults to `i32` just like integer literals. + - The value of the expression is formatted as a string and substituted directly into the asm template string. + +```rust +# #[cfg(target_arch = "x86_64")] { +// swizzle [0, 1, 2, 3] => [3, 2, 0, 1] +const SHUFFLE: u8 = 0b01_00_10_11; +let x: core::arch::x86_64::__m128 = unsafe { core::mem::transmute([0u32, 1u32, 2u32, 3u32]) }; +let y: core::arch::x86_64::__m128; +// Pass a constant value into an instruction that expects an immediate like `pshufd` +unsafe { + core::arch::asm!("pshufd {xmm}, {xmm}, {shuffle}", + xmm = inlateout(xmm_reg) x=>y, + shuffle = const SHUFFLE + ); +} +let y: [u32; 4] = unsafe { core::mem::transmute(y) }; +assert_eq!(y, [3, 2, 0, 1]); +# } +``` + +r[asm.operand-type.supported-operands-label] +* `label <block>` + - The address of the block is substituted into the asm template string. The assembly code may jump to the substituted address. + - For targets that distinguish between direct jumps and indirect jumps (e.g. x86-64 with `cf-protection` enabled), the assembly code must not jump to the substituted address indirectly. + - After execution of the block, the `asm!` expression returns. + - The type of the block must be unit or `!` (never). + - The block starts a new safety context; unsafe operations within the `label` block must be wrapped in an inner `unsafe` block, even though the entire `asm!` expression is already wrapped in `unsafe`. + +```rust +# #[cfg(target_arch = "x86_64")] +unsafe { + core::arch::asm!("jmp {}", label { + println!("Hello from inline assembly label"); + }); +} +``` + +r[asm.operand-type.left-to-right] +Operand expressions are evaluated from left to right, just like function call arguments. After the `asm!` has executed, outputs are written to in left to right order. This is significant if two outputs point to the same place: that place will contain the value of the rightmost output. + +```rust +# #[cfg(target_arch = "x86_64")] { +let mut y: i64; +// y gets its value from the second output, rather than the first +unsafe { core::arch::asm!("mov {}, 0", "mov {}, 1", out(reg) y, out(reg) y); } +assert_eq!(y, 1); +# } +``` + +r[asm.operand-type.naked_asm-restriction] +Because `naked_asm!` defines a whole function body and the compiler cannot emit any additional code to handle operands, it can only use `sym` and `const` operands. + +r[asm.operand-type.global_asm-restriction] +Because `global_asm!` exists outside a function, it can only use `sym` and `const` operands. + +```rust,compile_fail +# fn main() {} +// register operands aren't allowed, since we aren't in a function +# #[cfg(target_arch = "x86_64")] +core::arch::global_asm!("", in(reg) 5); +// ERROR: the `in` operand cannot be used with `global_asm!` +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +```rust +# fn main() {} +fn foo() {} + +# #[cfg(target_arch = "x86_64")] +// `const` and `sym` are both allowed, however +core::arch::global_asm!("/* {} {} */", const 0, sym foo); +``` + +r[asm.register-operands] +## Register operands + +r[asm.register-operands.register-or-class] +Input and output operands can be specified either as an explicit register or as a register class from which the register allocator can select a register. Explicit registers are specified as string literals (e.g. `"eax"`) while register classes are specified as identifiers (e.g. `reg`). + +```rust +# #[cfg(target_arch = "x86_64")] { +let mut y: i64; +// We can name both `reg`, or an explicit register like `eax` to get an +// integer register +unsafe { core::arch::asm!("mov eax, {:e}", in(reg) 5, lateout("eax") y); } +assert_eq!(y, 5); +# } +``` + +r[asm.register-operands.equivalence-to-base-register] +Note that explicit registers treat register aliases (e.g. `r14` vs `lr` on ARM) and smaller views of a register (e.g. `eax` vs `rax`) as equivalent to the base register. + +r[asm.register-operands.error-two-operands] +It is a compile-time error to use the same explicit register for two input operands or two output operands. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// We can't name eax twice +unsafe { core::arch::asm!("", in("eax") 5, in("eax") 4); } +// ERROR: register `eax` conflicts with register `eax` +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// ... even using different aliases +unsafe { core::arch::asm!("", in("ax") 5, in("rax") 4); } +// ERROR: register `rax` conflicts with register `ax` +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.register-operands.error-overlapping] +Additionally, it is also a compile-time error to use overlapping registers (e.g. ARM VFP) in input operands or in output operands. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// al overlaps with ax, so we can't name both of them. +unsafe { core::arch::asm!("", in("ax") 5, in("al") 4i8); } +// ERROR: register `al` conflicts with register `ax` +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.register-operands.allowed-types] +Only the following types are allowed as operands for inline assembly: +- Integers (signed and unsigned) +- Floating-point numbers +- Pointers (thin only) +- Function pointers +- SIMD vectors (structs defined with `#[repr(simd)]` and which implement `Copy`). This includes architecture-specific vector types defined in `std::arch` such as `__m128` (x86) or `int8x16_t` (ARM). + +```rust +# #[cfg(target_arch = "x86_64")] { +extern "C" fn foo() {} + +// Integers are allowed... +let y: i64 = 5; +unsafe { core::arch::asm!("/* {} */", in(reg) y); } + +// and pointers... +let py = &raw const y; +unsafe { core::arch::asm!("/* {} */", in(reg) py); } + +// floats as well... +let f = 1.0f32; +unsafe { core::arch::asm!("/* {} */", in(xmm_reg) f); } + +// even function pointers and simd vectors. +let func: extern "C" fn() = foo; +unsafe { core::arch::asm!("/* {} */", in(reg) func); } + +let z = unsafe { core::arch::x86_64::_mm_set_epi64x(1, 0) }; +unsafe { core::arch::asm!("/* {} */", in(xmm_reg) z); } +# } +``` + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +struct Foo; +let x: Foo = Foo; +// Complex types like structs are not allowed +unsafe { core::arch::asm!("/* {} */", in(reg) x); } +// ERROR: cannot use value of type `Foo` for inline assembly +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.register-operands.supported-register-classes] +Here is the list of currently supported register classes: + +| Architecture | Register class | Registers | LLVM constraint code | +| ------------ | -------------- | --------- | -------------------- | +| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `bp`, `r[8-15]` (x86-64 only) | `r` | +| x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` | +| x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` | +| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `bpl`, `r[8-15]b` | `q` | +| x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` | +| x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` | +| x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` | +| x86 | `kreg` | `k[1-7]` | `Yk` | +| x86 | `kreg0` | `k0` | Only clobbers | +| x86 | `x87_reg` | `st([0-7])` | Only clobbers | +| x86 | `mmx_reg` | `mm[0-7]` | Only clobbers | +| x86-64 | `tmm_reg` | `tmm[0-7]` | Only clobbers | +| AArch64 | `reg` | `x[0-30]` | `r` | +| AArch64 | `vreg` | `v[0-31]` | `w` | +| AArch64 | `vreg_low16` | `v[0-15]` | `x` | +| AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers | +| Arm64EC | `reg` | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r` | +| Arm64EC | `vreg` | `v[0-15]` | `w` | +| Arm64EC | `vreg_low16` | `v[0-15]` | `x` | +| ARM (ARM/Thumb2) | `reg` | `r[0-12]`, `r14` | `r` | +| ARM (Thumb1) | `reg` | `r[0-7]` | `r` | +| ARM | `sreg` | `s[0-31]` | `t` | +| ARM | `sreg_low16` | `s[0-15]` | `x` | +| ARM | `dreg` | `d[0-31]` | `w` | +| ARM | `dreg_low16` | `d[0-15]` | `t` | +| ARM | `dreg_low8` | `d[0-8]` | `x` | +| ARM | `qreg` | `q[0-15]` | `w` | +| ARM | `qreg_low8` | `q[0-7]` | `t` | +| ARM | `qreg_low4` | `q[0-3]` | `x` | +| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` | +| RISC-V | `freg` | `f[0-31]` | `f` | +| RISC-V | `vreg` | `v[0-31]` | Only clobbers | +| LoongArch | `reg` | `$r1`, `$r[4-20]`, `$r[23,30]` | `r` | +| LoongArch | `freg` | `$f[0-31]` | `f` | +| s390x | `reg` | `r[0-10]`, `r[12-14]` | `r` | +| s390x | `reg_addr` | `r[1-10]`, `r[12-14]` | `a` | +| s390x | `freg` | `f[0-15]` | `f` | +| s390x | `vreg` | `v[0-31]` | `v` | +| s390x | `areg` | `a[2-15]` | Only clobbers | +| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | +| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | +| PowerPC | `spe_acc` | `spe_acc` | Only clobbers | +| PowerPC64 | `reg` | `r0`, `r[3-12]`, `r[14-29]` | `r` | +| PowerPC64 | `reg_nonzero` | `r[3-12]`, `r[14-29]` | `b` | +| PowerPC/PowerPC64 | `freg` | `f[0-31]` | `f` | +| PowerPC/PowerPC64 | `vreg` | `v[0-31]` | `v` | +| PowerPC/PowerPC64 | `vsreg` | `vs[0-63]` | `wa` | +| PowerPC/PowerPC64 | `cr` | `cr[0-7]`, `cr` | Only clobbers | +| PowerPC/PowerPC64 | `ctr` | `ctr` | Only clobbers | +| PowerPC/PowerPC64 | `lr` | `lr` | Only clobbers | +| PowerPC/PowerPC64 | `xer` | `xer` | Only clobbers | + +> [!NOTE] +> - On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register. +> - On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class. +> - Some register classes are marked as "Only clobbers" which means that registers in these classes cannot be used for inputs or outputs, only clobbers of the form `out(<explicit register>) _` or `lateout(<explicit register>) _`. +> - The `spe_acc` register is only available on PowerPC SPE targets. + +r[asm.register-operands.value-type-constraints] +Each register class has constraints on which value types they can be used with. This is necessary because the way a value is loaded into a register depends on its type. For example, on big-endian systems, loading a `i32x4` and a `i8x16` into a SIMD register may result in different register contents even if the byte-wise memory representation of both values is identical. The availability of supported types for a particular register class may depend on what target features are currently enabled. + +| Architecture | Register class | Target feature | Allowed types | +| ------------ | -------------- | -------------- | ------------- | +| x86-32 | `reg` | None | `i16`, `i32`, `f32` | +| x86-64 | `reg` | None | `i16`, `i32`, `f32`, `i64`, `f64` | +| x86 | `reg_byte` | None | `i8` | +| x86 | `xmm_reg` | `sse` | `i32`, `f32`, `i64`, `f64`, `i128`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| x86 | `ymm_reg` | `avx` | `i32`, `f32`, `i64`, `f64`, `i128`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` | +| x86 | `zmm_reg` | `avx512f` | `i32`, `f32`, `i64`, `f64`, `i128`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` <br> `i8x64`, `i16x32`, `i32x16`, `i64x8`, `f32x16`, `f64x8` | +| x86 | `kreg` | `avx512f` | `i8`, `i16` | +| x86 | `kreg` | `avx512bw` | `i32`, `i64` | +| x86 | `mmx_reg` | N/A | Only clobbers | +| x86 | `x87_reg` | N/A | Only clobbers | +| x86 | `tmm_reg` | N/A | Only clobbers | +| AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | +| AArch64 | `vreg` | `neon` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| AArch64 | `preg` | N/A | Only clobbers | +| Arm64EC | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | +| Arm64EC | `vreg` | `neon` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| ARM | `reg` | None | `i8`, `i16`, `i32`, `f32` | +| ARM | `sreg` | `vfp2` | `i32`, `f32` | +| ARM | `dreg` | `vfp2` | `i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2` | +| ARM | `qreg` | `neon` | `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4` | +| RISC-V32 | `reg` | None | `i8`, `i16`, `i32`, `f32` | +| RISC-V64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | +| RISC-V | `freg` | `f` | `f32` | +| RISC-V | `freg` | `d` | `f64` | +| RISC-V | `vreg` | N/A | Only clobbers | +| LoongArch32 | `reg` | None | `i8`, `i16`, `i32`, `f32` | +| LoongArch64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` | +| LoongArch | `freg` | `f` | `f32` | +| LoongArch | `freg` | `d` | `f64` | +| s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` | +| s390x | `freg` | None | `f32`, `f64` | +| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| s390x | `areg` | N/A | Only clobbers | +| PowerPC | `spe_acc` | None | Only clobbers | +| PowerPC/PowerPC64 | `reg` | None | `i8`, `i16`, `i32`, `i64` (PowerPC64 only) | +| PowerPC/PowerPC64 | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (PowerPC64 only) | +| PowerPC/PowerPC64 | `freg` | None | `f32`, `f64` | +| PowerPC/PowerPC64 | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` | +| PowerPC/PowerPC64 | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` | +| PowerPC/PowerPC64 | `vsreg` | `vsx` | The union of vsx and altivec vreg types | +| PowerPC/PowerPC64 | `cr` | None | Only clobbers | +| PowerPC/PowerPC64 | `ctr` | None | Only clobbers | +| PowerPC/PowerPC64 | `lr` | None | Only clobbers | +| PowerPC/PowerPC64 | `xer` | None | Only clobbers | + +> [!NOTE] +> For the purposes of the above table pointers, function pointers and `isize`/`usize` are treated as the equivalent integer type (`i16`/`i32`/`i64` depending on the target). + +```rust +# #[cfg(target_arch = "x86_64")] { +let x = 5i32; +let y = -1i8; +let z = unsafe { core::arch::x86_64::_mm_set_epi64x(1, 0) }; + +// reg is valid for `i32`, `reg_byte` is valid for `i8`, and xmm_reg is valid for `__m128i` +// We can't use `tmm0` as an input or output, but we can clobber it. +unsafe { core::arch::asm!("/* {} {} {} */", in(reg) x, in(reg_byte) y, in(xmm_reg) z, out("tmm0") _); } +# } +``` + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +let z = unsafe { core::arch::x86_64::_mm_set_epi64x(1, 0) }; +// We can't pass an `__m128i` to a `reg` input +unsafe { core::arch::asm!("/* {} */", in(reg) z); } +// ERROR: type `__m128i` cannot be used with this register class +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.register-operands.smaller-value] +If a value is of a smaller size than the register it is allocated in then the upper bits of that register will have an undefined value for inputs and will be ignored for outputs. The only exception is the `freg` register class on RISC-V where `f32` values are NaN-boxed in a `f64` as required by the RISC-V architecture. + +<!--no_run, this test has a non-deterministic runtime behavior--> +```rust,no_run +# #[cfg(target_arch = "x86_64")] { +let mut x: i64; +// Moving a 32-bit value into a 64-bit value, oops. +#[allow(asm_sub_register)] // rustc warns about this behavior +unsafe { core::arch::asm!("mov {}, {}", lateout(reg) x, in(reg) 4i32); } +// top 32-bits are indeterminate +assert_eq!(x, 4); // This assertion is not guaranteed to succeed +assert_eq!(x & 0xFFFFFFFF, 4); // However, this one will succeed +# } +``` + +r[asm.register-operands.separate-input-output] +When separate input and output expressions are specified for an `inout` operand, both expressions must have the same type. The only exception is if both operands are pointers or integers, in which case they are only required to have the same size. This restriction exists because the register allocators in LLVM and GCC sometimes cannot handle tied operands with different types. + +```rust +# #[cfg(target_arch = "x86_64")] { +// Pointers and integers can mix (as long as they are the same size) +let x: isize = 0; +let y: *mut (); +// Transmute an `isize` to a `*mut ()`, using inline assembly magic +unsafe { core::arch::asm!("/*{}*/", inout(reg) x=>y); } +assert!(y.is_null()); // Extremely roundabout way to make a null pointer +# } +``` + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +let x: i32 = 0; +let y: f32; +// But we can't reinterpret an `i32` to an `f32` like this +unsafe { core::arch::asm!("/* {} */", inout(reg) x=>y); } +// ERROR: incompatible types for asm inout argument +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.register-names] +## Register names + +r[asm.register-names.supported-register-aliases] +Some registers have multiple names. These are all treated by the compiler as identical to the base register name. Here is the list of all supported register aliases: + +| Architecture | Base register | Aliases | +| ------------ | ------------- | ------- | +| x86 | `ax` | `eax`, `rax` | +| x86 | `bx` | `ebx`, `rbx` | +| x86 | `cx` | `ecx`, `rcx` | +| x86 | `dx` | `edx`, `rdx` | +| x86 | `si` | `esi`, `rsi` | +| x86 | `di` | `edi`, `rdi` | +| x86 | `bp` | `bpl`, `ebp`, `rbp` | +| x86 | `sp` | `spl`, `esp`, `rsp` | +| x86 | `ip` | `eip`, `rip` | +| x86 | `st(0)` | `st` | +| x86 | `r[8-15]` | `r[8-15]b`, `r[8-15]w`, `r[8-15]d` | +| x86 | `xmm[0-31]` | `ymm[0-31]`, `zmm[0-31]` | +| AArch64 | `x[0-30]` | `w[0-30]` | +| AArch64 | `x29` | `fp` | +| AArch64 | `x30` | `lr` | +| AArch64 | `sp` | `wsp` | +| AArch64 | `xzr` | `wzr` | +| AArch64 | `v[0-31]` | `b[0-31]`, `h[0-31]`, `s[0-31]`, `d[0-31]`, `q[0-31]` | +| Arm64EC | `x[0-30]` | `w[0-30]` | +| Arm64EC | `x29` | `fp` | +| Arm64EC | `x30` | `lr` | +| Arm64EC | `sp` | `wsp` | +| Arm64EC | `xzr` | `wzr` | +| Arm64EC | `v[0-15]` | `b[0-15]`, `h[0-15]`, `s[0-15]`, `d[0-15]`, `q[0-15]` | +| ARM | `r[0-3]` | `a[1-4]` | +| ARM | `r[4-9]` | `v[1-6]` | +| ARM | `r9` | `rfp` | +| ARM | `r10` | `sl` | +| ARM | `r11` | `fp` | +| ARM | `r12` | `ip` | +| ARM | `r13` | `sp` | +| ARM | `r14` | `lr` | +| ARM | `r15` | `pc` | +| RISC-V | `x0` | `zero` | +| RISC-V | `x1` | `ra` | +| RISC-V | `x2` | `sp` | +| RISC-V | `x3` | `gp` | +| RISC-V | `x4` | `tp` | +| RISC-V | `x[5-7]` | `t[0-2]` | +| RISC-V | `x8` | `fp`, `s0` | +| RISC-V | `x9` | `s1` | +| RISC-V | `x[10-17]` | `a[0-7]` | +| RISC-V | `x[18-27]` | `s[2-11]` | +| RISC-V | `x[28-31]` | `t[3-6]` | +| RISC-V | `f[0-7]` | `ft[0-7]` | +| RISC-V | `f[8-9]` | `fs[0-1]` | +| RISC-V | `f[10-17]` | `fa[0-7]` | +| RISC-V | `f[18-27]` | `fs[2-11]` | +| RISC-V | `f[28-31]` | `ft[8-11]` | +| LoongArch | `$r0` | `$zero` | +| LoongArch | `$r1` | `$ra` | +| LoongArch | `$r2` | `$tp` | +| LoongArch | `$r3` | `$sp` | +| LoongArch | `$r[4-11]` | `$a[0-7]` | +| LoongArch | `$r[12-20]` | `$t[0-8]` | +| LoongArch | `$r21` | | +| LoongArch | `$r22` | `$fp`, `$s9` | +| LoongArch | `$r[23-31]` | `$s[0-8]` | +| LoongArch | `$f[0-7]` | `$fa[0-7]` | +| LoongArch | `$f[8-23]` | `$ft[0-15]` | +| LoongArch | `$f[24-31]` | `$fs[0-7]` | +| PowerPC/PowerPC64 | `r1` | `sp` | +| PowerPC/PowerPC64 | `r31` | `fp` | +| PowerPC/PowerPC64 | `r[0-31]` | `[0-31]` | +| PowerPC/PowerPC64 | `f[0-31]` | `fr[0-31]`| + +```rust +# #[cfg(target_arch = "x86_64")] { +let z = 0i64; +// rax is an alias for eax and ax +unsafe { core::arch::asm!("", in("rax") z); } +# } +``` + +r[asm.register-names.not-for-io] +Some registers cannot be used for input or output operands: + +| Architecture | Unsupported register | Reason | +| ------------ | -------------------- | ------ | +| All | `sp`, `r15` (s390x), `r1` (PowerPC and PowerPC64) | The stack pointer must be restored to its original value at the end of the assembly code or before jumping to a `label` block. | +| All | `bp` (x86), `x29` (AArch64 and Arm64EC), `x8` (RISC-V), `$fp` (LoongArch), `r11` (s390x), `fp` (PowerPC and PowerPC64) | The frame pointer cannot be used as an input or output. | +| ARM | `r7` or `r11` | On ARM the frame pointer can be either `r7` or `r11` depending on the target. The frame pointer cannot be used as an input or output. | +| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64 and Arm64EC), `x9` (RISC-V), `$s8` (LoongArch), `r29` and `r30` (PowerPC), `r30` (PowerPC64) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | +| x86 | `ip` | This is the program counter, not a real register. | +| AArch64 | `xzr` | This is a constant zero register which can't be modified. | +| AArch64 | `x18` | This is an OS-reserved register on some AArch64 targets. | +| Arm64EC | `xzr` | This is a constant zero register which can't be modified. | +| Arm64EC | `x18` | This is an OS-reserved register. | +| Arm64EC | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]`, `p[0-15]`, `ffr` | These are AArch64 registers that are not supported for Arm64EC. | +| ARM | `pc` | This is the program counter, not a real register. | +| ARM | `r9` | This is an OS-reserved register on some ARM targets. | +| RISC-V | `x0` | This is a constant zero register which can't be modified. | +| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. | +| LoongArch | `$r0` or `$zero` | This is a constant zero register which can't be modified. | +| LoongArch | `$r2` or `$tp` | This is reserved for TLS. | +| LoongArch | `$r21` | This is reserved by the ABI. | +| s390x | `c[0-15]` | Reserved by the kernel. | +| s390x | `a[0-1]` | Reserved for system use. | +| PowerPC/PowerPC64 | `r2`, `r13` | These are system reserved registers. | +| PowerPC/PowerPC64 | `vrsave` | The vrsave register cannot be used as an input or output. | + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// bp is reserved +unsafe { core::arch::asm!("", in("bp") 5i32); } +// ERROR: invalid register `bp`: the frame pointer cannot be used as an operand for inline asm +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.register-names.fp-bp-reserved] +The frame pointer and base pointer registers are reserved for internal use by LLVM. While `asm!` statements cannot explicitly specify the use of reserved registers, in some cases LLVM will allocate one of these reserved registers for `reg` operands. Assembly code making use of reserved registers should be careful since `reg` operands may use the same registers. + +r[asm.template-modifiers] +## Template modifiers + +r[asm.template-modifiers.intro] +The placeholders can be augmented by modifiers which are specified after the `:` in the curly braces. These modifiers do not affect register allocation, but change the way operands are formatted when inserted into the template string. + +r[asm.template-modifiers.only-one] +Only one modifier is allowed per template placeholder. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// We can't specify both `r` and `e` at the same time. +unsafe { core::arch::asm!("/* {:er}", in(reg) 5i32); } +// ERROR: asm template modifier must be a single character +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.template-modifiers.supported-modifiers] +The supported modifiers are a subset of LLVM's (and GCC's) [asm template argument modifiers][llvm-argmod], but do not use the same letter codes. + +| Architecture | Register class | Modifier | Example output | LLVM modifier | +| ------------ | -------------- | -------- | -------------- | ------------- | +| x86-32 | `reg` | None | `eax` | `k` | +| x86-64 | `reg` | None | `rax` | `q` | +| x86-32 | `reg_abcd` | `l` | `al` | `b` | +| x86-64 | `reg` | `l` | `al` | `b` | +| x86 | `reg_abcd` | `h` | `ah` | `h` | +| x86 | `reg` | `x` | `ax` | `w` | +| x86 | `reg` | `e` | `eax` | `k` | +| x86-64 | `reg` | `r` | `rax` | `q` | +| x86 | `reg_byte` | None | `al` / `ah` | None | +| x86 | `xmm_reg` | None | `xmm0` | `x` | +| x86 | `ymm_reg` | None | `ymm0` | `t` | +| x86 | `zmm_reg` | None | `zmm0` | `g` | +| x86 | `*mm_reg` | `x` | `xmm0` | `x` | +| x86 | `*mm_reg` | `y` | `ymm0` | `t` | +| x86 | `*mm_reg` | `z` | `zmm0` | `g` | +| x86 | `kreg` | None | `k1` | None | +| AArch64/Arm64EC | `reg` | None | `x0` | `x` | +| AArch64/Arm64EC | `reg` | `w` | `w0` | `w` | +| AArch64/Arm64EC | `reg` | `x` | `x0` | `x` | +| AArch64/Arm64EC | `vreg` | None | `v0` | None | +| AArch64/Arm64EC | `vreg` | `v` | `v0` | None | +| AArch64/Arm64EC | `vreg` | `b` | `b0` | `b` | +| AArch64/Arm64EC | `vreg` | `h` | `h0` | `h` | +| AArch64/Arm64EC | `vreg` | `s` | `s0` | `s` | +| AArch64/Arm64EC | `vreg` | `d` | `d0` | `d` | +| AArch64/Arm64EC | `vreg` | `q` | `q0` | `q` | +| ARM | `reg` | None | `r0` | None | +| ARM | `sreg` | None | `s0` | None | +| ARM | `dreg` | None | `d0` | `P` | +| ARM | `qreg` | None | `q0` | `q` | +| ARM | `qreg` | `e` / `f` | `d0` / `d1` | `e` / `f` | +| RISC-V | `reg` | None | `x1` | None | +| RISC-V | `freg` | None | `f0` | None | +| LoongArch | `reg` | None | `$r1` | None | +| LoongArch | `freg` | None | `$f0` | None | +| s390x | `reg` | None | `%r0` | None | +| s390x | `reg_addr` | None | `%r1` | None | +| s390x | `freg` | None | `%f0` | None | +| s390x | `vreg` | None | `%v0` | None | +| PowerPC/PowerPC64 | `reg` | None | `0` | None | +| PowerPC/PowerPC64 | `reg_nonzero` | None | `3` | None | +| PowerPC/PowerPC64 | `freg` | None | `0` | None | +| PowerPC/PowerPC64 | `vreg` | None | `0` | None | +| PowerPC/PowerPC64 | `vsreg` | None | `0` | None | + +> [!NOTE] +> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register. +> - on x86: our behavior for `reg` with no modifiers differs from what GCC does. GCC will infer the modifier based on the operand value type, while we default to the full register size. +> - on x86 `xmm_reg`: the `x`, `t` and `g` LLVM modifiers are not yet implemented in LLVM (they are supported by GCC only), but this should be a simple change. + +```rust +# #[cfg(target_arch = "x86_64")] { +let mut x = 0x10u16; + +// u16::swap_bytes using `xchg` +// low half of `{x}` is referred to by `{x:l}`, and the high half by `{x:h}` +unsafe { core::arch::asm!("xchg {x:l}, {x:h}", x = inout(reg_abcd) x); } +assert_eq!(x, 0x1000u16); +# } +``` + +r[asm.template-modifiers.smaller-value] +As stated in the previous section, passing an input value smaller than the register width will result in the upper bits of the register containing undefined values. This is not a problem if the inline asm only accesses the lower bits of the register, which can be done by using a template modifier to use a subregister name in the assembly code (e.g. `ax` instead of `rax`). Since this an easy pitfall, the compiler will suggest a template modifier to use where appropriate given the input type. If all references to an operand already have modifiers then the warning is suppressed for that operand. + +[llvm-argmod]: http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers + +r[asm.abi-clobbers] +## ABI clobbers + +r[asm.abi-clobbers.intro] +The `clobber_abi` keyword can be used to apply a default set of clobbers to the assembly code. This will automatically insert the necessary clobber constraints as needed for calling a function with a particular calling convention: if the calling convention does not fully preserve the value of a register across a call then `lateout("...") _` is implicitly added to the operands list (where the `...` is replaced by the register's name). + +```rust +# #[cfg(target_arch = "x86_64")] { +extern "C" fn foo() -> i32 { 0 } + +let z: i32; +// To call a function, we have to inform the compiler that we're clobbering +// callee saved registers +unsafe { core::arch::asm!("call {}", sym foo, out("rax") z, clobber_abi("C")); } +assert_eq!(z, 0); +# } +``` + +r[asm.abi-clobbers.many] +`clobber_abi` may be specified any number of times. It will insert a clobber for all unique registers in the union of all specified calling conventions. + +```rust +# #[cfg(target_arch = "x86_64")] { +extern "sysv64" fn foo() -> i32 { 0 } +extern "win64" fn bar(x: i32) -> i32 { x + 1 } + +let z: i32; +// We can even call multiple functions with different conventions and +// different saved registers +unsafe { + core::arch::asm!( + "call {}", + "mov ecx, eax", + "call {}", + sym foo, + sym bar, + out("rax") z, + clobber_abi("sysv64"), + clobber_abi("win64"), + ); +} +assert_eq!(z, 1); +# } +``` + +r[asm.abi-clobbers.must-specify] +Generic register class outputs are disallowed by the compiler when `clobber_abi` is used: all outputs must specify an explicit register. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +extern "C" fn foo(x: i32) -> i32 { 0 } + +let z: i32; +// explicit registers must be used to not accidentally overlap. +unsafe { + core::arch::asm!( + "mov eax, {:e}", + "call {}", + out(reg) z, + sym foo, + clobber_abi("C") + ); + // ERROR: asm with `clobber_abi` must specify explicit registers for outputs +} +assert_eq!(z, 0); +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.abi-clobbers.explicit-have-precedence] +Explicit register outputs have precedence over the implicit clobbers inserted by `clobber_abi`: a clobber will only be inserted for a register if that register is not used as an output. + +r[asm.abi-clobbers.supported-abis] +The following ABIs can be used with `clobber_abi`: + +| Architecture | ABI name | Clobbered registers | +| ------------ | -------- | ------------------- | +| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `k[0-7]`, `st([0-7])` | +| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])`, `tmm[0-7]` | +| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])`, `tmm[0-7]` | +| AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x18`\*, `x30`, `v[0-31]`, `p[0-15]`, `ffr` | +| Arm64EC | `"C"`, `"system"` | `x[0-12]`, `x[15-17]`, `x30`, `v[0-15]` | +| ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` | +| RISC-V | `"C"`, `"system"`, `"efiapi"` | `x1`, `x[5-7]`, `x[10-17]`\*, `x[28-31]`\*, `f[0-7]`, `f[10-17]`, `f[28-31]`, `v[0-31]` | +| LoongArch | `"C"`, `"system"` | `$r1`, `$r[4-20]`, `$f[0-23]` | +| s390x | `"C"`, `"system"` | `r[0-5]`, `r14`, `f[0-7]`, `v[0-31]`, `a[2-15]` | + +> [!NOTE] +> - On AArch64 `x18` only included in the clobber list if it is not considered as a reserved register on the target. +> - On RISC-V `x[16-17]` and `x[28-31]` only included in the clobber list if they are not considered as reserved registers on the target. + +The list of clobbered registers for each ABI is updated in rustc as architectures gain new registers: this ensures that `asm!` clobbers will continue to be correct when LLVM starts using these new registers in its generated code. + +r[asm.options] +## Options + +r[asm.options.supported-options] +Flags are used to further influence the behavior of the inline assembly code. Currently the following options are defined: + +r[asm.options.supported-options-pure] +- `pure`: The assembly code has no side effects, must eventually return, and its outputs depend only on its direct inputs (i.e. the values themselves, not what they point to) or values read from memory (unless the `nomem` options is also set). This allows the compiler to execute the assembly code fewer times than specified in the program (e.g. by hoisting it out of a loop) or even eliminate it entirely if the outputs are not used. The `pure` option must be combined with either the `nomem` or `readonly` options, otherwise a compile-time error is emitted. + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i32 = 0; +let z: i32; +// pure can be used to optimize by assuming the assembly has no side effects +unsafe { core::arch::asm!("inc {}", inout(reg) x => z, options(pure, nomem)); } +assert_eq!(z, 1); +# } +``` + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +let x: i32 = 0; +let z: i32; +// Either nomem or readonly must be satisfied, to indicate whether or not +// memory is allowed to be read +unsafe { core::arch::asm!("inc {}", inout(reg) x => z, options(pure)); } +// ERROR: the `pure` option must be combined with either `nomem` or `readonly` +assert_eq!(z, 0); +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.options.supported-options-nomem] +- `nomem`: The assembly code does not read from or write to any memory accessible outside of the assembly code. This allows the compiler to cache the values of modified global variables in registers across execution of the assembly code since it knows that they are not read from or written to by it. The compiler also assumes that the assembly code does not perform any kind of synchronization with other threads, e.g. via fences. + +<!-- no_run: This test has unpredictable or undefined behavior at runtime --> +```rust,no_run +# #[cfg(target_arch = "x86_64")] { +let mut x = 0i32; +let z: i32; +// Accessing outside memory from assembly when `nomem` is +// specified is disallowed +unsafe { + core::arch::asm!("mov {val:e}, dword ptr [{ptr}]", + ptr = in(reg) &mut x, + val = lateout(reg) z, + options(nomem) + ) +} + +// Writing to outside memory from assembly when `nomem` is +// specified is also undefined behaviour +unsafe { + core::arch::asm!("mov dword ptr [{ptr}], {val:e}", + ptr = in(reg) &mut x, + val = in(reg) z, + options(nomem) + ) +} +# } +``` + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i32 = 0; +let z: i32; +// If we allocate our own memory, such as via `push`, however. +// we can still use it +unsafe { + core::arch::asm!("push {x}", "add qword ptr [rsp], 1", "pop {x}", + x = inout(reg) x => z, + options(nomem) + ); +} +assert_eq!(z, 1); +# } +``` + +r[asm.options.supported-options-readonly] +- `readonly`: The assembly code does not write to any memory accessible outside of the assembly code. This allows the compiler to cache the values of unmodified global variables in registers across execution of the assembly code since it knows that they are not written to by it. The compiler also assumes that this assembly code does not perform any kind of synchronization with other threads, e.g. via fences. + +<!-- no_run: This test has undefined behaviour at runtime --> +```rust,no_run +# #[cfg(target_arch = "x86_64")] { +let mut x = 0; +// We cannot modify outside memory when `readonly` is specified +unsafe { + core::arch::asm!("mov dword ptr[{}], 1", in(reg) &mut x, options(readonly)) +} +# } +``` + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i64 = 0; +let z: i64; +// We can still read from it, though +unsafe { + core::arch::asm!("mov {x}, qword ptr [{x}]", + x = inout(reg) &x => z, + options(readonly) + ); +} +assert_eq!(z, 0); +# } +``` + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i64 = 0; +let z: i64; +// Same exception applies as with nomem. +unsafe { + core::arch::asm!("push {x}", "add qword ptr [rsp], 1", "pop {x}", + x = inout(reg) x => z, + options(readonly) + ); +} +assert_eq!(z, 1); +# } +``` + +r[asm.options.supported-options-preserves_flags] +- `preserves_flags`: The assembly code does not modify the flags register (defined in the rules below). This allows the compiler to avoid recomputing the condition flags after execution of the assembly code. + +r[asm.options.supported-options-noreturn] +- `noreturn`: The assembly code does not fall through; behavior is undefined if it does. It may still jump to `label` blocks. If any `label` blocks return unit, the `asm!` block will return unit. Otherwise it will return `!` (never). As with a call to a function that does not return, local variables in scope are not dropped before execution of the assembly code. + +<!-- no_run: This test aborts at runtime --> +```rust,no_run +fn main() -> ! { +# #[cfg(target_arch = "x86_64")] { + // We can use an instruction to trap execution inside of a noreturn block + unsafe { core::arch::asm!("ud2", options(noreturn)); } +# } +# #[cfg(not(target_arch = "x86_64"))] panic!("no return"); +} +``` + +<!-- no_run: Test has undefined behavior at runtime --> +```rust,no_run +# #[cfg(target_arch = "x86_64")] { +// You are responsible for not falling past the end of a noreturn asm block +unsafe { core::arch::asm!("", options(noreturn)); } +# } +``` + +```rust +# #[cfg(target_arch = "x86_64")] +let _: () = unsafe { + // You may still jump to a `label` block + core::arch::asm!("jmp {}", label { + println!(); + }, options(noreturn)); +}; +``` + +r[asm.options.supported-options-nostack] +- `nostack`: The assembly code does not push data to the stack, or write to the stack red-zone (if supported by the target). If this option is *not* used then the stack pointer is guaranteed by the compiler at the start of the assembly code to be suitably aligned (according to the target ABI) for a function call. + +<!-- no_run: Test has undefined behavior at runtime --> +```rust,no_run +# #[cfg(target_arch = "x86_64")] { +// `push` and `pop` are UB when used with nostack +unsafe { core::arch::asm!("push rax", "pop rax", options(nostack)); } +# } +``` + +r[asm.options.supported-options-att_syntax] +- `att_syntax`: This option is only valid on x86, and causes the assembler to use the `.att_syntax prefix` mode of the GNU assembler. Register operands are substituted in with a leading `%`. + +```rust +# #[cfg(target_arch = "x86_64")] { +let x: i32; +let y = 1i32; +// We need to use AT&T Syntax here. src, dest order for operands +unsafe { + core::arch::asm!("mov {y:e}, {x:e}", + x = lateout(reg) x, + y = in(reg) y, + options(att_syntax) + ); +} +assert_eq!(x, y); +# } +``` + +r[asm.options.supported-options-raw] +- `raw`: This causes the template string to be parsed as a raw assembly string, with no special handling for `{` and `}`. This is primarily useful when including raw assembly code from an external file using `include_str!`. + +r[asm.options.checks] +The compiler performs some additional checks on options: + +r[asm.options.checks-mutually-exclusive] +- The `nomem` and `readonly` options are mutually exclusive: it is a compile-time error to specify both. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// nomem is strictly stronger than readonly, they can't be specified together +unsafe { core::arch::asm!("", options(nomem, readonly)); } +// ERROR: the `nomem` and `readonly` options are mutually exclusive +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.options.checks-pure] +- It is a compile-time error to specify `pure` on an asm block with no outputs or only discarded outputs (`_`). + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +// pure blocks need at least one output +unsafe { core::arch::asm!("", options(pure)); } +// ERROR: asm with the `pure` option must have at least one output +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.options.checks-noreturn] +- It is a compile-time error to specify `noreturn` on an asm block with outputs and without labels. + +```rust,compile_fail +# #[cfg(target_arch = "x86_64")] { +let z: i32; +// noreturn can't have outputs +unsafe { core::arch::asm!("mov {:e}, 1", out(reg) z, options(noreturn)); } +// ERROR: asm outputs are not allowed with the `noreturn` option +# } +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.options.checks-label-with-outputs] +- It is a compile-time error to have any `label` blocks in an asm block with outputs. + +r[asm.options.naked_asm-restriction] +`naked_asm!` only supports the `att_syntax` and `raw` options. The remaining options are not meaningful because the inline assembly defines the whole function body. + +r[asm.options.global_asm-restriction] +`global_asm!` only supports the `att_syntax` and `raw` options. The remaining options are not meaningful for global-scope inline assembly. + +```rust,compile_fail +# fn main() {} +# #[cfg(target_arch = "x86_64")] +// nomem is useless on global_asm! +core::arch::global_asm!("", options(nomem)); +# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch"); +``` + +r[asm.rules] +## Rules for inline assembly + +r[asm.rules.intro] +To avoid undefined behavior, these rules must be followed when using function-scope inline assembly (`asm!`): + +r[asm.rules.reg-not-input] +- Any registers not specified as inputs will contain an undefined value on entry to the assembly code. + - An "undefined value" in the context of inline assembly means that the register can (non-deterministically) have any one of the possible values allowed by the architecture. Notably it is not the same as an LLVM `undef` which can have a different value every time you read it (since such a concept does not exist in assembly code). + +r[asm.rules.reg-not-output] +- Any registers not specified as outputs must have the same value upon exiting the assembly code as they had on entry, otherwise behavior is undefined. + - This only applies to registers which can be specified as an input or output. Other registers follow target-specific rules. + - Note that a `lateout` may be allocated to the same register as an `in`, in which case this rule does not apply. Code should not rely on this however since it depends on the results of register allocation. + +r[asm.rules.unwind] +- Behavior is undefined if execution unwinds out of the assembly code. + - This also applies if the assembly code calls a function which then unwinds. + +r[asm.rules.mem-same-as-ffi] +- The set of memory locations that assembly code is allowed to read and write are the same as those allowed for an FFI function. + - If the `readonly` option is set, then only memory reads are allowed. + - If the `nomem` option is set then no reads or writes to memory are allowed. + - These rules do not apply to memory which is private to the assembly code, such as stack space allocated within it. + +r[asm.rules.black-box] +- The compiler cannot assume that the instructions in the assembly code are the ones that will actually end up executed. + - This effectively means that the compiler must treat the assembly code as a black box and only take the interface specification into account, not the instructions themselves. + - Runtime code patching is allowed, via target-specific mechanisms. + - However there is no guarantee that each block of assembly code in the source directly corresponds to a single instance of instructions in the object file; the compiler is free to duplicate or deduplicate the assembly code in `asm!` blocks. + +r[asm.rules.stack-below-sp] +- Unless the `nostack` option is set, assembly code is allowed to use stack space below the stack pointer. + - On entry to the assembly code the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call. + - You are responsible for making sure you don't overflow the stack (e.g. use stack probing to ensure you hit a guard page). + - You should adjust the stack pointer when allocating stack memory as required by the target ABI. + - The stack pointer must be restored to its original value before leaving the assembly code. + +r[asm.rules.stack-above-sp] +- Unless the `nostack` option is set, assembly code is allowed to modify the caller's stack frame when the target ABI requires storing certain values in the caller's frame (e.g., when saving the `lr` on PowerPC64). + +r[asm.rules.noreturn] +- If the `noreturn` option is set then behavior is undefined if execution falls through the end of the assembly code. + +r[asm.rules.pure] +- If the `pure` option is set then behavior is undefined if the `asm!` has side-effects other than its direct outputs. Behavior is also undefined if two executions of the `asm!` code with the same inputs result in different outputs. + - When used with the `nomem` option, "inputs" are just the direct inputs of the `asm!`. + - When used with the `readonly` option, "inputs" comprise the direct inputs of the assembly code and any memory that it is allowed to read. + +r[asm.rules.preserved-registers] +- These flags registers must be restored upon exiting the assembly code if the `preserves_flags` option is set: + - x86 + - Status flags in `EFLAGS` (CF, PF, AF, ZF, SF, OF). + - Floating-point status word (all). + - Floating-point exception flags in `MXCSR` (PE, UE, OE, ZE, DE, IE). + - ARM + - Condition flags in `CPSR` (N, Z, C, V) + - Saturation flag in `CPSR` (Q) + - Greater than or equal flags in `CPSR` (GE). + - Condition flags in `FPSCR` (N, Z, C, V) + - Saturation flag in `FPSCR` (QC) + - Floating-point exception flags in `FPSCR` (IDC, IXC, UFC, OFC, DZC, IOC). + - AArch64 and Arm64EC + - Condition flags (`NZCV` register). + - Floating-point status (`FPSR` register). + - RISC-V + - Floating-point exception flags in `fcsr` (`fflags`). + - Vector extension state (`vtype`, `vl`, `vxsat`, and `vxrm`). + - LoongArch + - Floating-point condition flags in `$fcc[0-7]`. + - PowerPC/PowerPC64 + - Floating-point status and sticky bits in the `fpscr` (any field other than DRN, VE, OE, UE, ZE, XE, NI, or RN). + - Vector status and sticky bits in the `vscr` (any field other than NJ). + - PowerPC SPE + - The sticky and status bits of the `spefscr` (any field other than FINXE, FINVE, FDBZE, FUNFE, FOVFE, or FRMC). + - s390x + - The condition code register `cc`. + +r[asm.rules.x86-df] +- On x86, the direction flag (DF in `EFLAGS`) is clear on entry to the assembly code and must be clear on exit. + - Behavior is undefined if the direction flag is set on exiting the assembly code. + +r[asm.rules.x86-x87] +- On x86, the x87 floating-point register stack must remain unchanged unless all of the `st([0-7])` registers have been marked as clobbered with `out("st(0)") _, out("st(1)") _, ...`. + - If all x87 registers are clobbered then the x87 register stack is guaranteed to be empty upon entering the assembly code. Assembly code must ensure that the x87 register stack is also empty when exiting the assembly code. + +```rust +# #[cfg(target_arch = "x86_64")] +pub fn fadd(x: f64, y: f64) -> f64 { + let mut out = 0f64; + let mut top = 0u16; + // we can do complex stuff with x87 if we clobber the entire x87 stack + unsafe { core::arch::asm!( + "fld qword ptr [{x}]", + "fld qword ptr [{y}])", + "faddp", + "fstp qword ptr [{out}]", + "xor eax, eax", + "fstsw ax", + "shl eax, 11", + x = in(reg) &x, + y = in(reg) &y, + out = in(reg) &mut out, + out("st(0)") _, out("st(1)") _, out("st(2)") _, out("st(3)") _, + out("st(4)") _, out("st(5)") _, out("st(6)") _, out("st(7)") _, + out("eax") top + );} + + assert_eq!(top & 0x7, 0); + out +} + +pub fn main() { +# #[cfg(target_arch = "x86_64")]{ + assert_eq!(fadd(1.0, 1.0), 2.0); +# } +} +``` + +r[asm.rules.arm64ec] +- On arm64ec, [call checkers with appropriate thunks](https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi#authoring-arm64ec-in-assembly) are mandatory when calling functions. + +r[asm.rules.only-on-exit] +- The requirement of restoring the stack pointer and non-output registers to their original value only applies when exiting the assembly code. + - This means that assembly code that does not fall through and does not jump to any `label` blocks, even if not marked `noreturn`, doesn't need to preserve these registers. + - When returning to the assembly code of a different `asm!` block than you entered (e.g. for context switching), these registers must contain the value they had upon entering the `asm!` block that you are *exiting*. + - You cannot exit the assembly code of an `asm!` block that has not been entered. Neither can you exit the assembly code of an `asm!` block whose assembly code has already been exited (without first entering it again). + - You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds). + - You cannot jump from an address in one `asm!` block to an address in another, even within the same function or block, without treating their contexts as potentially different and requiring context switching. You cannot assume that any particular value in those contexts (e.g. current stack pointer or temporary values below the stack pointer) will remain unchanged between the two `asm!` blocks. + - The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited. + +r[asm.rules.not-successive] +- You cannot assume that two `asm!` blocks adjacent in source code, even without any other code between them, will end up in successive addresses in the binary without any other instructions between them. + +r[asm.rules.not-exactly-once] +- You cannot assume that an `asm!` block will appear exactly once in the output binary. The compiler is allowed to instantiate multiple copies of the `asm!` block, for example when the function containing it is inlined in multiple places. + +r[asm.rules.x86-prefix-restriction] +- On x86, inline assembly must not end with an instruction prefix (such as `LOCK`) that would apply to instructions generated by the compiler. + - The compiler is currently unable to detect this due to the way inline assembly is compiled, but may catch and reject this in the future. + +r[asm.rules.preserves_flags] +> [!NOTE] +> As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call. + +r[asm.naked-rules] +## Rules for naked inline assembly + +r[asm.naked-rules.intro] +To avoid undefined behavior, these rules must be followed when using function-scope inline assembly in naked functions (`naked_asm!`): + +r[asm.naked-rules.reg-not-input] +- Any registers not used for function inputs according to the calling convention and function signature will contain an undefined value on entry to the `naked_asm!` block. + - An "undefined value" in the context of inline assembly means that the register can (non-deterministically) have any one of the possible values allowed by the architecture. Notably it is not the same as an LLVM `undef` which can have a different value every time you read it (since such a concept does not exist in assembly code). + +r[asm.naked-rules.callee-saved-registers] +- All callee-saved registers must have the same value upon return as they had on entry. + +r[asm.naked-rules.caller-saved-registers] +- Caller-saved registers may be used freely. + +r[asm.naked-rules.noreturn] +- Behavior is undefined if execution falls through past the end of the assembly code. + - Every path through the assembly code is expected to terminate with a return instruction or to diverge. + +r[asm.naked-rules.mem-same-as-ffi] +- The set of memory locations that assembly code is allowed to read and write are the same as those allowed for an FFI function. + +r[asm.naked-rules.black-box] +- The compiler cannot assume that the instructions in the `naked_asm!` block are the ones that will actually be executed. + - This effectively means that the compiler must treat the `naked_asm!` as a black box and only take the interface specification into account, not the instructions themselves. + - Runtime code patching is allowed, via target-specific mechanisms. + +r[asm.naked-rules.unwind] +- Unwinding out of a `naked_asm!` block is allowed. + - For correct behavior, the appropriate assembler directives that emit unwinding metadata must be used. + +```rust +# #[cfg(target_arch = "x86_64")] { +#[unsafe(naked)] +extern "sysv64-unwind" fn unwinding_naked() { + core::arch::naked_asm!( + // "CFI" here stands for "call frame information". + ".cfi_startproc", + // The CFA (canonical frame address) is the value of `rsp` + // before the `call`, i.e. before the return address, `rip`, + // was pushed to `rsp`, so it's eight bytes higher in memory + // than `rsp` upon function entry (after `rip` has been + // pushed). + // + // This is the default, so we don't have to write it. + //".cfi_def_cfa rsp, 8", + // + // The traditional thing to do is to preserve the base + // pointer, so we'll do that. + "push rbp", + // Since we've now extended the stack downward by 8 bytes in + // memory, we need to adjust the offset to the CFA from `rsp` + // by another 8 bytes. + ".cfi_adjust_cfa_offset 8", + // We also then annotate where we've stored the caller's value + // of `rbp`, relative to the CFA, so that when unwinding into + // the caller we can find it, in case we need it to calculate + // the caller's CFA relative to it. + // + // Here, we've stored the caller's `rbp` starting 16 bytes + // below the CFA. I.e., starting from the CFA, there's first + // the `rip` (which starts 8 bytes below the CFA and continues + // up to it), then there's the caller's `rbp` that we just + // pushed. + ".cfi_offset rbp, -16", + // As is traditional, we set the base pointer to the value of + // the stack pointer. This way, the base pointer stays the + // same throughout the function body. + "mov rbp, rsp", + // We can now track the offset to the CFA from the base + // pointer. This means we don't need to make any further + // adjustments until the end, as we don't change `rbp`. + ".cfi_def_cfa_register rbp", + // We can now call a function that may panic. + "call {f}", + // Upon return, we restore `rbp` in preparation for returning + // ourselves. + "pop rbp", + // Now that we've restored `rbp`, we must specify the offset + // to the CFA again in terms of `rsp`. + ".cfi_def_cfa rsp, 8", + // Now we can return. + "ret", + ".cfi_endproc", + f = sym may_panic, + ) +} + +extern "sysv64-unwind" fn may_panic() { + panic!("unwind"); +} +# } +``` + +> [!NOTE] +> +> For more information on the `cfi` assembler directives above, see these resources: +> +> - [Using `as` - CFI directives](https://sourceware.org/binutils/docs/as/CFI-directives.html) +> - [DWARF Debugging Information Format Version 5](https://dwarfstd.org/doc/DWARF5.pdf) +> - [ImperialViolet - CFI directives in assembly files](https://www.imperialviolet.org/2017/01/18/cfi.html) + +r[asm.validity] +### Correctness and validity + +r[asm.validity.necessary-but-not-sufficient] +In addition to all of the previous rules, the string argument to `asm!` must ultimately become---after all other arguments are evaluated, formatting is performed, and operands are translated---assembly that is both syntactically correct and semantically valid for the target architecture. The formatting rules allow the compiler to generate assembly with correct syntax. Rules concerning operands permit valid translation of Rust operands into and out of the assembly code. Adherence to these rules is necessary, but not sufficient, for the final expanded assembly to be both correct and valid. For instance: + +- arguments may be placed in positions which are syntactically incorrect after formatting +- an instruction may be correctly written, but given architecturally invalid operands +- an architecturally unspecified instruction may be assembled into unspecified code +- a set of instructions, each correct and valid, may cause undefined behavior if placed in immediate succession + +r[asm.validity.non-exhaustive] +As a result, these rules are _non-exhaustive_. The compiler is not required to check the correctness and validity of the initial string nor the final assembly that is generated. The assembler may check for correctness and validity but is not required to do so. When using `asm!`, a typographical error may be sufficient to make a program unsound, and the rules for assembly may include thousands of pages of architectural reference manuals. Programmers should exercise appropriate care, as invoking this `unsafe` capability comes with assuming the responsibility of not violating rules of both the compiler or the architecture. + +r[asm.directives] +### Directives support + +r[asm.directives.subset-supported] +Inline assembly supports a subset of the directives supported by both GNU AS and LLVM's internal assembler, given as follows. The result of using other directives is assembler-specific (and may cause an error, or may be accepted as-is). + +r[asm.directives.stateful] +If inline assembly includes any "stateful" directive that modifies how subsequent assembly is processed, the assembly code must undo the effects of any such directives before the inline assembly ends. + +r[asm.directives.supported-directives] +The following directives are guaranteed to be supported by the assembler: + +- `.2byte` +- `.4byte` +- `.8byte` +- `.align` +- `.alt_entry` +- `.ascii` +- `.asciz` +- `.balign` +- `.balignl` +- `.balignw` +- `.bss` +- `.byte` +- `.comm` +- `.data` +- `.def` +- `.double` +- `.endef` +- `.equ` +- `.equiv` +- `.eqv` +- `.fill` +- `.float` +- `.global` +- `.globl` +- `.inst` +- `.insn` +- `.lcomm` +- `.long` +- `.octa` +- `.option` +- `.p2align` +- `.popsection` +- `.private_extern` +- `.pushsection` +- `.quad` +- `.scl` +- `.section` +- `.set` +- `.short` +- `.size` +- `.skip` +- `.sleb128` +- `.space` +- `.string` +- `.text` +- `.type` +- `.uleb128` +- `.word` + +```rust +# #[cfg(target_arch = "x86_64")] { +let bytes: *const u8; +let len: usize; +unsafe { + core::arch::asm!( + "jmp 3f", "2: .ascii \"Hello World!\"", + "3: lea {bytes}, [2b+rip]", + "mov {len}, 12", + bytes = out(reg) bytes, + len = out(reg) len + ); +} + +let s = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(bytes, len)) }; + +assert_eq!(s, "Hello World!"); +# } +``` + +r[asm.target-specific-directives] +#### Target specific directive support + +r[asm.target-specific-directives.dwarf-unwinding] +##### Dwarf unwinding + +The following directives are supported on ELF targets that support DWARF unwind info: + +- `.cfi_adjust_cfa_offset` +- `.cfi_def_cfa` +- `.cfi_def_cfa_offset` +- `.cfi_def_cfa_register` +- `.cfi_endproc` +- `.cfi_escape` +- `.cfi_lsda` +- `.cfi_offset` +- `.cfi_personality` +- `.cfi_register` +- `.cfi_rel_offset` +- `.cfi_remember_state` +- `.cfi_restore` +- `.cfi_restore_state` +- `.cfi_return_column` +- `.cfi_same_value` +- `.cfi_sections` +- `.cfi_signal_frame` +- `.cfi_startproc` +- `.cfi_undefined` +- `.cfi_window_save` + +r[asm.target-specific-directives.structured-exception-handling] +##### Structured exception handling + +On targets with structured exception Handling, the following additional directives are guaranteed to be supported: + +- `.seh_endproc` +- `.seh_endprologue` +- `.seh_proc` +- `.seh_pushreg` +- `.seh_savereg` +- `.seh_setframe` +- `.seh_stackalloc` + +r[asm.target-specific-directives.x86] +##### x86 (32-bit and 64-bit) + +On x86 targets, both 32-bit and 64-bit, the following additional directives are guaranteed to be supported: +- `.nops` +- `.code16` +- `.code32` +- `.code64` + +Use of `.code16`, `.code32`, and `.code64` directives are only supported if the state is reset to the default before exiting the assembly code. 32-bit x86 uses `.code32` by default, and x86_64 uses `.code64` by default. + +r[asm.target-specific-directives.arm-32-bit] +##### ARM (32-bit) + +On ARM, the following additional directives are guaranteed to be supported: + +- `.even` +- `.fnstart` +- `.fnend` +- `.save` +- `.movsp` +- `.code` +- `.thumb` +- `.thumb_func` diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/input-format.md b/stdlib/kvlang/reference/rust/reference-repo/src/input-format.md new file mode 100644 index 00000000..88ab3658 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/input-format.md @@ -0,0 +1,64 @@ +r[input] +# Input format + +r[input.syntax] +```grammar,lexer +CHAR -> [U+0000-U+D7FF U+E000-U+10FFFF] // a Unicode scalar value + +ASCII -> [U+0000-U+007F] + +NUL -> U+0000 + +EOF -> !CHAR // End of file or input +``` + +r[input.intro] +This chapter describes how a source file is interpreted as a sequence of tokens. + +See [Crates and source files] for a description of how programs are organised into files. + +r[input.encoding] +## Source encoding + +r[input.encoding.utf8] +Each source file is interpreted as a sequence of Unicode characters encoded in UTF-8. + +r[input.encoding.invalid] +It is an error if the file is not valid UTF-8. + +r[input.byte-order-mark] +## Byte order mark removal + +If the first character in the sequence is `U+FEFF` ([BYTE ORDER MARK]), it is removed. + +r[input.crlf] +## CRLF normalization + +Each pair of characters `U+000D` (CR) immediately followed by `U+000A` (LF) is replaced by a single `U+000A` (LF). This happens once, not repeatedly, so after the normalization, there can still exist `U+000D` (CR) immediately followed by `U+000A` (LF) in the input (e.g. if the raw input contained "CR CR LF LF"). + +Other occurrences of the character `U+000D` (CR) are left in place (they are treated as [whitespace]). + +r[input.shebang] +## Shebang removal + +r[input.shebang.removal] +If a [shebang] is present, it is removed from the input sequence (and is therefore ignored). + +r[input.tokenization] +## Tokenization + +The resulting sequence of characters is then converted into tokens as described in the remainder of this chapter. + +> [!NOTE] +> The standard library [`include!`] macro applies the following transformations to the file it reads: +> +> - Byte order mark removal. +> - CRLF normalization. +> - Shebang removal when invoked in an item context (as opposed to expression or statement contexts). +> +> The [`include_str!`] and [`include_bytes!`] macros do not apply these transformations. + +[BYTE ORDER MARK]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 +[Crates and source files]: crates-and-source-files.md +[shebang]: shebang.md +[whitespace]: whitespace.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/interior-mutability.md b/stdlib/kvlang/reference/rust/reference-repo/src/interior-mutability.md new file mode 100644 index 00000000..7748ea20 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/interior-mutability.md @@ -0,0 +1,29 @@ +r[interior-mut] +# Interior mutability + +r[interior-mut.intro] +Sometimes a type needs to be mutated while having multiple aliases. In Rust this is achieved using a pattern called _interior mutability_. + +r[interior-mut.shared-ref] +A type has interior mutability if its internal state can be changed through a [shared reference] to it. + +r[interior-mut.no-constraint] +This goes against the usual [requirement][ub] that the value pointed to by a shared reference is not mutated. + +r[interior-mut.unsafe-cell] +[`std::cell::UnsafeCell<T>`] type is the only allowed way to disable this requirement. When `UnsafeCell<T>` is immutably aliased, it is still safe to mutate, or obtain a mutable reference to, the `T` it contains. + +r[interior-mut.mut-unsafe-cell] +As with all other types, it is undefined behavior to have multiple `&mut UnsafeCell<T>` aliases. + +r[interior-mut.abstraction] +Other types with interior mutability can be created by using `UnsafeCell<T>` as a field. The standard library provides a variety of types that provide safe interior mutability APIs. + +r[interior-mut.ref-cell] +For example, [`std::cell::RefCell<T>`] uses run-time borrow checks to ensure the usual rules around multiple references. + +r[interior-mut.atomic] +The [`std::sync::atomic`] module contains types that wrap a value that is only accessed with atomic operations, allowing the value to be shared and mutated across threads. + +[shared reference]: types/pointer.md#shared-references- +[ub]: behavior-considered-undefined.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/introduction.md b/stdlib/kvlang/reference/rust/reference-repo/src/introduction.md new file mode 100644 index 00000000..d44f1b07 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/introduction.md @@ -0,0 +1,144 @@ +# Introduction + +This book is the primary reference for the Rust programming language. + +> [!NOTE] +> For known bugs and omissions in this book, see our [GitHub issues]. If you see a case where the compiler behavior and the text here do not agree, file an issue so we can think about which is correct. + +## Rust releases + +Rust has a new language release every six weeks. +The first stable release of the language was Rust 1.0.0, followed by Rust 1.1.0 and so on. +Tools (`rustc`, `cargo`, etc.) and documentation ([Standard library], this book, etc.) are released with the language release. + +The latest release of this book, matching the latest Rust version, can always be found at <https://doc.rust-lang.org/reference/>. +Prior versions can be found by adding the Rust version before the "reference" directory. +For example, the Reference for Rust 1.49.0 is located at <https://doc.rust-lang.org/1.49.0/reference/>. + +## What *The Reference* is not + +This book does not serve as an introduction to the language. +Background familiarity with the language is assumed. +A separate [book] is available to help acquire such background familiarity. + +This book also does not serve as a reference to the [standard library] included in the language distribution. +Those libraries are documented separately by extracting documentation attributes from their source code. +Many of the features that one might expect to be language features are library features in Rust, so what you're looking for may be there, not here. + +Similarly, this book does not usually document the specifics of `rustc` as a tool or of Cargo. +`rustc` has its own [book][rustc book]. +Cargo has a [book][cargo book] that contains a [reference][cargo reference]. +There are a few pages such as [linkage] that still describe how `rustc` works. + +This book also only serves as a reference to what is available in stable Rust. +For unstable features being worked on, see the [Unstable Book]. + +Rust compilers, including `rustc`, will perform optimizations. +The reference does not specify what optimizations are allowed or disallowed. +Instead, think of the compiled program as a black box. +You can only probe by running it, feeding it input and observing its output. +Everything that happens that way must conform to what the reference says. + +## How to use this book + +This book does not assume you are reading this book sequentially. +Each chapter generally can be read standalone, but will cross-link to other chapters for facets of the language they refer to, but do not discuss. + +There are two main ways to read this document. + +The first is to answer a specific question. +If you know which chapter answers that question, you can jump to that chapter in the table of contents. +Otherwise, you can press `s` or click the magnifying glass on the top bar to search for keywords related to your question. +For example, say you wanted to know when a temporary value created in a let statement is dropped. +If you didn't already know that the [lifetime of temporaries] is defined in the [expressions chapter], you could search "temporary let" and the first search result will take you to that section. + +The second is to generally improve your knowledge of a facet of the language. +In that case, just browse the table of contents until you see something you want to know more about, and just start reading. +If a link looks interesting, click it, and read about that section. + +That said, there is no wrong way to read this book. Read it however you feel helps you best. + +### Conventions + +Like all technical books, this book has certain conventions in how it displays information. +These conventions are documented here. + +* Statements that define a term contain that term in *italics*. + Whenever that term is used outside of that chapter, it is usually a link to the section that has this definition. + + An *example term* is an example of a term being defined. + +* The main text describes the latest stable edition. Differences to previous editions are separated in edition blocks: + + > [!EDITION-2018] + > Before the 2018 edition, the behavior was this. As of the 2018 edition, the behavior is that. + +* Notes that contain useful information about the state of the book or point out useful, but mostly out of scope, information are in note blocks. + + > [!NOTE] + > This is an example note. + +* Example blocks show an example that demonstrates some rule or points out some interesting aspect. Some examples may have hidden lines which can be viewed by clicking the eye icon that appears when hovering or tapping the example. + + > [!EXAMPLE] + > This is a code example. + > ```rust + > println!("hello world"); + > ``` + +* Warnings that show unsound behavior in the language or possibly confusing interactions of language features are in a special warning box. + + > [!WARNING] + > This is an example warning. + +* Code snippets inline in the text are inside `<code>` tags. + + Longer code examples are in a syntax highlighted box that has controls for copying, executing, and showing hidden lines in the top right corner. + + ```rust + # // This is a hidden line. + fn main() { + println!("This is a code example"); + } + ``` + + All examples are written for the latest edition unless otherwise stated. + +* The grammar and lexical productions are described in the [Notation] chapter. + +r[example.rule.label] +* Rule identifiers appear before each language rule enclosed in square brackets. These identifiers provide a way to refer to and link to a specific rule in the language ([e.g.][example rule]). The rule identifier uses periods to separate sections from most general to most specific ([destructors.scope.nesting-function-body] for example). On narrow screens, the rule name will collapse to display `[*]`. + + The rule name can be clicked to link to that rule. + + > [!WARNING] + > The organization of the rules is currently in flux. For the time being, these identifier names are not stable between releases, and links to these rules may fail if they are changed. We intend to stabilize these once the organization has settled so that links to the rule names will not break between releases. + +* Rules that have associated tests will include a `Tests` link below them (on narrow screens, the link is `[T]`). Clicking the link will pop up a list of tests, which can be clicked to view the test. For example, see [input.encoding.utf8]. + + Linking rules to tests is an ongoing effort. See the [Test summary](test-summary.md) chapter for an overview. + +## Contributing + +We welcome contributions of all kinds. + +You can contribute to this book by opening an issue or sending a pull request to [the Rust Reference repository]. +If this book does not answer your question, and you think its answer is in scope of it, please do not hesitate to [file an issue] or ask about it in the `t-lang/doc` stream on [Zulip]. +Knowing what people use this book for the most helps direct our attention to making those sections the best that they can be. +And of course, if you see anything that is wrong or is non-normative but not specifically called out as such, please also [file an issue]. + +[book]: ../book/index.html +[github issues]: https://github.com/rust-lang/reference/issues +[standard library]: std +[the Rust Reference repository]: https://github.com/rust-lang/reference/ +[Unstable Book]: https://doc.rust-lang.org/nightly/unstable-book/ +[cargo book]: ../cargo/index.html +[cargo reference]: ../cargo/reference/index.html +[example rule]: example.rule.label +[expressions chapter]: expressions.html +[file an issue]: https://github.com/rust-lang/reference/issues +[lifetime of temporaries]: expressions.html#temporaries +[linkage]: linkage.html +[rustc book]: ../rustc/index.html +[Notation]: notation.md +[Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/237824-t-lang.2Fdoc diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items.md b/stdlib/kvlang/reference/rust/reference-repo/src/items.md new file mode 100644 index 00000000..1f81e10c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items.md @@ -0,0 +1,93 @@ +r[items] +# Items + +r[items.syntax] +```grammar,items +Item -> + OuterAttribute* ( VisItem | MacroItem ) + +VisItem -> + Visibility? + ( + Module + | ExternCrate + | UseDeclaration + | Function + | TypeAlias + | Struct + | Enumeration + | Union + | ConstantItem + | StaticItem + | Trait + | Implementation + | ExternBlock + ) + +MacroItem -> + MacroInvocationSemi + | MacroRulesDefinition +``` + +r[items.intro] +An _item_ is a component of a crate. Items are organized within a crate by a nested set of [modules]. Every crate has a single "outermost" anonymous module; all further items within the crate have [paths] within the module tree of the crate. + +r[items.static-def] +Items are entirely determined at compile-time, generally remain fixed during execution, and may reside in read-only memory. + +r[items.kinds] +There are several kinds of items: + +* [modules] +* [`extern crate` declarations] +* [`use` declarations] +* [function definitions] +* [type alias definitions] +* [struct definitions] +* [enumeration definitions] +* [union definitions] +* [constant items] +* [static items] +* [trait definitions] +* [implementations] +* [`extern` blocks] + +r[items.locations] +Items may be declared in the [root of the crate], a [module][modules], or a [block expression]. + +r[items.associated-locations] +A subset of items, called [associated items], may be declared in [traits] and [implementations]. + +r[items.extern-locations] +A subset of items, called external items, may be declared in [`extern` blocks]. + +r[items.decl-order] +Items may be defined in any order, with the exception of [`macro_rules`] which has its own scoping behavior. + +r[items.name-resolution] +[Name resolution] of item names allows items to be defined before or after where the item is referred to in the module or block. + +See [item scopes] for information on the scoping rules of items. + +[`extern crate` declarations]: items/extern-crates.md +[`extern` blocks]: items/external-blocks.md +[`macro_rules`]: macros-by-example.md +[`use` declarations]: items/use-declarations.md +[associated items]: items/associated-items.md +[block expression]: expressions/block-expr.md +[constant items]: items/constant-items.md +[enumeration definitions]: items/enumerations.md +[function definitions]: items/functions.md +[implementations]: items/implementations.md +[item scopes]: names/scopes.md#item-scopes +[modules]: items/modules.md +[name resolution]: names/name-resolution.md +[paths]: paths.md +[root of the crate]: crates-and-source-files.md +[statement]: statements.md +[static items]: items/static-items.md +[struct definitions]: items/structs.md +[trait definitions]: items/traits.md +[traits]: items/traits.md +[type alias definitions]: items/type-aliases.md +[union definitions]: items/unions.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/associated-items.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/associated-items.md new file mode 100644 index 00000000..7bcfa5b0 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/associated-items.md @@ -0,0 +1,514 @@ +r[items.associated] +# Associated items + +r[items.associated.syntax] +```grammar,items +AssociatedItem -> + OuterAttribute* ( + MacroInvocationSemi + | ( Visibility? ( TypeAlias | ConstantItem | Function ) ) + ) +``` + +r[items.associated.intro] +*Associated Items* are the items declared in [traits] or defined in [implementations]. They are called this because they are defined on an associate type — the type in the implementation. + +r[items.associated.kinds] +They are a subset of the kinds of items you can declare in a module. Specifically, there are [associated functions] (including methods), [associated types], and [associated constants]. + +[associated functions]: #associated-functions-and-methods +[associated types]: #associated-types +[associated constants]: #associated-constants + +r[items.associated.related] +Associated items are useful when the associated item is logically related to the associating item. For example, the `is_some` method on `Option` is intrinsically related to Options, so should be associated. + +r[items.associated.decl-def] +Every associated item kind comes in two varieties: definitions that contain the actual implementation and declarations that declare signatures for definitions. + +r[items.associated.trait-items] +It is the declarations that make up the contract of traits and what is available on generic types. + +r[items.associated.fn] +## Associated functions and methods + +r[items.associated.fn.intro] +*Associated functions* are [functions] associated with a type. + +r[items.associated.fn.decl] +An *associated function declaration* declares a signature for an associated function definition. It is written as a function item, except the function body is replaced with a `;`. + +r[items.associated.name] +The identifier is the name of the function. + +r[items.associated.same-signature] +The generics, parameter list, return type, and where clause of the associated function must be the same as the associated function declarations's. + +r[items.associated.fn.def] +An *associated function definition* defines a function associated with another type. It is written the same as a [function item]. + +> [!NOTE] +> A common example is an associated function named `new` that returns a value of the type with which it is associated. + +```rust +struct Struct { + field: i32 +} + +impl Struct { + fn new() -> Struct { + Struct { + field: 0i32 + } + } +} + +fn main () { + let _struct = Struct::new(); +} +``` + +r[items.associated.fn.qualified-self] +When the associated function is declared on a trait, the function can also be called with a [path] that is a path to the trait appended by the name of the trait. When this happens, it is substituted for `<_ as Trait>::function_name`. + +```rust +trait Num { + fn from_i32(n: i32) -> Self; +} + +impl Num for f64 { + fn from_i32(n: i32) -> f64 { n as f64 } +} + +// These 4 are all equivalent in this case. +let _: f64 = Num::from_i32(42); +let _: f64 = <_ as Num>::from_i32(42); +let _: f64 = <f64 as Num>::from_i32(42); +let _: f64 = f64::from_i32(42); +``` + +r[items.associated.fn.method] +### Methods + +r[items.associated.fn.method.intro] +Associated functions whose first parameter is named `self` are called *methods* and may be invoked using the [method call operator], for example, `x.foo()`, as well as the usual function call notation. + +r[items.associated.fn.method.self-ty] +If the type of the `self` parameter is specified, it is limited to types resolving to one generated by the following grammar (where `'lt` denotes some arbitrary lifetime): + +```text +P = &'lt S | &'lt mut S | Box<S> | Rc<S> | Arc<S> | Pin<P> +S = Self | P +``` + +The `Self` terminal in this grammar denotes a type resolving to the implementing type. This can also include the contextual type alias `Self`, other type aliases, or associated type projections resolving to the implementing type. + +```rust +# use std::rc::Rc; +# use std::sync::Arc; +# use std::pin::Pin; +// Examples of methods implemented on struct `Example`. +struct Example; +type Alias = Example; +trait Trait { type Output; } +impl Trait for Example { type Output = Example; } +impl Example { + fn by_value(self: Self) {} + fn by_ref(self: &Self) {} + fn by_ref_mut(self: &mut Self) {} + fn by_box(self: Box<Self>) {} + fn by_rc(self: Rc<Self>) {} + fn by_arc(self: Arc<Self>) {} + fn by_pin(self: Pin<&Self>) {} + fn explicit_type(self: Arc<Example>) {} + fn with_lifetime<'a>(self: &'a Self) {} + fn nested<'a>(self: &mut &'a Arc<Rc<Box<Alias>>>) {} + fn via_projection(self: <Example as Trait>::Output) {} +} +``` + +r[associated.fn.method.self-pat-shorthands] +Shorthand syntax can be used without specifying a type, which have the following equivalents: + +Shorthand | Equivalent +----------------------|----------- +`self` | `self: Self` +`&'lifetime self` | `self: &'lifetime Self` +`&'lifetime mut self` | `self: &'lifetime mut Self` + +> [!NOTE] +> Lifetimes can be, and usually are, elided with this shorthand. + +r[associated.fn.method.self-pat-mut] +If the `self` parameter is prefixed with `mut`, it becomes a mutable variable, similar to regular parameters using a `mut` [identifier pattern]. For example: + +```rust +trait Changer: Sized { + fn change(mut self) {} + fn modify(mut self: Box<Self>) {} +} +``` + +As an example of methods on a trait, consider the following: + +```rust +# type Surface = i32; +# type BoundingBox = i32; +trait Shape { + fn draw(&self, surface: Surface); + fn bounding_box(&self) -> BoundingBox; +} +``` + +This defines a trait with two methods. All values that have [implementations] of this trait while the trait is in scope can have their `draw` and `bounding_box` methods called. + +```rust +# type Surface = i32; +# type BoundingBox = i32; +# trait Shape { +# fn draw(&self, surface: Surface); +# fn bounding_box(&self) -> BoundingBox; +# } +# +struct Circle { + // ... +} + +impl Shape for Circle { + // ... +# fn draw(&self, _: Surface) {} +# fn bounding_box(&self) -> BoundingBox { 0i32 } +} + +# impl Circle { +# fn new() -> Circle { Circle{} } +# } +# +let circle_shape = Circle::new(); +let bounding_box = circle_shape.bounding_box(); +``` + +r[items.associated.fn.params.edition2018] +> [!EDITION-2018] +> In the 2015 edition, it is possible to declare trait methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and an error as of the 2018 edition. All parameters must have an argument name. + +r[items.associated.fn.param-attributes] +#### Attributes on method parameters + +Attributes on method parameters follow the same rules and restrictions as [regular function parameters]. + +r[items.associated.type] +## Associated types + +r[items.associated.type.intro] +*Associated types* are [type aliases] associated with another type. + +r[items.associated.type.restrictions] +Associated types cannot be defined in [inherent implementations] nor can they be given a default implementation in traits. + +r[items.associated.type.decl] +An *associated type declaration* declares a signature for associated type definitions. It is written in one of the following forms, where `Assoc` is the name of the associated type, `Params` is a comma-separated list of type, lifetime or const parameters, `Bounds` is a plus-separated list of trait bounds that the associated type must meet, and `WhereBounds` is a comma-separated list of bounds that the parameters must meet: + +<!-- ignore: illustrative example forms --> +```rust,ignore +type Assoc; +type Assoc: Bounds; +type Assoc<Params>; +type Assoc<Params>: Bounds; +type Assoc<Params> where WhereBounds; +type Assoc<Params>: Bounds where WhereBounds; +``` + +r[items.associated.type.name] +The identifier is the name of the declared type alias. + +r[items.associated.type.impl-fulfillment] +The optional trait bounds must be fulfilled by the implementations of the type alias. + +r[items.associated.type.sized] +There is an implicit [`Sized`] bound on associated types that can be relaxed using the special `?Sized` bound. + +r[items.associated.type.def] +An *associated type definition* defines a type alias for the implementation of a trait on a type. + +r[items.associated.type.def-restriction] +They are written similarly to an *associated type declaration*, but cannot contain `Bounds`, but instead must contain a `Type`: + +<!-- ignore: illustrative example forms --> +```rust,ignore +type Assoc = Type; +type Assoc<Params> = Type; // the type `Type` here may reference `Params` +type Assoc<Params> = Type where WhereBounds; +type Assoc<Params> where WhereBounds = Type; // deprecated, prefer the form above +``` + +r[items.associated.type.alias] +If a type `Item` has an associated type `Assoc` from a trait `Trait`, then `<Item as Trait>::Assoc` is a type that is an alias of the type specified in the associated type definition. + +r[items.associated.type.param] +Furthermore, if `Item` is a type parameter, then `Item::Assoc` can be used in type parameters. + +r[items.associated.type.generic] +Associated types may include [generic parameters] and [where clauses]; these are often referred to as *generic associated types*, or *GATs*. If the type `Thing` has an associated type `Item` from a trait `Trait` with the generics `<'a>` , the type can be named like `<Thing as Trait>::Item<'x>`, where `'x` is some lifetime in scope. In this case, `'x` will be used wherever `'a` appears in the associated type definitions on impls. + +```rust +trait AssociatedType { + // Associated type declaration + type Assoc; +} + +struct Struct; + +struct OtherStruct; + +impl AssociatedType for Struct { + // Associated type definition + type Assoc = OtherStruct; +} + +impl OtherStruct { + fn new() -> OtherStruct { + OtherStruct + } +} + +fn main() { + // Usage of the associated type to refer to OtherStruct as <Struct as AssociatedType>::Assoc + let _other_struct: OtherStruct = <Struct as AssociatedType>::Assoc::new(); +} +``` + +An example of associated types with generics and where clauses: + +```rust +struct ArrayLender<'a, T>(&'a mut [T; 16]); + +trait Lend { + // Generic associated type declaration + type Lender<'a> where Self: 'a; + fn lend<'a>(&'a mut self) -> Self::Lender<'a>; +} + +impl<T> Lend for [T; 16] { + // Generic associated type definition + type Lender<'a> = ArrayLender<'a, T> where Self: 'a; + + fn lend<'a>(&'a mut self) -> Self::Lender<'a> { + ArrayLender(self) + } +} + +fn borrow<'a, T: Lend>(array: &'a mut T) -> <T as Lend>::Lender<'a> { + array.lend() +} + +fn main() { + let mut array = [0usize; 16]; + let lender = borrow(&mut array); +} +``` + +### Associated types container example + +Consider the following example of a `Container` trait. Notice that the type is available for use in the method signatures: + +```rust +trait Container { + type E; + fn empty() -> Self; + fn insert(&mut self, elem: Self::E); +} +``` + +In order for a type to implement this trait, it must not only provide implementations for every method, but it must specify the type `E`. Here's an implementation of `Container` for the standard library type `Vec`: + +```rust +# trait Container { +# type E; +# fn empty() -> Self; +# fn insert(&mut self, elem: Self::E); +# } +impl<T> Container for Vec<T> { + type E = T; + fn empty() -> Vec<T> { Vec::new() } + fn insert(&mut self, x: T) { self.push(x); } +} +``` + +### Relationship between `Bounds` and `WhereBounds` + +In this example: + +```rust +# use std::fmt::Debug; +trait Example { + type Output<T>: Ord where T: Debug; +} +``` + +Given a reference to the associated type like `<X as Example>::Output<Y>`, the associated type itself must be `Ord`, and the type `Y` must be `Debug`. + +r[items.associated.type.generic-where-clause] +### Required where clauses on generic associated types + +r[items.associated.type.generic-where-clause.intro] +Generic associated type declarations on traits currently may require a list of where clauses, dependent on functions in the trait and how the GAT is used. These rules may be loosened in the future; updates can be found [on the generic associated types initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/explainer/required_bounds.html). + +r[items.associated.type.generic-where-clause.valid-fn] +In a few words, these where clauses are required in order to maximize the allowed definitions of the associated type in impls. To do this, any clauses that *can be proven to hold* on functions (using the parameters of the function or trait) where a GAT appears as an input or output must also be written on the GAT itself. + +```rust +trait LendingIterator { + type Item<'x> where Self: 'x; + fn next<'a>(&'a mut self) -> Self::Item<'a>; +} +``` + +In the above, on the `next` function, we can prove that `Self: 'a`, because of the implied bounds from `&'a mut self`; therefore, we must write the equivalent bound on the GAT itself: `where Self: 'x`. + +r[items.associated.type.generic-where-clause.intersection] +When there are multiple functions in a trait that use the GAT, then the *intersection* of the bounds from the different functions are used, rather than the union. + +```rust +trait Check<T> { + type Checker<'x>; + fn create_checker<'a>(item: &'a T) -> Self::Checker<'a>; + fn do_check(checker: Self::Checker<'_>); +} +``` + +In this example, no bounds are required on the `type Checker<'a>;`. While we know that `T: 'a` on `create_checker`, we do not know that on `do_check`. However, if `do_check` was commented out, then the `where T: 'x` bound would be required on `Checker`. + +r[items.associated.type.generic-where-clause.forward] +The bounds on associated types also propagate required where clauses. + +```rust +trait Iterable { + type Item<'a> where Self: 'a; + type Iterator<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a; + fn iter<'a>(&'a self) -> Self::Iterator<'a>; +} +``` + +Here, `where Self: 'a` is required on `Item` because of `iter`. However, `Item` is used in the bounds of `Iterator`, the `where Self: 'a` clause is also required there. + +r[items.associated.type.generic-where-clause.static] +Finally, any explicit uses of `'static` on GATs in the trait do not count towards the required bounds. + +```rust +trait StaticReturn { + type Y<'a>; + fn foo(&self) -> Self::Y<'static>; +} +``` + +r[items.associated.const] +## Associated constants + +r[items.associated.const.intro] +*Associated constants* are [constants] associated with a type. + +r[items.associated.const.decl] +An *associated constant declaration* declares a signature for associated constant definitions. It is written as `const`, then an identifier, then `:`, then a type, finished by a `;`. + +r[items.associated.const.name] +The identifier is the name of the constant used in the path. The type is the type that the definition has to implement. + +r[items.associated.const.def] +An *associated constant definition* defines a constant associated with a type. It is written the same as a [constant item]. + +r[items.associated.const.eval] +Associated constant definitions undergo [constant evaluation] only when referenced. Further, definitions that include [generic parameters] are evaluated after monomorphization. + +```rust,compile_fail +struct Struct; +struct GenericStruct<const ID: i32>; + +impl Struct { + // Definition not immediately evaluated + const PANIC: () = panic!("compile-time panic"); +} + +impl<const ID: i32> GenericStruct<ID> { + // Definition not immediately evaluated + const NON_ZERO: () = if ID == 0 { + panic!("contradiction") + }; +} + +fn main() { + // Referencing Struct::PANIC causes compilation error + let _ = Struct::PANIC; + + // Fine, ID is not 0 + let _ = GenericStruct::<1>::NON_ZERO; + + // Compilation error from evaluating NON_ZERO with ID=0 + let _ = GenericStruct::<0>::NON_ZERO; +} +``` + +### Associated constants examples + +A basic example: + +```rust +trait ConstantId { + const ID: i32; +} + +struct Struct; + +impl ConstantId for Struct { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, Struct::ID); +} +``` + +Using default values: + +```rust +trait ConstantIdDefault { + const ID: i32 = 1; +} + +struct Struct; +struct OtherStruct; + +impl ConstantIdDefault for Struct {} + +impl ConstantIdDefault for OtherStruct { + const ID: i32 = 5; +} + +fn main() { + assert_eq!(1, Struct::ID); + assert_eq!(5, OtherStruct::ID); +} +``` + +[`Arc<Self>`]: ../special-types-and-traits.md#arct +[`Box<Self>`]: ../special-types-and-traits.md#boxt +[`Pin<P>`]: ../special-types-and-traits.md#pinp +[`Rc<Self>`]: ../special-types-and-traits.md#rct +[`Sized`]: ../special-types-and-traits.md#sized +[traits]: traits.md +[type aliases]: type-aliases.md +[inherent implementations]: implementations.md#inherent-implementations +[identifier]: ../identifiers.md +[identifier pattern]: ../patterns.md#identifier-patterns +[implementations]: implementations.md +[type]: ../types.md#type-expressions +[constants]: constant-items.md +[constant item]: constant-items.md +[functions]: functions.md +[function item]: ../types/function-item.md +[method call operator]: ../expressions/method-call-expr.md +[path]: ../paths.md +[regular function parameters]: functions.md#attributes-on-function-parameters +[generic parameters]: generics.md +[where clauses]: generics.md#where-clauses +[constant evaluation]: ../const_eval.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/constant-items.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/constant-items.md new file mode 100644 index 00000000..17903c9a --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/constant-items.md @@ -0,0 +1,120 @@ +r[items.const] +# Constant items + +r[items.const.syntax] +```grammar,items +ConstantItem -> + `const` ( IDENTIFIER | `_` ) `:` Type ( `=` Expression )? `;` +``` + +r[items.const.intro] +A *constant item* is an optionally named _[constant value]_ which is not associated with a specific memory location in the program. + +r[items.const.behavior] +Constants are essentially inlined wherever they are used, meaning that they are copied directly into the relevant context when used. This includes use of constants from external crates, and non-[`Copy`] types. References to the same constant are not necessarily guaranteed to refer to the same memory address. + +r[items.const.namespace] +The constant declaration defines the constant value in the [value namespace] of the module or block where it is located. + +r[items.const.static] +Constants must be explicitly typed. The type must have a `'static` lifetime: any references in the initializer must have `'static` lifetimes. References in the type of a constant default to `'static` lifetime; see [static lifetime elision]. + +r[items.const.static-temporary] +A reference to a constant will have `'static` lifetime if the constant value is eligible for [promotion]; otherwise, a temporary will be created. + +```rust +const BIT1: u32 = 1 << 0; +const BIT2: u32 = 1 << 1; + +const BITS: [u32; 2] = [BIT1, BIT2]; +const STRING: &'static str = "bitstring"; + +struct BitsNStrings<'a> { + mybits: [u32; 2], + mystring: &'a str, +} + +const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { + mybits: BITS, + mystring: STRING, +}; +``` + +r[items.const.expr-omission] +The constant expression may only be omitted in a [trait definition]. + +r[items.const.destructor] +## Constants with destructors + +Constants can contain destructors. Destructors are run when the value goes out of scope. + +```rust +struct TypeWithDestructor(i32); + +impl Drop for TypeWithDestructor { + fn drop(&mut self) { + println!("Dropped. Held {}.", self.0); + } +} + +const ZERO_WITH_DESTRUCTOR: TypeWithDestructor = TypeWithDestructor(0); + +fn create_and_drop_zero_with_destructor() { + let x = ZERO_WITH_DESTRUCTOR; + // x gets dropped at end of function, calling drop. + // prints "Dropped. Held 0.". +} +``` + +r[items.const.unnamed] +## Unnamed constant + +r[items.const.unnamed.intro] +Unlike an [associated constant], a [free] constant may be unnamed by using an underscore instead of the name. For example: + +```rust +const _: () = { struct _SameNameTwice; }; + +// OK although it is the same name as above: +const _: () = { struct _SameNameTwice; }; +``` + +r[items.const.unnamed.repetition] +As with [underscore imports], macros may safely emit the same unnamed constant in the same scope more than once. For example, the following should not produce an error: + +```rust +macro_rules! m { + ($item: item) => { $item $item } +} + +m!(const _: () = ();); +// This expands to: +// const _: () = (); +// const _: () = (); +``` + +r[items.const.eval] +## Evaluation + +[Free][free] constants are always [evaluated][const_eval] at compile-time to surface panics. This happens even within an unused function: + +```rust,compile_fail +// Compile-time panic +const PANIC: () = std::unimplemented!(); + +fn unused_generic_function<T>() { + // A failing compile-time assertion + const _: () = assert!(usize::BITS == 0); +} +``` + +[const_eval]: ../const_eval.md +[associated constant]: ../items/associated-items.md#associated-constants +[constant value]: ../const_eval.md#constant-expressions +[free]: ../glossary.md#free-item +[static lifetime elision]: ../lifetime-elision.md#const-and-static-elision +[trait definition]: traits.md +[underscore imports]: use-declarations.md#underscore-imports +[`Copy`]: ../special-types-and-traits.md#copy +[value namespace]: ../names/namespaces.md +[promotion]: destructors.scope.const-promotion diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/enumerations.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/enumerations.md new file mode 100644 index 00000000..3d7ecd62 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/enumerations.md @@ -0,0 +1,398 @@ +r[items.enum] +# Enumerations + +r[items.enum.syntax] +```grammar,items +Enumeration -> + `enum` IDENTIFIER GenericParams? WhereClause? `{` EnumVariants? `}` + +EnumVariants -> EnumVariant ( `,` EnumVariant )* `,`? + +EnumVariant -> + OuterAttribute* Visibility? + IDENTIFIER ( EnumVariantTuple | EnumVariantStruct )? EnumVariantDiscriminant? + +EnumVariantTuple -> `(` TupleFields? `)` + +EnumVariantStruct -> `{` StructFields? `}` + +EnumVariantDiscriminant -> `=` Expression +``` + +r[items.enum.intro] +An *enumeration*, also referred to as an *enum*, is a simultaneous definition of a nominal [enumerated type] as well as a set of *constructors*, that can be used to create or pattern-match values of the corresponding enumerated type. + +r[items.enum.decl] +Enumerations are declared with the keyword `enum`. + +r[items.enum.namespace] +The `enum` declaration defines the enumeration type in the [type namespace] of the module or block where it is located. + +An example of an `enum` item and its use: + +```rust +enum Animal { + Dog, + Cat, +} + +let mut a: Animal = Animal::Dog; +a = Animal::Cat; +``` + +r[items.enum.constructor] +Enum constructors can have either named or unnamed fields: + +```rust +enum Animal { + Dog(String, f64), + Cat { name: String, weight: f64 }, +} + +let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2); +a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 }; +``` + +In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply called an enum variant. + +r[items.enum.fieldless] +An enum where no constructors contain fields is called a *<span id="field-less-enum">field-less enum</span>*. For example, this is a fieldless enum: + +```rust +enum Fieldless { + Tuple(), + Struct{}, + Unit, +} +``` + +r[items.enum.unit-only] +If a field-less enum only contains unit variants, the enum is called an *<span id="unit-only-enum">unit-only enum</span>*. For example: + +```rust +enum Enum { + Foo = 3, + Bar = 2, + Baz = 1, +} +``` + +r[items.enum.constructor-names] +Variant constructors are similar to [struct] definitions, and can be referenced by a path from the enumeration name, including in [use declarations]. + +r[items.enum.constructor-namespace] +Each variant defines its type in the [type namespace], though that type cannot be used as a type specifier. Tuple-like and unit-like variants also define a constructor in the [value namespace]. + +r[items.enum.struct-expr] +A struct-like variant can be instantiated with a [struct expression]. + +r[items.enum.tuple-expr] +A tuple-like variant can be instantiated with a [call expression] or a [struct expression]. + +r[items.enum.path-expr] +A unit-like variant can be instantiated with a [path expression] or a [struct expression]. For example: + +```rust +enum Examples { + UnitLike, + TupleLike(i32), + StructLike { value: i32 }, +} + +use Examples::*; // Creates aliases to all variants. +let x = UnitLike; // Path expression of the const item. +let x = UnitLike {}; // Struct expression. +let y = TupleLike(123); // Call expression. +let y = TupleLike { 0: 123 }; // Struct expression using integer field names. +let z = StructLike { value: 123 }; // Struct expression. +``` + +<span id="custom-discriminant-values-for-fieldless-enumerations"></span> +r[items.enum.discriminant] +## Discriminants + +r[items.enum.discriminant.intro] +Each enum instance has a _discriminant_: an integer logically associated to it that is used to determine which variant it holds. + +r[items.enum.discriminant.type] +Enums without a [primitive representation] have discriminants of type `isize`. However, the compiler may use a smaller type or another means of distinguishing variants in the actual memory layout. + +```rust +# use core::mem::size_of; +enum E { + V1 = 0isize, // OK: `isize` is the discriminant type. + V2, +} + +assert!(size_of::<E>() <= size_of::<isize>()); +``` + +```rust,compile_fail,E0308 +enum E { + V = 0u8, // ERROR: Expected `isize`, found `u8`. +} +``` + +r[items.enum.discriminant.type-primitive] +Enums with a [primitive representation] have discriminants of the type named by the representation. This also applies to enums that combine the `C` representation with a primitive representation (see [layout.repr.primitive-c]). + +```rust +#[repr(u8)] +enum E { + V = 0u8, // OK: `u8` is the discriminant type. +} +``` + +```rust,compile_fail,E0308 +#[repr(u8)] +enum E { + V = 0isize, // ERROR: Expected `u8`, found `isize`. +} +``` + +### Assigning discriminant values + +r[items.enum.discriminant.explicit] +#### Explicit discriminants + +r[items.enum.discriminant.explicit.intro] +In two circumstances, the discriminant of a variant may be explicitly set by following the variant name with `=` and a [constant expression]: + +r[items.enum.discriminant.explicit.unit-only] +1. if the enumeration is "[unit-only]". + +r[items.enum.discriminant.explicit.primitive-repr] +2. if a [primitive representation] is used. For example: + + ```rust + #[repr(u8)] + enum Enum { + Unit = 3, + Tuple(u16), + Struct { + a: u8, + b: u16, + } = 1, + } + ``` + +r[items.enum.discriminant.implicit] +#### Implicit discriminants + +If a discriminant for a variant is not specified, then it is set to one higher than the discriminant of the previous variant in the declaration. If the discriminant of the first variant in the declaration is unspecified, then it is set to zero. + +```rust +enum Foo { + Bar, // 0 + Baz = 123, // 123 + Quux, // 124 +} + +let baz_discriminant = Foo::Baz as u32; +assert_eq!(baz_discriminant, 123); +``` + +r[items.enum.discriminant.restrictions] +#### Restrictions + +r[items.enum.discriminant.restrictions.same-discriminant] +It is an error when two variants share the same discriminant. + +```rust,compile_fail +enum SharedDiscriminantError { + SharedA = 1, + SharedB = 1, +} + +enum SharedDiscriminantError2 { + Zero, // 0 + One, // 1 + OneToo = 1, // 1 (collision with previous!) +} +``` + +r[items.enum.discriminant.restrictions.above-max-discriminant] +It is also an error to have an unspecified discriminant where the previous discriminant is the maximum value for the size of the discriminant. + +```rust,compile_fail +#[repr(u8)] +enum OverflowingDiscriminantError { + Max = 255, + MaxPlusOne, // Would be 256, but that overflows the enum. +} + +#[repr(u8)] +enum OverflowingDiscriminantError2 { + MaxMinusOne = 254, // 254 + Max, // 255 + MaxPlusOne, // Would be 256, but that overflows the enum. +} +``` + +r[items.enum.discriminant.restrictions.generics] +Explicit enum discriminant initializers may not use generic parameters from the enclosing enum. + +```rust,compile_fail +#[repr(u32)] +enum E<'a, T, const N: u32> { + Lifetime(&'a T) = { + let a: &'a (); // ERROR. + 1 + }, + Type(T) = { + let x: T; // ERROR. + 2 + }, + Const = N, // ERROR. +} +``` + +### Accessing discriminant + +#### Via `mem::discriminant` + +r[items.enum.discriminant.access-opaque] + +[`std::mem::discriminant`] returns an opaque reference to the discriminant of an enum value which can be compared. This cannot be used to get the value of the discriminant. + +r[items.enum.discriminant.coercion] +#### Casting + +r[items.enum.discriminant.coercion.intro] +If an enumeration is [unit-only] (with no tuple and struct variants), then its discriminant can be directly accessed with a [numeric cast]; e.g.: + +```rust +enum Enum { + Foo, + Bar, + Baz, +} + +assert_eq!(0, Enum::Foo as isize); +assert_eq!(1, Enum::Bar as isize); +assert_eq!(2, Enum::Baz as isize); +``` + +r[items.enum.discriminant.coercion.fieldless] +[Field-less enums] can be cast if they do not have explicit discriminants, or where only unit variants are explicit. + +```rust +enum Fieldless { + Tuple(), + Struct{}, + Unit, +} + +assert_eq!(0, Fieldless::Tuple() as isize); +assert_eq!(1, Fieldless::Struct{} as isize); +assert_eq!(2, Fieldless::Unit as isize); + +#[repr(u8)] +enum FieldlessWithDiscriminants { + First = 10, + Tuple(), + Second = 20, + Struct{}, + Unit, +} + +assert_eq!(10, FieldlessWithDiscriminants::First as u8); +assert_eq!(11, FieldlessWithDiscriminants::Tuple() as u8); +assert_eq!(20, FieldlessWithDiscriminants::Second as u8); +assert_eq!(21, FieldlessWithDiscriminants::Struct{} as u8); +assert_eq!(22, FieldlessWithDiscriminants::Unit as u8); +``` + +#### Pointer casting + +r[items.enum.discriminant.access-memory] + +If the enumeration specifies a [primitive representation], then the discriminant may be reliably accessed via unsafe pointer casting: + +```rust +#[repr(u8)] +enum Enum { + Unit, + Tuple(bool), + Struct{a: bool}, +} + +impl Enum { + fn discriminant(&self) -> u8 { + unsafe { *(self as *const Self as *const u8) } + } +} + +let unit_like = Enum::Unit; +let tuple_like = Enum::Tuple(true); +let struct_like = Enum::Struct{a: false}; + +assert_eq!(0, unit_like.discriminant()); +assert_eq!(1, tuple_like.discriminant()); +assert_eq!(2, struct_like.discriminant()); +``` + +r[items.enum.empty] +## Zero-variant enums + +r[items.enum.empty.intro] +Enums with zero variants are known as *zero-variant enums*. As they have no valid values, they cannot be instantiated. + +```rust +enum ZeroVariants {} +``` + +r[items.enum.empty.uninhabited] +Zero-variant enums are equivalent to the [never type], but they cannot be coerced into other types. + +```rust,compile_fail +# enum ZeroVariants {} +let x: ZeroVariants = panic!(); +let y: u32 = x; // mismatched type error +``` + +r[items.enum.variant-visibility] +## Variant visibility + +Enum variants syntactically allow a [Visibility] annotation, but this is rejected when the enum is validated. This allows items to be parsed with a unified syntax across different contexts where they are used. + +```rust +macro_rules! mac_variant { + ($vis:vis $name:ident) => { + enum $name { + $vis Unit, + + $vis Tuple(u8, u16), + + $vis Struct { f: u8 }, + } + } +} + +// Empty `vis` is allowed. +mac_variant! { E } + +// This is allowed, since it is removed before being validated. +#[cfg(false)] +enum E { + pub U, + pub(crate) T(u8), + pub(super) T { f: String }, +} +``` + +[`C` representation]: ../type-layout.md#the-c-representation +[call expression]: ../expressions/call-expr.md +[constant expression]: ../const_eval.md#constant-expressions +[enumerated type]: ../types/enum.md +[Field-less enums]: #field-less-enum +[never type]: ../types/never.md +[numeric cast]: ../expressions/operator-expr.md#semantics +[path expression]: ../expressions/path-expr.md +[primitive representation]: ../type-layout.md#primitive-representations +[struct expression]: ../expressions/struct-expr.md +[struct]: structs.md +[type namespace]: ../names/namespaces.md +[unit-only]: #unit-only-enum +[use declarations]: use-declarations.md +[value namespace]: ../names/namespaces.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/extern-crates.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/extern-crates.md new file mode 100644 index 00000000..ffad1d98 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/extern-crates.md @@ -0,0 +1,102 @@ +r[items.extern-crate] +# Extern crate declarations + +r[items.extern-crate.syntax] +```grammar,items +ExternCrate -> `extern` `crate` CrateRef AsClause? `;` + +CrateRef -> IDENTIFIER | `self` + +AsClause -> `as` ( IDENTIFIER | `_` ) +``` + +r[items.extern-crate.intro] +An _`extern crate` declaration_ specifies a dependency on an external crate. + +r[items.extern-crate.namespace] +The external crate is then bound into the declaring scope as the given [identifier] in the [type namespace]. + +r[items.extern-crate.extern-prelude] +Additionally, if the `extern crate` appears in the crate root, then the crate name is also added to the [extern prelude], making it automatically in scope in all modules. + +r[items.extern-crate.as] +The `as` clause can be used to bind the imported crate to a different name. + +r[items.extern-crate.lookup] +The external crate is resolved to a specific `soname` at compile time, and a runtime linkage requirement to that `soname` is passed to the linker for loading at runtime. The `soname` is resolved at compile time by scanning the compiler's library path and matching the optional `crate_name` provided against the [`crate_name` attributes] that were declared on the external crate when it was compiled. If no `crate_name` is provided, a default `name` attribute is assumed, equal to the [identifier] given in the `extern crate` declaration. + +r[items.extern-crate.self] +The `self` crate may be imported which creates a binding to the current crate. In this case the `as` clause must be used to specify the name to bind it to. + +Three examples of `extern crate` declarations: + +<!-- ignore: requires external crates --> +```rust,ignore +extern crate pcre; + +extern crate std; // equivalent to: extern crate std as std; + +extern crate std as ruststd; // linking to 'std' under another name +``` + +r[items.extern-crate.name-restrictions] +When naming Rust crates, hyphens are disallowed. However, Cargo packages may make use of them. In such case, when `Cargo.toml` doesn't specify a crate name, Cargo will transparently replace `-` with `_` (Refer to [RFC 940] for more details). + +Here is an example: + +<!-- ignore: requires external crates --> +```rust,ignore +// Importing the Cargo package hello-world +extern crate hello_world; // hyphen replaced with an underscore +``` + +r[items.extern-crate.underscore] +## Underscore imports + +r[items.extern-crate.underscore.intro] +An external crate dependency can be declared without binding its name in scope by using an underscore with the form `extern crate foo as _`. This may be useful for crates that only need to be linked, but are never referenced, and will avoid being reported as unused. + +r[items.extern-crate.underscore.macro_use] +The [`macro_use` attribute] works as usual and imports the macro names into the [`macro_use` prelude]. + +<!-- template:attributes --> +r[items.extern-crate.no_link] +## The `no_link` attribute + +r[items.extern-crate.no_link.intro] +The *`no_link` [attribute][attributes]* may be applied to an `extern crate` item to prevent linking the crate. + +> [!NOTE] +> This is helpful, e.g., when only the macros of a crate are needed. + +> [!EXAMPLE] +> <!-- ignore: requires external crates --> +> ```rust,ignore +> #[no_link] +> extern crate other_crate; +> +> other_crate::some_macro!(); +> ``` + +r[items.extern-crate.no_link.syntax] +The `no_link` attribute uses the [MetaWord] syntax. + +r[items.extern-crate.no_link.allowed-positions] +The `no_link` attribute may only be applied to an `extern crate` declaration. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[items.extern-crate.no_link.duplicates] +Only the first use of `no_link` on an `extern crate` declaration has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +[identifier]: ../identifiers.md +[RFC 940]: https://github.com/rust-lang/rfcs/blob/master/text/0940-hyphens-considered-harmful.md +[`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute +[extern prelude]: ../names/preludes.md#extern-prelude +[`macro_use` prelude]: ../names/preludes.md#macro_use-prelude +[`crate_name` attributes]: ../crates-and-source-files.md#the-crate_name-attribute +[type namespace]: ../names/namespaces.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/external-blocks.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/external-blocks.md new file mode 100644 index 00000000..662fb235 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/external-blocks.md @@ -0,0 +1,476 @@ +r[items.extern] +# External blocks + +r[items.extern.syntax] +```grammar,items +ExternBlock -> + `unsafe`?[^unsafe-2024] `extern` Abi? `{` + InnerAttribute* + ExternalItem* + `}` + +ExternalItem -> + OuterAttribute* ( + MacroInvocationSemi + | Visibility? StaticItem + | Visibility? Function + ) +``` + +[^unsafe-2024]: Starting with the 2024 Edition, the `unsafe` keyword is required semantically. + +r[items.extern.intro] +External blocks provide _declarations_ of items that are not _defined_ in the current crate and are the basis of Rust's foreign function interface. These are akin to unchecked imports. + +r[items.extern.allowed-kinds] +Two kinds of item _declarations_ are allowed in external blocks: [functions] and [statics]. + +r[items.extern.safety] +Calling unsafe functions or accessing unsafe statics that are declared in external blocks is only allowed in an [`unsafe` context]. + +r[items.extern.namespace] +The external block defines its functions and statics in the [value namespace] of the module or block where it is located. + +r[items.extern.unsafe-required] +The `unsafe` keyword is semantically required to appear before the `extern` keyword on external blocks. + +r[items.extern.edition2024] +> [!EDITION-2024] +> Prior to the 2024 edition, the `unsafe` keyword is optional. The `safe` and `unsafe` item qualifiers are only allowed if the external block itself is marked as `unsafe`. + +r[items.extern.fn] +## Functions + +r[items.extern.fn.body] +Functions within external blocks are declared in the same way as other Rust functions, with the exception that they must not have a body and are instead terminated by a semicolon. + +r[items.extern.fn.param-patterns] +Patterns are not allowed in parameters, only [IDENTIFIER] or `_` may be used. + +r[items.extern.fn.qualifiers] +The `safe` and `unsafe` function qualifiers are allowed, but other function qualifiers (e.g. `const`, `async`, `extern`) are not. The `safe` qualifier is rejected in `extern "custom"` blocks. + +r[items.extern.fn.foreign-abi] +Functions within external blocks may be called by Rust code, just like functions defined in Rust. The Rust compiler automatically translates between the Rust ABI and the foreign ABI. + +r[items.extern.fn.safety] +A function declared in an extern block is implicitly `unsafe` unless the `safe` function qualifier is present. + +r[items.extern.fn.fn-ptr] +When coerced to a function pointer, a function declared in an extern block has type `for<'l1, ..., 'lm> extern "abi" fn(A1, ..., An) -> R`, where `'l1`, ... `'lm` are its lifetime parameters, `A1`, ..., `An` are the declared types of its parameters, and `R` is the declared return type. + +r[items.extern.static] +## Statics + +r[items.extern.static.intro] +Statics within external blocks are declared in the same way as [statics] outside of external blocks, except that they do not have an expression initializing their value. + +r[items.extern.static.safety] +Unless a static item declared in an extern block is qualified as `safe`, it is `unsafe` to access that item, whether or not it's mutable, because there is nothing guaranteeing that the bit pattern at the static's memory is valid for the type it is declared with, since some arbitrary (e.g. C) code is in charge of initializing the static. + +r[items.extern.static.mut] +Extern statics can be either immutable or mutable just like [statics] outside of external blocks. + +r[items.extern.static.read-only] +An immutable static *must* be initialized before any Rust code is executed. It is not enough for the static to be initialized before Rust code reads from it. Once Rust code runs, mutating an immutable static (from inside or outside Rust) is UB, except if the mutation happens to bytes inside of an `UnsafeCell`. + +r[items.extern.abi] +## ABI + +r[items.extern.abi.intro] +The `extern` keyword can be followed by an optional [ABI] string. The ABI specifies the calling convention of the functions in the block. The calling convention defines a low-level interface for functions, such as how arguments are placed in registers or on the stack, how return values are passed, and who is responsible for cleaning up the stack. + +> [!EXAMPLE] +> ```rust +> // Interface to the Windows API. +> unsafe extern "system" { /* ... */ } +> ``` + +r[items.extern.abi.default] +If the ABI string is not specified, it defaults to `"C"`. + +> [!NOTE] +> The `extern` syntax without an explicit ABI is being phased out, so it's better to always write the ABI explicitly. +> +> For more details, see [Rust issue #134986](https://github.com/rust-lang/rust/issues/134986). + +r[items.extern.abi.standard] +The following ABI strings are supported on all platforms: + +r[items.extern.abi.rust] +* `unsafe extern "Rust"` --- The native calling convention for Rust functions and closures. This is the default when a function is declared without using [`extern fn`]. The Rust ABI offers no stability guarantees. + +r[items.extern.abi.c] +* `unsafe extern "C"` --- The "C" ABI matches the default ABI chosen by the dominant C compiler for the target. + +r[items.extern.abi.system] +* `unsafe extern "system"` --- This is equivalent to `extern "C"` except on Windows x86_32 where it is equivalent to `"stdcall"` for non-variadic functions, and equivalent to `"C"` for variadic functions. + + > [!NOTE] + > As the correct underlying ABI on Windows is target-specific, it's best to use `extern "system"` when attempting to link Windows API functions that don't use an explicitly defined ABI. + +r[items.extern.abi.unwind] +* `extern "C-unwind"` and `extern "system-unwind"` --- Identical to `"C"` and `"system"`, respectively, but with [different behavior][unwind-behavior] when the callee unwinds (by panicking or throwing a C++ style exception). + +r[items.extern.abi.custom] +* `unsafe extern "custom"` --- A custom ABI that is not known to the compiler. + +r[items.extern.abi.platform] +There are also some platform-specific ABI strings: + +r[items.extern.abi.cdecl] +* `unsafe extern "cdecl"` --- The calling convention typically used with x86_32 C code. + * Only available on x86_32 targets. + * Corresponds to MSVC's `__cdecl` and GCC and clang's `__attribute__((cdecl))`. + + > [!NOTE] + > For details, see: + > + > - <https://learn.microsoft.com/en-us/cpp/cpp/cdecl> + > - <https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl> + +r[items.extern.abi.stdcall] +* `unsafe extern "stdcall"` --- The calling convention typically used by the [Win32 API] on x86_32. + * Only available on x86_32 targets. + * Corresponds to MSVC's `__stdcall` and GCC and clang's `__attribute__((stdcall))`. + + > [!NOTE] + > For details, see: + > + > - <https://learn.microsoft.com/en-us/cpp/cpp/stdcall> + > - <https://en.wikipedia.org/wiki/X86_calling_conventions#stdcall> + +r[items.extern.abi.win64] +* `unsafe extern "win64"` --- The Windows x64 ABI. + * Only available on x86_64 targets. + * "win64" is the same as the "C" ABI on Windows x86_64 targets. + * Corresponds to GCC and clang's `__attribute__((ms_abi))`. + + > [!NOTE] + > For details, see: + > + > - <https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions> + > - <https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention> + +r[items.extern.abi.sysv64] +* `unsafe extern "sysv64"` --- The System V ABI. + * Only available on x86_64 targets. + * "sysv64" is the same as the "C" ABI on non-Windows x86_64 targets. + * Corresponds to GCC and clang's `__attribute__((sysv_abi))`. + + > [!NOTE] + > For details, see: + > + > - <https://wiki.osdev.org/System_V_ABI> + > - <https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI> + +r[items.extern.abi.aapcs] +* `unsafe extern "aapcs"` --- The soft-float ABI for ARM. + * Only available on ARM32 targets. + * "aapcs" is the same as the "C" ABI on soft-float ARM32. + * Corresponds to clang's `__attribute__((pcs("aapcs")))`. + + > [!NOTE] + > For details, see: + > + > - [Arm Procedure Call Standard](https://developer.arm.com/documentation/107656/0101/Getting-started-with-Armv8-M-based-systems/Procedure-Call-Standard-for-Arm-Architecture--AAPCS-) + +r[items.extern.abi.fastcall] +* `unsafe extern "fastcall"` --- A "fast" variant of stdcall that passes some arguments in registers. + * Only available on x86_32 targets. + * Corresponds to MSVC's `__fastcall` and GCC and clang's `__attribute__((fastcall))`. + + > [!NOTE] + > For details, see: + > + > - <https://learn.microsoft.com/en-us/cpp/cpp/fastcall> + > - <https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_fastcall> + +r[items.extern.abi.thiscall] +* `unsafe extern "thiscall"` --- The calling convention typically used on C++ class member functions on x86_32 MSVC. + * Only available on x86_32 targets. + * Corresponds to MSVC's `__thiscall` and GCC and clang's `__attribute__((thiscall))`. + + > [!NOTE] + > For details, see: + > + > - <https://en.wikipedia.org/wiki/X86_calling_conventions#thiscall> + > - <https://learn.microsoft.com/en-us/cpp/cpp/thiscall> + +r[items.extern.abi.efiapi] +* `unsafe extern "efiapi"` --- The ABI used for [UEFI] functions. + * Only available on x86 and ARM targets (32bit and 64bit). + +r[items.extern.abi.platform-unwind-variants] +Like `"C"` and `"system"`, most platform-specific ABI strings also have a [corresponding `-unwind` variant][unwind-behavior]; specifically, these are: + +* `"aapcs-unwind"` +* `"cdecl-unwind"` +* `"fastcall-unwind"` +* `"stdcall-unwind"` +* `"sysv64-unwind"` +* `"thiscall-unwind"` +* `"win64-unwind"` + +r[items.extern.variadic] +## Variadic functions + +r[items.extern.variadic.syntax] +Functions within external blocks may be made variadic by specifying `...` as the last parameter. The variadic parameter may be specified with a pattern. + +```rust +unsafe extern "C" { + unsafe fn foo(...); + unsafe fn bar(x: i32, ...); + unsafe fn with_name(format: *const u8, args: ...); + // SAFETY: This function guarantees it will not access + // variadic arguments. + safe fn ignores_variadic_arguments(x: i32, ...); +} +``` + +> [!WARNING] +> The `safe` qualifier should not be used on a function in an `extern` block unless that function guarantees that it will not access the variadic arguments at all. Passing an unexpected number of arguments or arguments of unexpected type to a variadic function may lead to [undefined behavior][undefined]. + +r[items.extern.variadic.conventions] +Variadic parameters can only be specified within `extern` blocks with the following ABI strings or their corresponding [`-unwind` variants][items.fn.extern.unwind]: + +- `"aapcs"` +- `"C"` +- `"cdecl"` +- `"efiapi"` +- `"system"` +- `"sysv64"` +- `"win64"` + +r[items.extern.attributes] +## Attributes on extern blocks + +r[items.extern.attributes.intro] +The following [attributes] control the behavior of external blocks. + +r[items.extern.attributes.link] +### The `link` attribute + +r[items.extern.attributes.link.intro] +The *`link` attribute* specifies the name of a native library that the compiler should link with for the items within an `extern` block. + +r[items.extern.attributes.link.syntax] +It uses the [MetaListNameValueStr] syntax to specify its inputs. The `name` key is the name of the native library to link. The `kind` key is an optional value which specifies the kind of library with the following possible values: + +r[items.extern.attributes.link.dylib] +- `dylib` --- Indicates a dynamic library. This is the default if `kind` is not specified. + +r[items.extern.attributes.link.static] +- `static` --- Indicates a static library. + +r[items.extern.attributes.link.framework] +- `framework` --- Indicates a macOS framework. This is only valid for macOS targets. + +r[items.extern.attributes.link.raw-dylib] +- `raw-dylib` --- Indicates a dynamic library where the compiler will generate an import library to link against (see [`dylib` versus `raw-dylib`] below for details). This is only valid for Windows targets. + +r[items.extern.attributes.link.name-requirement] +The `name` key must be included if `kind` is specified. + +r[items.extern.attributes.link.modifiers] +The optional `modifiers` argument is a way to specify linking modifiers for the library to link. + +r[items.extern.attributes.link.modifiers-syntax] +Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. + +r[items.extern.attributes.link.modifiers-multiple] +Specifying multiple `modifiers` arguments in a single `link` attribute, or multiple identical modifiers in the same `modifiers` argument is not currently supported. Example: `#[link(name = "mylib", kind = "static", modifiers = "+whole-archive")]`. + +r[items.extern.attributes.link.wasm_import_module] +The `wasm_import_module` key may be used to specify the [WebAssembly module] name for the items within an `extern` block when importing symbols from the host environment. The default module name is `env` if `wasm_import_module` is not specified. + +<!-- ignore: requires extern linking --> +```rust,ignore +#[link(name = "crypto")] +unsafe extern { + // … +} + +#[link(name = "CoreFoundation", kind = "framework")] +unsafe extern { + // … +} + +#[link(wasm_import_module = "foo")] +unsafe extern { + // … +} +``` + +r[items.extern.attributes.link.empty-block] +It is valid to add the `link` attribute on an empty extern block. You can use this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern block. + +r[items.extern.attributes.link.modifiers-bundle] +#### Linking modifiers: `bundle` + +r[items.extern.attributes.link.modifiers-bundle.allowed-kinds] +This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. + +r[items.extern.attributes.link.modifiers-bundle.behavior] +When building a rlib or staticlib `+bundle` means that the native static library will be packed into the rlib or staticlib archive, and then retrieved from there during linking of the final binary. + +r[items.extern.attributes.link.modifiers-bundle.behavior-negative] +When building a rlib `-bundle` means that the native static library is registered as a dependency of that rlib "by name", and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. When building a staticlib `-bundle` means that the native static library is simply not included into the archive and some higher level build system will need to add it later during linking of the final binary. + +r[items.extern.attributes.link.modifiers-bundle.no-effect] +This modifier has no effect when building other targets like executables or dynamic libraries. + +r[items.extern.attributes.link.modifiers-bundle.default] +The default for this modifier is `+bundle`. + +More implementation details about this modifier can be found in [`bundle` documentation for rustc]. + +r[items.extern.attributes.link.modifiers-whole-archive] +#### Linking modifiers: `whole-archive` + +r[items.extern.attributes.link.modifiers-whole-archive.allowed-kinds] +This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. + +r[items.extern.attributes.link.modifiers-whole-archive.behavior] +`+whole-archive` means that the static library is linked as a whole archive without throwing any object files away. + +r[items.extern.attributes.link.modifiers-whole-archive.default] +The default for this modifier is `-whole-archive`. + +More implementation details about this modifier can be found in [`whole-archive` documentation for rustc]. + +r[items.extern.attributes.link.modifiers-verbatim] +#### Linking modifiers: `verbatim` + +r[items.extern.attributes.link.modifiers-verbatim.allowed-kinds] +This modifier is compatible with all linking kinds. + +r[items.extern.attributes.link.modifiers-verbatim.behavior] +`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker. + +r[items.extern.attributes.link.modifiers-verbatim.behavior-negative] +`-verbatim` means that rustc will either add a target-specific prefix and suffix to the library name before passing it to linker, or won't prevent linker from implicitly adding it. + +r[items.extern.attributes.link.modifiers-verbatim.default] +The default for this modifier is `-verbatim`. + +More implementation details about this modifier can be found in [`verbatim` documentation for rustc]. + +r[items.extern.attributes.link.kind-raw-dylib] +#### `dylib` versus `raw-dylib` + +r[items.extern.attributes.link.kind-raw-dylib.intro] +On Windows, linking against a dynamic library requires that an import library is provided to the linker: this is a special static library that declares all of the symbols exported by the dynamic library in such a way that the linker knows that they have to be dynamically loaded at runtime. + +r[items.extern.attributes.link.kind-raw-dylib.import] +Specifying `kind = "dylib"` instructs the Rust compiler to link an import library based on the `name` key. The linker will then use its normal library resolution logic to find that import library. Alternatively, specifying `kind = "raw-dylib"` instructs the compiler to generate an import library during compilation and provide that to the linker instead. + +r[items.extern.attributes.link.kind-raw-dylib.platform-specific] +`raw-dylib` is only supported on Windows. Using it when targeting other platforms will result in a compiler error. + +r[items.extern.attributes.link.import_name_type] +#### The `import_name_type` key + +r[items.extern.attributes.link.import_name_type.intro] +On x86 Windows, names of functions are "decorated" (i.e., have a specific prefix and/or suffix added) to indicate their calling convention. For example, a `stdcall` calling convention function with the name `fn1` that has no arguments would be decorated as `_fn1@0`. However, the [PE Format] does also permit names to have no prefix or be undecorated. Additionally, the MSVC and GNU toolchains use different decorations for the same calling conventions which means, by default, some Win32 functions cannot be called using the `raw-dylib` link kind via the GNU toolchain. + +r[items.extern.attributes.link.import_name_type.values] +To allow for these differences, when using the `raw-dylib` link kind you may also specify the `import_name_type` key with one of the following values to change how functions are named in the generated import library: + +* `decorated`: The function name will be fully-decorated using the MSVC toolchain format. +* `noprefix`: The function name will be decorated using the MSVC toolchain format, but skipping the leading `?`, `@`, or optionally `_`. +* `undecorated`: The function name will not be decorated. + +r[items.extern.attributes.link.import_name_type.default] +If the `import_name_type` key is not specified, then the function name will be fully-decorated using the target toolchain's format. + +r[items.extern.attributes.link.import_name_type.variables] +Variables are never decorated and so the `import_name_type` key has no effect on how they are named in the generated import library. + +r[items.extern.attributes.link.import_name_type.platform-specific] +The `import_name_type` key is only supported on x86 Windows. Using it when targeting other platforms will result in a compiler error. + +<!-- template:attributes --> +r[items.extern.attributes.link_name] +### The `link_name` attribute + +r[items.extern.attributes.link_name.intro] +The *`link_name` [attribute][attributes]* may be applied to declarations inside an `extern` block to specify the symbol to import for the given function or static. + +> [!EXAMPLE] +> ```rust +> unsafe extern "C" { +> #[link_name = "actual_symbol_name"] +> safe fn name_in_rust(); +> } +> ``` + +r[items.extern.attributes.link_name.syntax] +The `link_name` attribute uses the [MetaNameValueStr] syntax. + +r[items.extern.attributes.link_name.invalid-names] +The symbol name must not be the empty string or contain any `U+0000` (NUL) bytes. + +r[items.extern.attributes.link_name.allowed-positions] +The `link_name` attribute may only be applied to a function or static item in an `extern` block. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[items.extern.attributes.link_name.duplicates] +Only the first use of `link_name` on an item has effect. + +> [!NOTE] +> `rustc` lints against any use following the first with a future-compatibility warning. This may become an error in the future. + +r[items.extern.attributes.link_name.link_ordinal] +The `link_name` attribute may not be used with the [`link_ordinal`] attribute. + +r[items.extern.attributes.link_ordinal] +### The `link_ordinal` attribute + +r[items.extern.attributes.link_ordinal.intro] +The *`link_ordinal` attribute* can be applied on declarations inside an `extern` block to indicate the numeric ordinal to use when generating the import library to link against. An ordinal is a unique number per symbol exported by a dynamic library on Windows and can be used when the library is being loaded to find that symbol rather than having to look it up by name. + +> [!WARNING] +> `link_ordinal` should only be used in cases where the ordinal of the symbol is known to be stable: if the ordinal of a symbol is not explicitly set when its containing binary is built then one will be automatically assigned to it, and that assigned ordinal may change between builds of the binary. + +```rust +# #[cfg(all(windows, target_arch = "x86"))] +#[link(name = "exporter", kind = "raw-dylib")] +unsafe extern "stdcall" { + #[link_ordinal(15)] + safe fn imported_function_stdcall(i: i32); +} +``` + +r[items.extern.attributes.link_ordinal.allowed-kinds] +This attribute is only used with the `raw-dylib` linking kind. Using any other kind will result in a compiler error. + +r[items.extern.attributes.link_ordinal.exclusive] +Using this attribute with the `link_name` attribute will result in a compiler error. + +r[items.extern.attributes.fn-parameters] +### Attributes on function parameters + +Attributes on extern function parameters follow the same rules and restrictions as [regular function parameters]. + +[ABI]: glossary.abi +[PE Format]: https://learn.microsoft.com/windows/win32/debug/pe-format#import-name-type +[UEFI]: https://uefi.org/specifications +[WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html +[`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle +[`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib +[`extern fn`]: items.fn.extern +[`unsafe` context]: ../unsafe-keyword.md +[`verbatim` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-verbatim +[`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive +[attributes]: ../attributes.md +[functions]: functions.md +[regular function parameters]: functions.md#attributes-on-function-parameters +[statics]: static-items.md +[unwind-behavior]: functions.md#unwinding +[value namespace]: ../names/namespaces.md +[win32 api]: https://learn.microsoft.com/en-us/windows/win32/api/ +[`link_ordinal`]: items.extern.attributes.link_ordinal diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/functions.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/functions.md new file mode 100644 index 00000000..25ae723a --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/functions.md @@ -0,0 +1,779 @@ +r[items.fn] +# Functions + +r[items.fn.syntax] +```grammar,items +Function -> + FunctionQualifiers `fn` IDENTIFIER GenericParams? + `(` FunctionParameters? `)` + FunctionReturnType? WhereClause? + ( BlockExpression | `;` ) + +FunctionQualifiers -> `const`? `async`?[^async-edition] ItemSafety?[^extern-qualifiers] (`extern` Abi?)? + +ItemSafety -> `safe`[^extern-safe] | `unsafe` + +Abi -> STRING_LITERAL | RAW_STRING_LITERAL + +FunctionParameters -> + SelfParam `,`? + | (SelfParam `,`)? FunctionParam (`,` FunctionParam)* `,`? + +SelfParam -> OuterAttribute* ( ShorthandSelf | TypedSelf ) + +ShorthandSelf -> (`&` | `&` Lifetime)? `mut`? `self` + +TypedSelf -> `mut`? `self` `:` Type + +FunctionParam -> OuterAttribute* ( FunctionParamPattern | `...` | Type[^fn-param-2015] ) + +FunctionParamPattern -> PatternNoTopAlt `:` ( Type | `...` ) + +FunctionReturnType -> `->` Type +``` + +[^async-edition]: The `async` qualifier is not allowed in the 2015 edition. + +[^extern-safe]: The `safe` function qualifier is only allowed semantically within `extern` blocks. + +[^extern-qualifiers]: *Relevant to editions earlier than Rust 2024*: Within `extern` blocks, the `safe` or `unsafe` function qualifier is only allowed when the `extern` is qualified as `unsafe`. + +[^fn-param-2015]: Function parameters with only a type are only allowed in an associated function of a [trait item] in the 2015 edition. + +r[items.fn.intro] +A _function_ consists of a [block] (that's the _body_ of the function), along with a name, a set of parameters, and an output type. Other than a name, all these are optional. + +r[items.fn.namespace] +Functions are declared with the keyword `fn` which defines the given name in the [value namespace] of the module or block where it is located. + +r[items.fn.signature] +Functions may declare a set of *input* [*variables*][variables] as parameters, through which the caller passes arguments into the function, and the *output* [*type*][type] of the value the function will return to its caller on completion. + +r[items.fn.implicit-return] +If the output type is not explicitly stated, it is the [unit type]. + +r[items.fn.fn-item-type] +When referred to, a _function_ yields a first-class *value* of the corresponding [zero-sized] [*function item type*], which when called evaluates to a direct call to the function. + +For example, this is a simple function: + +```rust +fn answer_to_life_the_universe_and_everything() -> i32 { + return 42; +} +``` + +r[items.fn.safety-qualifiers] +The `safe` function is semantically only allowed when used in an [`extern` block]. + +r[items.fn.params] +## Function parameters + +r[items.fn.params.intro] +Function parameters are irrefutable [patterns], so any pattern that is valid in an else-less `let` binding is also valid as a parameter: + +```rust +fn first((value, _): (i32, i32)) -> i32 { value } +``` + +r[items.fn.params.self-pat] +If the first parameter is a [SelfParam], this indicates that the function is a [method]. + +r[items.fn.params.self-restriction] +Functions with a self parameter may only appear as an [associated function] in a [trait] or [implementation]. + +r[items.fn.params.varargs] +A parameter with the `...` token indicates a [C-variadic function] and may only be used as the last parameter. In a function declaration in an [`extern` block], the C-variadic parameter may have a pattern, such as `ap: ...`, and in a [C-variadic function] definition or C-variadic associated function declaration in a trait definition, the pattern is mandatory. + +```rust +unsafe extern "C" { + unsafe fn f1(...); + unsafe fn f2(ap: ...); +} + +unsafe extern "C" fn f3(ap: ...) {} + +trait Tr { + unsafe extern "C" fn f4(ap: ...); +} +``` + +```rust,compile_fail +unsafe extern "C" fn f(...) {} // ERROR: Missing pattern. +``` + +```rust,compile_fail +trait Tr { + unsafe extern "C" fn f(...); // ERROR: Missing pattern. +} +``` + +r[items.fn.body] +## Function body + +r[items.fn.body.intro] +The body block of a function is conceptually wrapped in another block that first binds the argument patterns and then `return`s the value of the function's body. This means that the tail expression of the block, if evaluated, ends up being returned to the caller. As usual, an explicit return expression within the body of the function will short-cut that implicit return, if reached. + +For example, the function above behaves as if it was written as: + +<!-- ignore: example expansion --> +```rust,ignore +// argument_0 is the actual first argument passed from the caller +let (value, _) = argument_0; +return { + value +}; +``` + +r[items.fn.body.bodyless] +Functions without a body block are terminated with a semicolon. This form may only appear in a [trait] or [external block]. + +r[items.fn.generics] +## Generic functions + +r[items.fn.generics.intro] +A _generic function_ allows one or more _parameterized types_ to appear in its signature. Each type parameter must be explicitly declared in an angle-bracket-enclosed and comma-separated list, following the function name. + +```rust +// foo is generic over A and B + +fn foo<A, B>(x: A, y: B) { +# } +``` + +r[items.fn.generics.param-names] +Inside the function signature and body, the name of the type parameter can be used as a type name. + +r[items.fn.generics.param-bounds] +[Trait] bounds can be specified for type parameters to allow methods from that trait to be called on values of that type. This is specified using the `where` syntax: + +```rust +# use std::fmt::Debug; +fn foo<T>(x: T) where T: Debug { +# } +``` + +r[items.fn.generics.mono] +When a generic function is referenced, its type is instantiated based on the context of the reference. For example, calling the `foo` function here: + +```rust +use std::fmt::Debug; + +fn foo<T>(x: &[T]) where T: Debug { + // details elided +} + +foo(&[1, 2]); +``` + +will instantiate type parameter `T` with `i32`. + +r[items.fn.generics.explicit-arguments] +The type parameters can also be explicitly supplied in a trailing [path] component after the function name. This might be necessary if there is not sufficient context to determine the type parameters. For example, `mem::size_of::<u32>() == 4`. + +r[items.fn.extern] +## Extern function qualifier + +r[items.fn.extern.intro] +The `extern` function qualifier allows providing function _definitions_ that can be called with a particular ABI: + +<!-- ignore: fake ABI --> +```rust,ignore +extern "ABI" fn foo() { /* ... */ } +``` + +r[items.fn.extern.def] +These are often used in combination with [external block] items which provide function _declarations_ that can be used to call functions without providing their _definition_: + +<!-- ignore: fake ABI --> +```rust,ignore +unsafe extern "ABI" { + unsafe fn foo(); /* no body */ + safe fn bar(); /* no body */ +} +unsafe { foo() }; +bar(); +``` + +r[items.fn.extern.default-abi] +When `"extern" Abi?*` is omitted from `FunctionQualifiers` in function items, the ABI `"Rust"` is assigned. For example: + +```rust +fn foo() {} +``` + +is equivalent to: + +```rust +extern "Rust" fn foo() {} +``` + +r[items.fn.extern.foreign-call] +Functions can be called by foreign code, and using an ABI that differs from Rust allows, for example, to provide functions that can be called from other programming languages like C: + +```rust +// Declares a function with the "C" ABI +extern "C" fn new_i32() -> i32 { 0 } + +// Declares a function with the "stdcall" ABI +# #[cfg(any(windows, target_arch = "x86"))] +extern "stdcall" fn new_i32_stdcall() -> i32 { 0 } +``` + +r[items.fn.extern.default-extern] +Just as with [external block], when the `extern` keyword is used and the `"ABI"` is omitted, the ABI used defaults to `"C"`. That is, this: + +```rust +extern fn new_i32() -> i32 { 0 } +let fptr: extern fn() -> i32 = new_i32; +``` + +is equivalent to: + +```rust +extern "C" fn new_i32() -> i32 { 0 } +let fptr: extern "C" fn() -> i32 = new_i32; +``` + +r[items.fn.extern.unwind] +### Unwinding + +r[items.fn.extern.unwind.intro] +Most ABI strings come in two variants, one with an `-unwind` suffix and one without. The `Rust` ABI always permits unwinding, so there is no `Rust-unwind` ABI. The choice of ABI, together with the runtime [panic handler], determines the behavior when unwinding out of a function. + +r[items.fn.extern.unwind.behavior] +The table below indicates the behavior of an unwinding operation reaching each type of ABI boundary (function declaration or definition using the corresponding ABI string). Note that the Rust runtime is not affected by, and cannot have an effect on, any unwinding that occurs entirely within another language's runtime, that is, unwinds that are thrown and caught without reaching a Rust ABI boundary. + +The `panic`-unwind column refers to [panicking] via the `panic!` macro and similar standard library mechanisms, as well as to any other Rust operations that cause a panic, such as out-of-bounds array indexing or integer overflow. + +The "unwinding" ABI category refers to `"Rust"` (the implicit ABI of Rust functions not marked `extern`), `"C-unwind"`, and any other ABI with `-unwind` in its name. The "non-unwinding" ABI category refers to all other ABI strings, including `"C"` and `"stdcall"`. + +Native unwinding is defined per-target. On targets that support throwing and catching C++ exceptions, it refers to the mechanism used to implement this feature. Some platforms implement a form of unwinding referred to as ["forced unwinding"][forced-unwinding]; `longjmp` on Windows and `pthread_exit` in `glibc` are implemented this way. Forced unwinding is explicitly excluded from the "Native unwind" column in the table. + +| panic runtime | ABI | `panic`-unwind | Native unwind (unforced) | +| -------------- | ------------ | ------------------------------------- | ----------------------- | +| `panic=unwind` | unwinding | unwind | unwind | +| `panic=unwind` | non-unwinding | abort (see notes below) | [undefined behavior] | +| `panic=abort` | unwinding | `panic` aborts without unwinding | abort | +| `panic=abort` | non-unwinding | `panic` aborts without unwinding | [undefined behavior] | + +r[items.fn.extern.abort] +With `panic=unwind`, when a `panic` is turned into an abort by a non-unwinding ABI boundary, either no destructors (`Drop` calls) will run, or all destructors up until the ABI boundary will run. It is unspecified which of those two behaviors will happen. + +For other considerations and limitations regarding unwinding across FFI boundaries, see the [relevant section in the Panic documentation][panic-ffi]. + +r[items.fn.extern.custom] +### Extern "custom" + +r[items.fn.extern.custom.intro] +An `extern "custom"` function has an unknown, custom ABI. The only way to call such a function is via [inline assembly]. + +> [!EXAMPLE] +> ```rust +> # #[cfg(target_arch = "x86_64")] { +> # use core::arch::{asm, naked_asm}; +> # +> /// Adds 1 to `rax`. +> /// +> /// This function uses a custom calling convention: the argument is +> /// passed in `rax`, the result is returned in `rax`, the flags may +> /// be clobbered, and all other registers are preserved. +> #[unsafe(naked)] +> unsafe extern "custom" fn increment() { +> naked_asm!( +> "add rax, 1", +> "ret", +> ) +> } +> +> let mut x: u64 = 41; +> // SAFETY: The inline assembly respects the calling convention of +> // `increment`: the argument is passed in `rax`, the result is read +> // from `rax`, and no other registers are affected. +> unsafe { +> asm!( +> "call {}", +> sym increment, +> inout("rax") x, +> ); +> } +> assert_eq!(x, 42); +> # } +> ``` + +r[items.fn.extern.custom.signature] +An `extern "custom"` function must: + +- Be `unsafe`. +- Not have any parameters. +- Return the [unit type], with the return type either omitted or written explicitly as `()`. + +> [!NOTE] +> The rule is syntactic. The return type may not be a type alias, even one defined to be the [unit type]. +> +> ```rust,compile_fail +> type Unit = (); +> +> #[unsafe(naked)] +> unsafe extern "custom" fn f() -> Unit { // ERROR: Not explicit `()`. +> core::arch::naked_asm!("ret") +> } +> ``` + +r[items.fn.extern.custom.naked] +An `extern "custom"` function definition must be a [naked function]. + +[forced-unwinding]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html#forced-unwinding +[panic handler]: ../panic.md#the-panic_handler-attribute +[panic-ffi]: ../panic.md#unwinding-across-ffi-boundaries +[panicking]: ../panic.md +[undefined behavior]: ../behavior-considered-undefined.md + +r[items.fn.const] +## Const functions + +See [const functions] for the definition of const functions. + +r[items.fn.async] +## Async functions + +r[items.fn.async.intro] +Functions may be qualified as async, and this can also be combined with the `unsafe` qualifier: + +```rust +async fn regular_example() { } +async unsafe fn unsafe_example() { } +``` + +r[items.fn.async.future] +Async functions do no work when called: instead, they capture their arguments into a future. When polled, that future will execute the function's body. + +r[items.fn.async.desugar-brief] +An async function is roughly equivalent to a function that returns [`impl Future`] and with an [`async move` block][async-blocks] as its body: + +```rust +// Source +async fn example(x: &str) -> usize { + x.len() +} +``` + +is roughly equivalent to: + +```rust +# use std::future::Future; +// Desugared +fn example<'a>(x: &'a str) -> impl Future<Output = usize> + 'a { + async move { x.len() } +} +``` + +r[items.fn.async.desugar] +The actual desugaring is more complex: + +r[items.fn.async.lifetime-capture] +- The return type in the desugaring is assumed to capture all lifetime parameters from the `async fn` declaration. This can be seen in the desugared example above, which explicitly outlives, and hence captures, `'a`. + +r[items.fn.async.param-capture] +- The [`async move` block][async-blocks] in the body captures all function parameters, including those that are unused or bound to a `_` pattern. This ensures that function parameters are dropped in the same order as they would be if the function were not async, except that the drop occurs when the returned future has been fully awaited. + +For more information on the effect of async, see [`async` blocks][async-blocks]. + +[async-blocks]: ../expressions/block-expr.md#async-blocks +[`impl Future`]: ../types/impl-trait.md + +r[items.fn.async.edition2018] +> [!EDITION-2018] +> Async functions are only available beginning with Rust 2018. + +r[items.fn.async.safety] +### Combining `async` and `unsafe` + +r[items.fn.async.safety.intro] +It is legal to declare a function that is both async and unsafe. The resulting function is unsafe to call and (like any async function) returns a future. This future is just an ordinary future and thus an `unsafe` context is not required to "await" it: + +```rust +// Returns a future that, when awaited, dereferences `x`. +// +// Soundness condition: `x` must be safe to dereference until +// the resulting future is complete. +async unsafe fn unsafe_example(x: *const i32) -> i32 { + *x +} + +async fn safe_example() { + // An `unsafe` block is required to invoke the function initially: + let p = 22; + let future = unsafe { unsafe_example(&p) }; + + // But no `unsafe` block required here. This will + // read the value of `p`: + let q = future.await; +} +``` + +Note that this behavior is a consequence of the desugaring to a function that returns an `impl Future` -- in this case, the function we desugar to is an `unsafe` function, but the return value remains the same. + +Unsafe is used on an async function in precisely the same way that it is used on other functions: it indicates that the function imposes some additional obligations on its caller to ensure soundness. As in any other unsafe function, these conditions may extend beyond the initial call itself -- in the snippet above, for example, the `unsafe_example` function took a pointer `x` as argument, and then (when awaited) dereferenced that pointer. This implies that `x` would have to be valid until the future is finished executing, and it is the caller's responsibility to ensure that. + +r[items.fn.c-variadic] +## C-variadic functions + +r[items.fn.c-variadic.intro] +A *C-variadic* function accepts a variable argument list `pat: ...` as its final parameter. + +```rust +unsafe extern "C" fn f(mut ap: ...) -> f64 { + unsafe { ap.next_arg::<f64>() } +} +``` + +```rust,compile_fail +unsafe extern "C" fn f(ap: ..., _: ()) {} // ERROR: `...` must be last. +``` + +This parameter stands in for an arbitrary number of arguments that may be passed by the caller. + +r[items.fn.c-variadic.parameter-type] +The type of `pat` in the function body is [`VaList<'_>`]. + +```rust +# use core::ffi::VaList; +unsafe extern "C" fn f(ap: ...) { + let _: VaList<'_> = ap; +} +``` + +r[items.fn.c-variadic.lifetime] +A C-variadic function definition is implicitly generic over the lifetime of its variadic parameter, as if the parameter had type `VaList<'x>` for a fresh, unnameable lifetime `'x`. Because the function must be valid for any such lifetime, the `VaList` cannot be proved to outlive any caller-provided lifetime (and so cannot escape the call) and no caller-provided lifetime can be proved to outlive it. + +```rust,compile_fail +# use core::ffi::VaList; +fn b_outlives_a<'a, 'b: 'a>(_: &mut VaList<'a>, _: &mut &'b mut u8) {} +unsafe extern "C" fn f(mut r: &mut u8, mut ap: ...) { + b_outlives_a(&mut ap, &mut r); // ERROR: May not live long enough. +} +``` + +```rust,compile_fail +# use core::ffi::VaList; +fn a_outlives_b<'a: 'b, 'b>(_: &mut VaList<'a>, _: &mut &'b mut u8) {} +unsafe extern "C" fn f(mut r: &mut u8, mut ap: ...) { + a_outlives_b(&mut ap, &mut r); // ERROR: May not live long enough. +} +``` + +> [!NOTE] +> This is different than if the data were a stack variable: any caller-provided lifetime can be proved to outlive a borrow of a callee stack variable. +> +> ```rust +> struct MockVaList<'data>(&'data u8); +> fn b_outlives_a<'a, 'b: 'a>(_: &mut MockVaList<'a>, _: &mut &'b mut u8) {} +> unsafe extern "C" fn f(mut r: &mut u8) { +> let data = 0; +> let mut ap = MockVaList(&data); +> b_outlives_a(&mut ap, &mut r); // OK. +> } +> ``` + +r[items.fn.c-variadic.desugar-brief] +A C-variadic function definition is roughly equivalent to a function operating on a [`VaList`]. + +```rust +unsafe extern "C" fn f(mut ap: ...) -> i32 { + unsafe { ap.next_arg::<i32>() } +} +``` + +Roughly desugars to: + +<!-- no_run: conceptual desugaring --> +```rust,no_run +# #![ feature(core_intrinsics) ] +# #![allow(internal_features)] +# use core::ffi::VaList; +# use core::mem::MaybeUninit; +use core::intrinsics::{va_arg, va_end}; +// `va_start` is magic and has no intrinsic. +fn va_start(ap: *mut VaList<'_>) { /* magic */ } +unsafe extern "C" fn f() -> i32 { + unsafe { + let mut ap: MaybeUninit<VaList<'_>> = MaybeUninit::uninit(); + va_start(ap.as_mut_ptr()); + let mut ap = ap.assume_init(); + let x = va_arg::<i32>(&mut ap); + va_end(&mut ap); + x + } +} +``` + +> [!NOTE] +> In an actual C-variadic function definition, the lifetime in `VaList<'_>` is different from what this code would suggest. See [items.fn.c-variadic.lifetime]. + +r[items.fn.c-variadic.next-arg-safety] +Calling `VaList::next_arg` to read an argument of type `T` is only safe if all of the following conditions are satisfied: + +- There is another C-variadic argument to read. +- The actual type of the argument `U` is compatible with `T` (as defined below). +- If `U` and `T` are both integer types, then the value passed by the caller must be +representable in both types. + +Types `T` and `U` are compatible when one of the following is true: + +- `T` and `U` are the same type (up to free lifetimes). +- `T` and `U` are integer types of the same size. +- `T` and `U` are both pointers and their target types are compatible. +- `T` is a pointer to `c_void` and `U` is a pointer to `i8` or `u8`, or vice versa. + +Examples of compatible types are: + +- `u32` and `i32` --- but UB may still occur if the value is not representable in the target type. +- `u64` and `usize` --- on a 64-bit platform. +- `*const &'a u32` and `*mut &'static u32` --- these types are equal up to free lifetimes. + +Examples of incompatible types are: + +- `usize` and `*const _` --- pointers and integers are not compatible. +- `*const fn(&'static ())` and `*const for<'a> fn(&'a ())` --- these types are not equal up to free lifetimes. + +r[items.fn.c-variadic.abi-compatibility] +[`VaList`] is ABI compatible with the C `va_list` type. + +```rust +# use core::ffi::{c_char, c_int, VaList}; +unsafe extern "C" { + // The C `vprintf` function is: + // + // int vprintf(const char *format, va_list ap); + // + unsafe fn vprintf(fmt: *const c_char, ap: VaList<'_>) -> c_int; +} + +unsafe extern "C" fn print(fmt: *const c_char, ap: ...) -> c_int { + // The `VaList` is passed directly to the C function. + unsafe { vprintf(fmt, ap) } +} +``` + +r[items.fn.c-variadic.abi] +Except on [naked functions], only `extern "C"` and `extern "C-unwind"` function definitions can accept a variable argument list. + +```rust,compile_fail +unsafe fn f(ap: ...) {} // ERROR: Not supported. +``` + +```rust,compile_fail +unsafe extern "sysv64" fn f(ap: ...) {} // ERROR: Not supported. +``` + +A naked function can accept a variable argument list only if its ABI string is accepted under [items.extern.variadic.conventions]. + +```rust +# #[cfg(target_arch = "x86_64")] { +/// Computes the dot product of the `n`-dimensional vector `v`, passed +/// as `n` C-variadic `f64` arguments, with the vector `(c, ..., c)`. +/// That is, it computes `c * (v1 + ... + vn)`. +/// +/// # Safety +/// +/// The caller must pass `n` in the range `1..=7`, followed by exactly +/// `n` values of type `f64`. +// SAFETY: The body respects the "sysv64" calling convention, upholds +// the signature, and does not fall through. +#[unsafe(naked)] +unsafe extern "sysv64" fn dot(n: u64, c: f64, v: ...) -> f64 { + core::arch::naked_asm!( + // The "sysv64" calling convention passes `n` in `rdi`, `c` in + // `xmm0`, and the coordinates in `xmm1` through `xmm7`, + // in order. (The caller also passes the number of vector + // registers used in `al`.) + // + // The sum takes the last `n - 1` additions of the chain + // below. Each `addsd` encodes in exactly 4 bytes, so we enter + // the chain `4 * (n - 1)` bytes before the `mulsd`. + "neg rdi", // I.e., `rdi = -n`. + "lea rax, [rip + 2f]", // I.e., `rax` = address of label 2. + "lea rax, [rax + rdi*4 + 4]", // I.e., `rax -= 4 * (n - 1)`. + "jmp rax", + "addsd xmm6, xmm7", // Entered when `n` is 7. + "addsd xmm5, xmm6", // ... when `n` is at least 6. + "addsd xmm4, xmm5", + "addsd xmm3, xmm4", + "addsd xmm2, xmm3", + "addsd xmm1, xmm2", // ... when `n` is at least 2. + "2:", + "mulsd xmm0, xmm1", // The result is returned in `xmm0`. + "ret", + ) +} + +// SAFETY: `dot` is passed `n` variadic `f64` arguments in each call. +let dot2 = unsafe { dot(2, 10.0, 3.0, 4.0) }; +assert_eq!(dot2, 70.0); +let dot7 = unsafe { dot(7, 2.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0) }; +assert_eq!(dot7, 56.0); +# } +``` + +r[items.fn.c-variadic.safety] +When a variable argument list is used in the signature: + +- Function definitions must be `unsafe`. +- Function declarations within trait definitions must be `unsafe`. +- Function declarations in `extern` blocks may be `safe`. + +```rust,compile_fail +extern "C" fn f(ap: ...) {} // ERROR: Must be `unsafe`. +``` + +```rust,compile_fail +trait Tr { + extern "C" fn f(ap: ...); // ERROR: Must be `unsafe`. +} +``` + +```rust +unsafe extern "C" { + safe fn f(ap: ...); // OK. +} +``` + +> [!NOTE] +> For `safe` function declarations in an `extern` block, see the warning in [items.extern.variadic]. + +r[items.fn.c-variadic.async] +A C-variadic function cannot be `async`. + +```rust,compile_fail +async unsafe extern "C" fn f(ap: ...) {} // ERROR: Cannot be `async`. +``` + +r[items.fn.c-variadic.const] +A C-variadic function cannot be `const`. + +```rust,compile_fail,E0658 +const unsafe extern "C" fn f(ap: ...) {} // ERROR: Cannot be `const`. +``` + +r[items.fn.c-variadic.stable-targets] +Support for C-variadic function definitions is stable on the following target architectures: + +- x86 and x86-64 +- ARM +- AArch64 and Arm64EC +- RISC-V 32-bit and 64-bit (except when using the ilp32e ABI) +- LoongArch 32-bit and 64-bit +- s390x +- PowerPC and PowerPC64 +- AMDGPU and NVPTX +- Wasm32 and Wasm64 +- C-SKY +- Xtensa +- Hexagon +- SPARC64 +- MIPS + +> [!NOTE] +> Some target architectures (e.g., BPF) do not support C-variadic function definitions. The compiler will emit an error if such a definition is used on an unsupported target. + +r[items.fn.attributes] +## Attributes on functions + +r[items.fn.attributes.intro] +[Outer attributes][attributes] are allowed on functions. [Inner attributes][attributes] are allowed directly after the `{` inside its body [block]. + +This example shows an inner attribute on a function. The function is documented with just the word "Example". + +```rust +fn documented() { + #![doc = "Example"] +} +``` + +> [!NOTE] +> Except for lints, it is idiomatic to only use outer attributes on function items. + +r[items.fn.attributes.builtin-attributes] +The attributes that have meaning on a function are: + +- [`cfg_attr`] +- [`cfg`] +- [`cold`] +- [`deprecated`] +- [`doc`] +- [`export_name`] +- [`inline`] +- [`link_section`] +- [`must_use`] +- [`no_mangle`] +- [Lint check attributes] +- [Procedural macro attributes] +- [Testing attributes] + +r[items.fn.param-attributes] +## Attributes on function parameters + +r[items.fn.param-attributes.intro] +[Outer attributes][attributes] are allowed on function parameters and the permitted [built-in attributes] are restricted to `cfg`, `cfg_attr`, `allow`, `warn`, `deny`, and `forbid`. + +```rust +fn len( + #[cfg(windows)] slice: &[u16], + #[cfg(not(windows))] slice: &[u8], +) -> usize { + slice.len() +} +``` + +r[items.fn.param-attributes.parsed-attributes] +Inert helper attributes used by procedural macro attributes applied to items are also allowed but be careful to not include these inert attributes in your final `TokenStream`. + +For example, the following code defines an inert `some_inert_attribute` attribute that is not formally defined anywhere and the `some_proc_macro_attribute` procedural macro is responsible for detecting its presence and removing it from the output token stream. + +<!-- ignore: requires proc macro --> +```rust,ignore +#[some_proc_macro_attribute] +fn foo_oof(#[some_inert_attribute] arg: u8) { +} +``` + +[const contexts]: ../const_eval.md#const-context +[const functions]: ../const_eval.md#const-functions +[external block]: external-blocks.md +[path]: ../paths.md +[block]: ../expressions/block-expr.md +[variables]: ../variables.md +[type]: ../types.md#type-expressions +[unit type]: ../types/tuple.md +[*function item type*]: ../types/function-item.md +[Trait]: traits.md +[attributes]: ../attributes.md +[`cfg`]: ../conditional-compilation.md#the-cfg-attribute +[`cfg_attr`]: ../conditional-compilation.md#the-cfg_attr-attribute +[lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[procedural macro attributes]: macro.proc.attribute +[testing attributes]: ../attributes/testing.md +[`cold`]: ../attributes/codegen.md#the-cold-attribute +[`inline`]: ../attributes/codegen.md#the-inline-attribute +[naked function]: ../attributes/codegen.md#the-naked-attribute +[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute +[`doc`]: ../../rustdoc/the-doc-attribute.html +[`must_use`]: ../attributes/diagnostics.md#the-must_use-attribute +[patterns]: ../patterns.md +[`export_name`]: ../abi.md#the-export_name-attribute +[`link_section`]: ../abi.md#the-link_section-attribute +[`no_mangle`]: ../abi.md#the-no_mangle-attribute +[built-in attributes]: ../attributes.md#built-in-attributes-index +[trait item]: traits.md +[method]: associated-items.md#methods +[associated function]: associated-items.md#associated-functions-and-methods +[implementation]: implementations.md +[value namespace]: ../names/namespaces.md +[C-variadic function]: items.fn.c-variadic.intro +[`extern` block]: external-blocks.md +[`VaList<'_>`]: lang-types.va-list +[`VaList`]: lang-types.va-list +[zero-sized]: glossary.zst +[inline assembly]: ../inline-assembly.md +[naked functions]: attributes.codegen.naked diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/generics.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/generics.md new file mode 100644 index 00000000..1f9cab7b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/generics.md @@ -0,0 +1,310 @@ +r[items.generics] +# Generic parameters + +r[items.generics.syntax] +```grammar,items +GenericParams -> `<` ( GenericParam (`,` GenericParam)* `,`? )? `>` + +GenericParam -> OuterAttribute* ( LifetimeParam | TypeParam | ConstParam ) + +LifetimeParam -> Lifetime ( `:` LifetimeBounds? )? + +TypeParam -> IDENTIFIER ( `:` Bounds? )? ( `=` Type )? + +ConstParam -> + `const` IDENTIFIER `:` Type + ( `=` ( BlockExpression | IDENTIFIER | `-`?LiteralExpression ) )? +``` + +r[items.generics.intro] +[Functions], [type aliases], [structs], [enumerations], [unions], [traits], and [implementations] may be *parameterized* by types, constants, and lifetimes. These parameters are listed in angle <span class="parenthetical">brackets (`<...>`)</span>, usually immediately after the name of the item and before its definition. For implementations, which don't have a name, they come directly after `impl`. + +r[items.generics.decl-order] +The order of generic parameters is restricted to lifetime parameters and then type and const parameters intermixed. + +r[items.generics.duplicate-params] +The same parameter name may not be declared more than once in a [GenericParams] list. + +Some examples of items with type, const, and lifetime parameters: + +```rust +fn foo<'a, T>() {} +trait A<U> {} +struct Ref<'a, T> where T: 'a { r: &'a T } +struct InnerArray<T, const N: usize>([T; N]); +struct EitherOrderWorks<const N: bool, U>(U); +``` + +r[items.generics.scope] +Generic parameters are in scope within the item definition where they are declared. They are not in scope for items declared within the body of a function as described in [item declarations]. See [generic parameter scopes] for more details. + +r[items.generics.builtin-generic-types] +[References], [raw pointers], [arrays], [slices], [tuples], and [function pointers] have lifetime or type parameters as well, but are not referred to with path syntax. + +r[items.generics.invalid-lifetimes] +`'_` and `'static` are not valid lifetime parameter names. + +r[items.generics.const] +### Const generics + +r[items.generics.const.intro] +*Const generic parameters* allow items to be generic over constant values. + +r[items.generics.const.namespace] +The const identifier introduces a name in the [value namespace] for the constant parameter, and all instances of the item must be instantiated with a value of the given type. + +r[items.generics.const.allowed-types] +The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`. + +r[items.generics.const.use] +Const parameters can be used anywhere a [const item] can be used, with the exception that when used in a [type] or [array repeat expression], it must be standalone (as described below). That is, they are allowed in the following places: + +1. As an applied const to any type which forms a part of the signature of the item in question. +2. As part of a const expression used to define an [associated const], or as a parameter to an [associated type]. +3. As a value in any runtime expression in the body of any functions in the item. +4. As a parameter to any type used in the body of any functions in the item. +5. As a part of the type of any fields in the item. + +```rust +// Examples where const generic parameters can be used. + +// Used in the signature of the item itself. +fn foo<const N: usize>(arr: [i32; N]) { + // Used as a type within a function body. + let x: [i32; N]; + // Used as an expression. + println!("{}", N * 2); +} + +// Used as a field of a struct. +struct Foo<const N: usize>([i32; N]); + +impl<const N: usize> Foo<N> { + // Used as an associated constant. + const CONST: usize = N * 4; +} + +trait Trait { + type Output; +} + +impl<const N: usize> Trait for Foo<N> { + // Used as an associated type. + type Output = [i32; N]; +} +``` + +```rust,compile_fail +// Examples where const generic parameters cannot be used. +fn foo<const N: usize>() { + // Cannot use in item definitions within a function body. + const BAD_CONST: [usize; N] = [1; N]; + static BAD_STATIC: [usize; N] = [1; N]; + fn inner(bad_arg: [usize; N]) { + let bad_value = N * 2; + } + type BadAlias = [usize; N]; + struct BadStruct([usize; N]); +} +``` + +r[items.generics.const.standalone] +As a further restriction, const parameters may only appear as a standalone argument inside of a [type] or [array repeat expression]. In those contexts, they may only be used as a single segment [path expression], possibly inside a [block] (such as `N` or `{N}`). That is, they cannot be combined with other expressions. + +```rust,compile_fail +// Examples where const parameters may not be used. + +// Not allowed to combine in other expressions in types, such as the +// arithmetic expression in the return type here. +fn bad_function<const N: usize>() -> [u8; {N + 1}] { + // Similarly not allowed for array repeat expressions. + [1; {N + 1}] +} +``` + +r[items.generics.const.argument] +A const argument in a [path] specifies the const value to use for that item. + +r[items.generics.const.argument-const-expr] +The argument must either be an [inferred const] or be a [const expression] of the type ascribed to the const parameter. The const expression must be a [block expression][block] (surrounded with braces) unless it is a single path segment (an [IDENTIFIER]) or a [literal] (with a possibly leading `-` token). + +> [!NOTE] +> This syntactic restriction is necessary to avoid requiring infinite lookahead when parsing an expression inside of a type. + +```rust +struct S<const N: i64>; +const C: i64 = 1; +fn f<const N: i64>() -> S<N> { S } + +let _ = f::<1>(); // Literal. +let _ = f::<-1>(); // Negative literal. +let _ = f::<{ 1 + 2 }>(); // Constant expression. +let _ = f::<C>(); // Single segment path. +let _ = f::<{ C + 1 }>(); // Constant expression. +let _: S<1> = f::<_>(); // Inferred const. +let _: S<1> = f::<(((_)))>(); // Inferred const. +``` + +> [!NOTE] +> In a generic argument list, an [inferred const] is parsed as an [inferred type][InferredType] but then semantically treated as a separate kind of [const generic argument]. + +r[items.generics.const.inferred] +Where a const argument is expected, an `_` (optionally surrounded by any number of matching parentheses), called the *inferred const* ([path rules][paths.expr.complex-const-params], [array expression rules][expr.array.length-restriction]), can be used instead. This asks the compiler to infer the const argument if possible based on surrounding information. + +```rust +fn make_buf<const N: usize>() -> [u8; N] { + [0; _] + // ^ Infers `N`. +} +let _: [u8; 1024] = make_buf::<_>(); +// ^ Infers `1024`. +``` + +> [!NOTE] +> An [inferred const] is not semantically an [expression][Expression] and so is not accepted within braces. +> +> ```rust,compile_fail +> fn f<const N: usize>() -> [u8; N] { [0; _] } +> let _: [_; 1] = f::<{ _ }>(); +> // ^ ERROR `_` not allowed here +> ``` + +r[items.generics.const.inferred-constraint] +The inferred const cannot be used in item signatures. + +```rust,compile_fail +fn f<const N: usize>(x: [u8; N]) -> [u8; _] { x } +// ^ ERROR not allowed +``` + +r[items.generics.const.type-ambiguity] +When there is ambiguity if a generic argument could be resolved as either a type or const argument, it is always resolved as a type. Placing the argument in a block expression can force it to be interpreted as a const argument. + +<!-- TODO: Rewrite the paragraph above to be in terms of namespaces, once namespaces are introduced, and it is clear which namespace each parameter lives in. --> + +```rust,compile_fail +type N = u32; +struct Foo<const N: usize>; +// The following is an error, because `N` is interpreted as the type alias `N`. +fn foo<const N: usize>() -> Foo<N> { todo!() } // ERROR +// Can be fixed by wrapping in braces to force it to be interpreted as the `N` +// const parameter: +fn bar<const N: usize>() -> Foo<{ N }> { todo!() } // ok +``` + +r[items.generics.const.variance] +Unlike type and lifetime parameters, const parameters can be declared without being used inside of a parameterized item, with the exception of implementations as described in [generic implementations]: + +```rust,compile_fail +// ok +struct Foo<const N: usize>; +enum Bar<const M: usize> { A, B } + +// ERROR: unused parameter +struct Baz<T>; +struct Biz<'a>; +struct Unconstrained; +impl<const N: usize> Unconstrained {} +``` + +r[items.generics.const.exhaustiveness] +When resolving a trait bound obligation, the exhaustiveness of all implementations of const parameters is not considered when determining if the bound is satisfied. For example, in the following, even though all possible const values for the `bool` type are implemented, it is still an error that the trait bound is not satisfied: + +```rust,compile_fail +struct Foo<const B: bool>; +trait Bar {} +impl Bar for Foo<true> {} +impl Bar for Foo<false> {} + +fn needs_bar(_: impl Bar) {} +fn generic<const B: bool>() { + let v = Foo::<B>; + needs_bar(v); // ERROR: trait bound `Foo<B>: Bar` is not satisfied +} +``` + +r[items.generics.where] +## Where clauses + +r[items.generics.where.syntax] +```grammar,items +WhereClause -> `where` ( WhereClauseItem `,` )* WhereClauseItem? + +WhereClauseItem -> + LifetimeWhereClauseItem + | TypeBoundWhereClauseItem + +LifetimeWhereClauseItem -> Lifetime `:` LifetimeBounds? + +TypeBoundWhereClauseItem -> ForLifetimes? Type `:` Bounds? +``` + +r[items.generics.where.intro] +*Where clauses* provide another way to specify bounds on type and lifetime parameters as well as a way to specify bounds on types that aren't type parameters. + +r[items.generics.where.higher-ranked-lifetimes] +The `for` keyword can be used to introduce [higher-ranked lifetimes]. It only allows [LifetimeParam] parameters. + +```rust +struct A<T> +where + T: Iterator, // Could use A<T: Iterator> instead + T::Item: Copy, // Bound on an associated type + String: PartialEq<T>, // Bound on `String`, using the type parameter + i32: Default, // Allowed, but not useful +{ + f: T, +} +``` + +r[items.generics.attributes] +## Attributes + +Generic lifetime and type parameters allow [attributes] on them. There are no built-in attributes that do anything in this position, although custom derive attributes may give meaning to it. + +This example shows using a custom derive attribute to modify the meaning of a generic parameter. + +<!-- ignore: requires proc macro derive --> +```rust,ignore +// Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as +// an attribute it understands. +#[derive(MyFlexibleClone)] +struct Foo<#[my_flexible_clone(unbounded)] H> { + a: *const H +} +``` + +[array repeat expression]: ../expressions/array-expr.md +[arrays]: ../types/array.md +[slices]: ../types/slice.md +[associated const]: associated-items.md#associated-constants +[associated type]: associated-items.md#associated-types +[attributes]: ../attributes.md +[block]: ../expressions/block-expr.md +[const contexts]: ../const_eval.md#const-context +[const expression]: ../const_eval.md#constant-expressions +[const generic argument]: items.generics.const.argument +[const item]: constant-items.md +[enumerations]: enumerations.md +[functions]: functions.md +[function pointers]: ../types/function-pointer.md +[generic implementations]: implementations.md#generic-implementations +[generic parameter scopes]: ../names/scopes.md#generic-parameter-scopes +[higher-ranked lifetimes]: ../trait-bounds.md#higher-ranked-trait-bounds +[implementations]: implementations.md +[inferred const]: items.generics.const.inferred +[item declarations]: ../statements.md#item-declarations +[item]: ../items.md +[literal]: ../expressions/literal-expr.md +[path]: ../paths.md +[path expression]: ../expressions/path-expr.md +[raw pointers]: ../types/pointer.md#raw-pointers-const-and-mut +[references]: ../types/pointer.md#shared-references- +[structs]: structs.md +[tuples]: ../types/tuple.md +[trait object]: ../types/trait-object.md +[traits]: traits.md +[type aliases]: type-aliases.md +[type]: ../types.md +[unions]: unions.md +[value namespace]: ../names/namespaces.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/implementations.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/implementations.md new file mode 100644 index 00000000..967d87bc --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/implementations.md @@ -0,0 +1,291 @@ +r[items.impl] +# Implementations + +r[items.impl.syntax] +```grammar,items +Implementation -> InherentImpl | TraitImpl + +InherentImpl -> + `impl` GenericParams? Type WhereClause? `{` + InnerAttribute* + AssociatedItem* + `}` + +TraitImpl -> + `unsafe`? `impl` GenericParams? `!`? TypePath `for` Type + WhereClause? + `{` + InnerAttribute* + AssociatedItem* + `}` +``` + +r[items.impl.intro] +An _implementation_ is an item that associates items with an _implementing type_. Implementations are defined with the keyword `impl` and contain functions that belong to an instance of the type that is being implemented or to the type statically. + +r[items.impl.kinds] +There are two types of implementations: + +- inherent implementations +- [trait] implementations + +r[items.impl.inherent] +## Inherent implementations + +r[items.impl.inherent.intro] +An inherent implementation is defined as the sequence of the `impl` keyword, generic type declarations, a path to a nominal type, a where clause, and a bracketed set of associable items. + +r[items.impl.inherent.implementing-type] +The nominal type is called the _implementing type_ and the associable items are the _associated items_ to the implementing type. + +r[items.impl.inherent.associated-items] +Inherent implementations associate the contained items to the implementing type. + +r[items.impl.inherent.allowed-items] +Inherent implementations can contain [associated functions] (including [methods]) and [associated constants]. + +r[items.impl.inherent.type-alias] +They cannot contain associated type aliases. + +r[items.impl.inherent.associated-item-path] +The [path] to an associated item is any path to the implementing type, followed by the associated item's identifier as the final path component. + +r[items.impl.inherent.coherence] +A type can also have multiple inherent implementations. An implementing type must be defined within the same crate as the original type definition. + +``` rust +pub mod color { + pub struct Color(pub u8, pub u8, pub u8); + + impl Color { + pub const WHITE: Color = Color(255, 255, 255); + } +} + +mod values { + use super::color::Color; + impl Color { + pub fn red() -> Color { + Color(255, 0, 0) + } + } +} + +pub use self::color::Color; +fn main() { + // Actual path to the implementing type and impl in the same module. + color::Color::WHITE; + + // Impl blocks in different modules are still accessed through a path to the type. + color::Color::red(); + + // Re-exported paths to the implementing type also work. + Color::red(); + + // Does not work, because use in `values` is not pub. + // values::Color::red(); +} +``` + +r[items.impl.trait] +## Trait implementations + +r[items.impl.trait.intro] +A _trait implementation_ is defined like an inherent implementation except that the optional generic type declarations are followed by a [trait], followed by the keyword `for`, followed by a path to a nominal type. + +<!-- To understand this, you have to back-reference to the previous section. :( --> + +r[items.impl.trait.implemented-trait] +The trait is known as the _implemented trait_. The implementing type implements the implemented trait. + +r[items.impl.trait.def-requirement] +A trait implementation must define all non-default associated items declared by the implemented trait, may redefine default associated items defined by the implemented trait, and cannot define any other items. + +r[items.impl.trait.associated-item-path] +The path to the associated items is `<` followed by a path to the implementing type followed by `as` followed by a path to the trait followed by `>` as a path component followed by the associated item's path component. + +r[items.impl.trait.safety] +[Unsafe traits] require the trait implementation to begin with the `unsafe` keyword. + +```rust +# #[derive(Copy, Clone)] +# struct Point {x: f64, y: f64}; +# type Surface = i32; +# struct BoundingBox {x: f64, y: f64, width: f64, height: f64}; +# trait Shape { fn draw(&self, s: Surface); fn bounding_box(&self) -> BoundingBox; } +# fn do_draw_circle(s: Surface, c: Circle) { } +struct Circle { + radius: f64, + center: Point, +} + +impl Copy for Circle {} + +impl Clone for Circle { + fn clone(&self) -> Circle { *self } +} + +impl Shape for Circle { + fn draw(&self, s: Surface) { do_draw_circle(s, *self); } + fn bounding_box(&self) -> BoundingBox { + let r = self.radius; + BoundingBox { + x: self.center.x - r, + y: self.center.y - r, + width: 2.0 * r, + height: 2.0 * r, + } + } +} +``` + +r[items.impl.trait.coherence] +### Trait implementation coherence + +r[items.impl.trait.coherence.intro] +A trait implementation is considered incoherent if either the orphan rules check fails or there are overlapping implementation instances. + +r[items.impl.trait.coherence.overlapping] +Two trait implementations overlap when there is a non-empty intersection of the traits the implementation is for, the implementations can be instantiated with the same type. <!-- This is probably wrong? Source: No two implementations can be instantiable with the same set of types for the input type parameters. --> + +r[items.impl.trait.orphan-rule] +#### Orphan rules + +r[items.impl.trait.orphan-rule.intro] +The *orphan rule* states that a trait implementation is only allowed if either the trait or at least one of the types in the implementation is defined in the current crate. It prevents conflicting trait implementations across different crates and is key to ensuring coherence. + +An orphan implementation is one that implements a foreign trait for a foreign type. If these were freely allowed, two crates could implement the same trait for the same type in incompatible ways, creating a situation where adding or updating a dependency could break compilation due to conflicting implementations. + +The orphan rule enables library authors to add new implementations to their traits without fear that they'll break downstream code. Without these restrictions, a library couldn't add an implementation like `impl<T: Display> MyTrait for T` without potentially conflicting with downstream implementations. + +r[items.impl.trait.orphan-rule.def] +Given `impl<P1..=Pn> Trait<T1..=Tn> for T0`, an `impl` is valid only if at least one of the following is true: + +- `Trait` is a [local trait] +- All of + - At least one of the types `T0..=Tn` must be a [local type]. Let `Ti` be the first such type. + - No [uncovered type] parameters `P1..=Pn` may appear in `T0..Ti` (excluding `Ti`) + +r[items.impl.trait.uncovered-param] +Only the appearance of *uncovered* type parameters is restricted. + +r[items.impl.trait.fundamental] +Note that for the purposes of coherence, [fundamental types] are special. The `T` in `Box<T>` is not considered covered, and `Box<LocalType>` is considered local. + +r[items.impl.generics] +## Generic implementations + +r[items.impl.generics.intro] +An implementation can take [generic parameters], which can be used in the rest of the implementation. Implementation parameters are written directly after the `impl` keyword. + +```rust +# trait Seq<T> { fn dummy(&self, _: T) { } } +impl<T> Seq<T> for Vec<T> { + /* ... */ +} +impl Seq<bool> for u32 { + /* Treat the integer as a sequence of bits */ +} +``` + +r[items.impl.generics.use] +Generic parameters *constrain* an implementation if the parameter appears at least once in one of: + +* The implemented trait, if it has one +* The implementing type +* As an [associated type] in the [bounds] of a type that contains another parameter that constrains the implementation + +r[items.impl.generics.constrain] +Type and const parameters must always constrain the implementation. Lifetimes must constrain the implementation if the lifetime is used in an associated type. + +Examples of constraining situations: + +```rust +# trait Trait{} +# trait GenericTrait<T> {} +# trait HasAssocType { type Ty; } +# struct Struct; +# struct GenericStruct<T>(T); +# struct ConstGenericStruct<const N: usize>([(); N]); +// T constrains by being an argument to GenericTrait. +impl<T> GenericTrait<T> for i32 { /* ... */ } + +// T constrains by being an argument to GenericStruct +impl<T> Trait for GenericStruct<T> { /* ... */ } + +// Likewise, N constrains by being an argument to ConstGenericStruct +impl<const N: usize> Trait for ConstGenericStruct<N> { /* ... */ } + +// T constrains by being in an associated type in a bound for type `U` which is +// itself a generic parameter constraining the trait. +impl<T, U> GenericTrait<U> for u32 where U: HasAssocType<Ty = T> { /* ... */ } + +// Like previous, except the type is `(U, isize)`. `U` appears inside the type +// that includes `T`, and is not the type itself. +impl<T, U> GenericStruct<U> where (U, isize): HasAssocType<Ty = T> { /* ... */ } +``` + +Examples of non-constraining situations: + +```rust,compile_fail +// The rest of these are errors, since they have type or const parameters that +// do not constrain. + +// T does not constrain since it does not appear at all. +impl<T> Struct { /* ... */ } + +// N does not constrain for the same reason. +impl<const N: usize> Struct { /* ... */ } + +// Usage of T inside the implementation does not constrain the impl. +impl<T> Struct { + fn uses_t(t: &T) { /* ... */ } +} + +// T is used as an associated type in the bounds for U, but U does not constrain. +impl<T, U> Struct where U: HasAssocType<Ty = T> { /* ... */ } + +// T is used in the bounds, but not as an associated type, so it does not constrain. +impl<T, U> GenericTrait<U> for u32 where U: GenericTrait<T> {} +``` + +Example of an allowed unconstraining lifetime parameter: + +```rust +# struct Struct; +impl<'a> Struct {} +``` + +Example of a disallowed unconstraining lifetime parameter: + +```rust,compile_fail +# struct Struct; +# trait HasAssocType { type Ty; } +impl<'a> HasAssocType for Struct { + type Ty = &'a Struct; +} +``` + +r[items.impl.attributes] +## Attributes on implementations + +Implementations may contain outer [attributes] before the `impl` keyword and inner [attributes] inside the brackets that contain the associated items. Inner attributes must come before any associated items. The attributes that have meaning here are [`cfg`], [`deprecated`], [`doc`], and [the lint check attributes]. + +[trait]: traits.md +[associated constants]: associated-items.md#associated-constants +[associated functions]: associated-items.md#associated-functions-and-methods +[associated type]: associated-items.md#associated-types +[attributes]: ../attributes.md +[bounds]: ../trait-bounds.md +[`cfg`]: ../conditional-compilation.md +[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute +[`doc`]: ../../rustdoc/the-doc-attribute.html +[generic parameters]: generics.md +[methods]: associated-items.md#methods +[path]: ../paths.md +[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[Unsafe traits]: traits.md#unsafe-traits +[local trait]: ../glossary.md#local-trait +[local type]: ../glossary.md#local-type +[fundamental types]: ../glossary.md#fundamental-type-constructors +[uncovered type]: ../glossary.md#uncovered-type diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/modules.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/modules.md new file mode 100644 index 00000000..3cc01502 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/modules.md @@ -0,0 +1,141 @@ +r[items.mod] +# Modules + +r[items.mod.syntax] +```grammar,items +Module -> + `unsafe`? `mod` IDENTIFIER `;` + | `unsafe`? `mod` IDENTIFIER `{` + InnerAttribute* + Item* + `}` +``` + +r[items.mod.intro] +A module is a container for zero or more [items]. + +r[items.mod.def] +A _module item_ is a module, surrounded in braces, named, and prefixed with the keyword `mod`. A module item introduces a new, named module into the tree of modules making up a crate. + +r[items.mod.nesting] +Modules can nest arbitrarily. + +An example of a module: + +```rust +mod math { + type Complex = (f64, f64); + fn sin(f: f64) -> f64 { + /* ... */ +# unimplemented!(); + } + fn cos(f: f64) -> f64 { + /* ... */ +# unimplemented!(); + } + fn tan(f: f64) -> f64 { + /* ... */ +# unimplemented!(); + } +} +``` + +r[items.mod.namespace] +Modules are defined in the [type namespace] of the module or block where they are located. + +r[items.mod.multiple-items] +It is an error to define multiple items with the same name in the same namespace within a module. See the [scopes chapter] for more details on restrictions and shadowing behavior. + +r[items.mod.unsafe] +The `unsafe` keyword is syntactically allowed to appear before the `mod` keyword, but it is rejected at a semantic level. This allows macros to consume the syntax and make use of the `unsafe` keyword, before removing it from the token stream. + +r[items.mod.outlined] +## Module source filenames + +r[items.mod.outlined.intro] +A module without a body is loaded from an external file. When the module does not have a `path` attribute, the path to the file mirrors the logical [module path]. + +r[items.mod.outlined.search] +Ancestor module path components are directories, and the module's contents are in a file with the name of the module plus the `.rs` extension. For example, the following module structure can have this corresponding filesystem structure: + +Module Path | Filesystem Path | File Contents +------------------------- | --------------- | ------------- +`crate` | `lib.rs` | `mod util;` +`crate::util` | `util.rs` | `mod config;` +`crate::util::config` | `util/config.rs` | + +r[items.mod.outlined.search-mod] +Module filenames may also be the name of the module as a directory with the contents in a file named `mod.rs` within that directory. The above example can alternately be expressed with `crate::util`'s contents in a file named `util/mod.rs`. It is not allowed to have both `util.rs` and `util/mod.rs`. + +> [!NOTE] +> Prior to `rustc` 1.30, using `mod.rs` files was the way to load a module with nested children. It is encouraged to use the new naming convention as it is more consistent, and avoids having many files named `mod.rs` within a project. + +r[items.mod.outlined.path] +### The `path` attribute + +r[items.mod.outlined.path.intro] +The directories and files used for loading external file modules can be influenced with the `path` attribute. + +r[items.mod.outlined.path.search] +For `path` attributes on modules not inside inline module blocks, the file path is relative to the directory the source file is located. For example, the following code snippet would use the paths shown based on where it is located: + +<!-- ignore: requires external files --> +```rust,ignore +#[path = "foo.rs"] +mod c; +``` + +Source File | `c`'s File Location | `c`'s Module Path +-------------- | ------------------- | ---------------------- +`src/a/b.rs` | `src/a/foo.rs` | `crate::a::b::c` +`src/a/mod.rs` | `src/a/foo.rs` | `crate::a::c` + +r[items.mod.outlined.path.search-nested] +For `path` attributes inside inline module blocks, the relative location of the file path depends on the kind of source file the `path` attribute is located in. "mod-rs" source files are root modules (such as `lib.rs` or `main.rs`) and modules with files named `mod.rs`. "non-mod-rs" source files are all other module files. Paths for `path` attributes inside inline module blocks in a mod-rs file are relative to the directory of the mod-rs file including the inline module components as directories. For non-mod-rs files, it is the same except the path starts with a directory with the name of the non-mod-rs module. For example, the following code snippet would use the paths shown based on where it is located: + +<!-- ignore: requires external files --> +```rust,ignore +mod inline { + #[path = "other.rs"] + mod inner; +} +``` + +Source File | `inner`'s File Location | `inner`'s Module Path +-------------- | --------------------------| ---------------------------- +`src/a/b.rs` | `src/a/b/inline/other.rs` | `crate::a::b::inline::inner` +`src/a/mod.rs` | `src/a/inline/other.rs` | `crate::a::inline::inner` + +An example of combining the above rules of `path` attributes on inline modules and nested modules within (applies to both mod-rs and non-mod-rs files): + +<!-- ignore: requires external files --> +```rust,ignore +#[path = "thread_files"] +mod thread { + // Load the `local_data` module from `thread_files/tls.rs` relative to + // this source file's directory. + #[path = "tls.rs"] + mod local_data; +} +``` + +r[items.mod.attributes] +## Attributes on modules + +r[items.mod.attributes.intro] +Modules, like all items, accept outer attributes. They also accept inner attributes: either after `{` for a module with a body, or at the beginning of the source file, after the optional BOM and shebang. + +r[items.mod.attributes.supported] +The built-in attributes that have meaning on a module are [`cfg`], [`deprecated`], [`doc`], [the lint check attributes], [`path`], and [`no_implicit_prelude`]. Modules also accept macro attributes. + +[`cfg`]: ../conditional-compilation.md +[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute +[`doc`]: ../../rustdoc/the-doc-attribute.html +[`no_implicit_prelude`]: ../names/preludes.md#the-no_implicit_prelude-attribute +[`path`]: #the-path-attribute +[attribute]: ../attributes.md +[items]: ../items.md +[module path]: ../paths.md +[scopes chapter]: ../names/scopes.md +[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[type namespace]: ../names/namespaces.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/static-items.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/static-items.md new file mode 100644 index 00000000..d3fc458e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/static-items.md @@ -0,0 +1,146 @@ +r[items.static] +# Static items + +r[items.static.syntax] +```grammar,items +StaticItem -> + ItemSafety?[^extern-safety] `static` `mut`? IDENTIFIER `:` Type ( `=` Expression )? `;` +``` + +[^extern-safety]: The `safe` and `unsafe` function qualifiers are only allowed semantically within `extern` blocks. + +r[items.static.intro] +A *static item* is similar to a [constant], except that it represents an allocation in the program that is initialized with the initializer expression. All references and raw pointers to the static refer to the same allocation. + +r[items.static.lifetime] +Static items have the `static` lifetime, which outlives all other lifetimes in a Rust program. Static items do not call [`drop`] at the end of the program. + +r[items.static.storage-disjointness] +If the `static` has a size of at least 1 byte, this allocation is disjoint from all other such `static` allocations as well as heap allocations and stack-allocated variables. However, the storage of immutable `static` items can overlap with allocations that do not themselves have a unique address, such as [promoteds] and [`const` items][constant]. + +r[items.static.namespace] +The static declaration defines a static value in the [value namespace] of the module or block where it is located. + +r[items.static.init] +The static initializer is a [constant expression] evaluated at compile time. Static initializers may refer to and read from other statics. When reading from mutable statics, they read the initial value of that static. + +r[items.static.read-only] +Non-`mut` static items that contain a type that is not [interior mutable] may be placed in read-only memory. + +r[items.static.safety] +All access to a static is safe, but there are a number of restrictions on statics: + +r[items.static.sync] +* The type must have the [`Sync`](std::marker::Sync) trait bound to allow thread-safe access. + +r[items.static.init-omission] +The initializer expression must be omitted in an [external block], and must be provided for free static items. + +r[items.static.safety-qualifiers] +The `safe` and `unsafe` qualifiers are semantically only allowed when used in an [external block]. + +r[items.static.generics] +## Statics & generics + +A static item defined in a generic scope (for example in a blanket or default implementation) will result in exactly one static item being defined, as if the static definition was pulled out of the current scope into the module. There will *not* be one item per monomorphization. + +This code: + +```rust +use std::sync::atomic::{AtomicUsize, Ordering}; + +trait Tr { + fn default_impl() { + static COUNTER: AtomicUsize = AtomicUsize::new(0); + println!("default_impl: counter was {}", COUNTER.fetch_add(1, Ordering::Relaxed)); + } + + fn blanket_impl(); +} + +struct Ty1 {} +struct Ty2 {} + +impl<T> Tr for T { + fn blanket_impl() { + static COUNTER: AtomicUsize = AtomicUsize::new(0); + println!("blanket_impl: counter was {}", COUNTER.fetch_add(1, Ordering::Relaxed)); + } +} + +fn main() { + <Ty1 as Tr>::default_impl(); + <Ty2 as Tr>::default_impl(); + <Ty1 as Tr>::blanket_impl(); + <Ty2 as Tr>::blanket_impl(); +} +``` + +prints + +```text +default_impl: counter was 0 +default_impl: counter was 1 +blanket_impl: counter was 0 +blanket_impl: counter was 1 +``` + +r[items.static.mut] +## Mutable statics + +r[items.static.mut.intro] +If a static item is declared with the `mut` keyword, then it is allowed to be modified by the program. One of Rust's goals is to make concurrency bugs hard to run into, and this is obviously a very large source of race conditions or other bugs. + +r[items.static.mut.safety] +For this reason, an `unsafe` block is required when either reading or writing a mutable static variable. Care should be taken to ensure that modifications to a mutable static are safe with respect to other threads running in the same process. + +r[items.static.mut.extern] +Mutable statics are still very useful, however. They can be used with C libraries and can also be bound from C libraries in an `extern` block. + +```rust +# fn atomic_add(_: *mut u32, _: u32) -> u32 { 2 } + +static mut LEVELS: u32 = 0; + +// This violates the idea of no shared state, and this doesn't internally +// protect against races, so this function is `unsafe` +unsafe fn bump_levels_unsafe() -> u32 { + unsafe { + let ret = LEVELS; + LEVELS += 1; + return ret; + } +} + +// As an alternative to `bump_levels_unsafe`, this function is safe, assuming +// that we have an atomic_add function which returns the old value. This +// function is safe only if no other code accesses the static in a non-atomic +// fashion. If such accesses are possible (such as in `bump_levels_unsafe`), +// then this would need to be `unsafe` to indicate to the caller that they +// must still guard against concurrent access. +fn bump_levels_safe() -> u32 { + unsafe { + return atomic_add(&raw mut LEVELS, 1); + } +} +``` + +r[items.static.mut.sync] +Mutable statics have the same restrictions as normal statics, except that the type does not have to implement the `Sync` trait. + +r[items.static.alternate] +## Using statics or consts + +It can be confusing whether or not you should use a constant item or a static item. Constants should, in general, be preferred over statics unless one of the following are true: + +* Large amounts of data are being stored. +* The single-address property of statics is required. +* Interior mutability is required. + +[constant]: constant-items.md +[`drop`]: ../destructors.md +[constant expression]: ../const_eval.md#constant-expressions +[external block]: external-blocks.md +[interior mutable]: ../interior-mutability.md +[value namespace]: ../names/namespaces.md +[promoteds]: ../destructors.md#constant-promotion diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/structs.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/structs.md new file mode 100644 index 00000000..6374a0ff --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/structs.md @@ -0,0 +1,72 @@ +r[items.struct] +# Structs + +r[items.struct.syntax] +```grammar,items +Struct -> + StructStruct + | TupleStruct + +StructStruct -> + `struct` IDENTIFIER GenericParams? WhereClause? ( `{` StructFields? `}` | `;` ) + +TupleStruct -> + `struct` IDENTIFIER GenericParams? `(` TupleFields? `)` WhereClause? `;` + +StructFields -> StructField (`,` StructField)* `,`? + +StructField -> OuterAttribute* Visibility? IDENTIFIER `:` Type + +TupleFields -> TupleField (`,` TupleField)* `,`? + +TupleField -> OuterAttribute* Visibility? Type +``` + +r[items.struct.intro] +A _struct_ is a nominal [struct type] defined with the keyword `struct`. + +r[items.struct.namespace] +A struct declaration defines the given name in the [type namespace] of the module or block where it is located. + +An example of a `struct` item and its use: + +```rust +struct Point {x: i32, y: i32} +let p = Point {x: 10, y: 11}; +let px: i32 = p.x; +``` + +r[items.struct.tuple] +A _tuple struct_ is a nominal [tuple type], and is also defined with the keyword `struct`. In addition to defining a type, it also defines a constructor of the same name in the [value namespace]. The constructor is a function which can be called to create a new instance of the struct. For example: + +```rust +struct Point(i32, i32); +let p = Point(10, 11); +let px: i32 = match p { Point(x, _) => x }; +``` + +r[items.struct.unit] +A _unit-like struct_ is a struct without any fields, defined by leaving off the list of fields entirely. Such a struct implicitly defines a [constant] of its type with the same name. For example: + +```rust +struct Cookie; +let c = [Cookie, Cookie {}, Cookie, Cookie {}]; +``` + +is equivalent to + +```rust +struct Cookie {} +const Cookie: Cookie = Cookie {}; +let c = [Cookie, Cookie {}, Cookie, Cookie {}]; +``` + +r[items.struct.layout] +The precise memory layout of a struct is not specified. One can specify a particular layout using the [`repr` attribute]. + +[`repr` attribute]: ../type-layout.md#representations +[constant]: constant-items.md +[struct type]: ../types/struct.md +[tuple type]: ../types/tuple.md +[type namespace]: ../names/namespaces.md +[value namespace]: ../names/namespaces.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/traits.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/traits.md new file mode 100644 index 00000000..043c1773 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/traits.md @@ -0,0 +1,390 @@ +r[items.traits] +# Traits + +r[items.traits.syntax] +```grammar,items +Trait -> + `unsafe`? `trait` IDENTIFIER GenericParams? ( `:` Bounds? )? WhereClause? + `{` + InnerAttribute* + AssociatedItem* + `}` +``` + +r[items.traits.intro] +A _trait_ describes an abstract interface that types can implement. This interface consists of [associated items], which come in three varieties: + +- [functions](associated-items.md#associated-functions-and-methods) +- [types](associated-items.md#associated-types) +- [constants](associated-items.md#associated-constants) + +r[items.traits.namespace] +The trait declaration defines a trait in the [type namespace] of the module or block where it is located. + +r[items.traits.associated-item-namespaces] +Associated items are defined as members of the trait within their respective namespaces. Associated types are defined in the type namespace. Associated constants and associated functions are defined in the value namespace. + +r[items.traits.self-param] +All traits define an implicit type parameter `Self` that refers to "the type that is implementing this interface". Traits may also contain additional type parameters. These type parameters, including `Self`, may be constrained by other traits and so forth [as usual][generics]. + +r[items.traits.impls] +Traits are implemented for specific types through separate [implementations]. + +r[items.traits.associated-item-decls] +Trait functions may omit the function body by replacing it with a semicolon. This indicates that the implementation must define the function. If the trait function defines a body, this definition acts as a default for any implementation which does not override it. Similarly, associated constants may omit the equal sign and expression to indicate implementations must define the constant value. Associated types must never define the type, the type may only be specified in an implementation. + +```rust +// Examples of associated trait items with and without definitions. +trait Example { + const CONST_NO_DEFAULT: i32; + const CONST_WITH_DEFAULT: i32 = 99; + type TypeNoDefault; + fn method_without_default(&self); + fn method_with_default(&self) {} +} +``` + +r[items.traits.const-fn] +Trait functions are not allowed to be [`const`]. + +r[items.traits.bounds] +## Trait bounds + +Generic items may use traits as [bounds] on their type parameters. + +r[items.traits.generic] +## Generic traits + +Type parameters can be specified for a trait to make it generic. These appear after the trait name, using the same syntax used in [generic functions]. + +```rust +trait Seq<T> { + fn len(&self) -> u32; + fn elt_at(&self, n: u32) -> T; + fn iter<F>(&self, f: F) where F: Fn(T); +} +``` + +<a id="object-safety"></a> +r[items.traits.dyn-compatible] +## Dyn compatibility + +r[items.traits.dyn-compatible.intro] +A dyn-compatible trait can be the base trait of a [trait object]. A trait is *dyn compatible* if it has the following qualities: + +r[items.traits.dyn-compatible.supertraits] +* All [supertraits] must also be dyn compatible. + +r[items.traits.dyn-compatible.sized] +* `Sized` must not be a [supertrait][supertraits]. In other words, it must not require `Self: Sized`. + +r[items.traits.dyn-compatible.associated-consts] +* It must not have any associated constants. + +r[items.traits.dyn-compatible.associated-types] +* It must not have any associated types with generics. + +r[items.traits.dyn-compatible.associated-functions] +* All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable: + * Dispatchable functions must: + * Not have any type parameters (although lifetime parameters are allowed). + * Be a [method] that does not use `Self` except in the type of the receiver. + * Have a receiver with one of the following types: + * `&Self` (i.e. `&self`) + * `&mut Self` (i.e `&mut self`) + * [`Box<Self>`] + * [`Rc<Self>`] + * [`Arc<Self>`] + * [`Pin<P>`] where `P` is one of the types above + * Not have an opaque return type; that is, + * Not be an `async fn` (which has a hidden `Future` type). + * Not have a return position `impl Trait` type (`fn example(&self) -> impl Trait`). + * Not have a `where Self: Sized` bound (receiver type of `Self` (i.e. `self`) implies this). + * Not have a C-variadic parameter (`_: ...`). + * Explicitly non-dispatchable functions require: + * Have a `where Self: Sized` bound (receiver type of `Self` (i.e. `self`) implies this). + +r[items.traits.dyn-compatible.async-traits] +* The [`AsyncFn`], [`AsyncFnMut`], and [`AsyncFnOnce`] traits are not dyn-compatible. + +> [!NOTE] +> This concept was formerly known as *object safety*. + +```rust +# use std::rc::Rc; +# use std::sync::Arc; +# use std::pin::Pin; +// Examples of dyn compatible methods. +trait TraitMethods { + fn by_ref(self: &Self) {} + fn by_ref_mut(self: &mut Self) {} + fn by_box(self: Box<Self>) {} + fn by_rc(self: Rc<Self>) {} + fn by_arc(self: Arc<Self>) {} + fn by_pin(self: Pin<&Self>) {} + fn with_lifetime<'a>(self: &'a Self) {} + fn nested_pin(self: Pin<Arc<Self>>) {} +} +# struct S; +# impl TraitMethods for S {} +# let t: Box<dyn TraitMethods> = Box::new(S); +``` + +```rust,compile_fail +// This trait is dyn compatible, but these methods cannot be dispatched on a trait object. +trait NonDispatchable { + // Non-methods cannot be dispatched. + fn foo() where Self: Sized {} + // Self type isn't known until runtime. + fn returns(&self) -> Self where Self: Sized; + // `other` may be a different concrete type of the receiver. + fn param(&self, other: Self) where Self: Sized {} + // Generics are not compatible with vtables. + fn typed<T>(&self, x: T) where Self: Sized {} +} + +struct S; +impl NonDispatchable for S { + fn returns(&self) -> Self where Self: Sized { S } +} +let obj: Box<dyn NonDispatchable> = Box::new(S); +obj.returns(); // ERROR: cannot call with Self return +obj.param(S); // ERROR: cannot call with Self parameter +obj.typed(1); // ERROR: cannot call with generic type +``` + +```rust,compile_fail +# use std::rc::Rc; +// Examples of dyn-incompatible traits. +trait DynIncompatible { + const CONST: i32 = 1; // ERROR: cannot have associated const + + fn foo() {} // ERROR: associated function without Sized + fn returns(&self) -> Self; // ERROR: Self in return type + fn typed<T>(&self, x: T) {} // ERROR: has generic type parameters + fn nested(self: Rc<Box<Self>>) {} // ERROR: nested receiver cannot be dispatched on +} + +struct S; +impl DynIncompatible for S { + fn returns(&self) -> Self { S } +} +let obj: Box<dyn DynIncompatible> = Box::new(S); // ERROR +``` + +```rust,compile_fail +// `Self: Sized` traits are dyn-incompatible. +trait TraitWithSize where Self: Sized {} + +struct S; +impl TraitWithSize for S {} +let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR +``` + +```rust,compile_fail +// Dyn-incompatible if `Self` is a type argument. +trait Super<A> {} +trait WithSelf: Super<Self> where Self: Sized {} + +struct S; +impl<A> Super<A> for S {} +impl WithSelf for S {} +let obj: Box<dyn WithSelf> = Box::new(S); // ERROR: cannot use `Self` type parameter +``` + +r[items.traits.supertraits] +## Supertraits + +r[items.traits.supertraits.intro] +**Supertraits** are traits that are required to be implemented for a type to implement a specific trait. Furthermore, anywhere a [generic][generics] or [trait object] is bounded by a trait, it has access to the associated items of its supertraits. + +r[items.traits.supertraits.decl] +Supertraits are declared by trait bounds on the `Self` type of a trait and transitively the supertraits of the traits declared in those trait bounds. It is an error for a trait to be its own supertrait. + +r[items.traits.supertraits.subtrait] +The trait with a supertrait is called a **subtrait** of its supertrait. + +The following is an example of declaring `Shape` to be a supertrait of `Circle`. + +```rust +trait Shape { fn area(&self) -> f64; } +trait Circle: Shape { fn radius(&self) -> f64; } +``` + +And the following is the same example, except using [where clauses]. + +```rust +trait Shape { fn area(&self) -> f64; } +trait Circle where Self: Shape { fn radius(&self) -> f64; } +``` + +This next example gives `radius` a default implementation using the `area` function from `Shape`. + +```rust +# trait Shape { fn area(&self) -> f64; } +trait Circle where Self: Shape { + fn radius(&self) -> f64 { + // A = pi * r^2 + // so algebraically, + // r = sqrt(A / pi) + (self.area() / std::f64::consts::PI).sqrt() + } +} +``` + +This next example calls a supertrait method on a generic parameter. + +```rust +# trait Shape { fn area(&self) -> f64; } +# trait Circle: Shape { fn radius(&self) -> f64; } +fn print_area_and_radius<C: Circle>(c: C) { + // Here we call the area method from the supertrait `Shape` of `Circle`. + println!("Area: {}", c.area()); + println!("Radius: {}", c.radius()); +} +``` + +Similarly, here is an example of calling supertrait methods on trait objects. + +```rust +# trait Shape { fn area(&self) -> f64; } +# trait Circle: Shape { fn radius(&self) -> f64; } +# struct UnitCircle; +# impl Shape for UnitCircle { fn area(&self) -> f64 { std::f64::consts::PI } } +# impl Circle for UnitCircle { fn radius(&self) -> f64 { 1.0 } } +# let circle = UnitCircle; +let circle = Box::new(circle) as Box<dyn Circle>; +let nonsense = circle.radius() * circle.area(); +``` + +r[items.traits.safety] +## Unsafe traits + +r[items.traits.safety.intro] +Traits items that begin with the `unsafe` keyword indicate that *implementing* the trait may be [unsafe]. It is safe to use a correctly implemented unsafe trait. The [trait implementation] must also begin with the `unsafe` keyword. + +[`Sync`] and [`Send`] are examples of unsafe traits. + +r[items.traits.params] +## Parameter patterns + +r[items.traits.params.patterns-no-body] +Parameters in associated functions without a body only allow [IDENTIFIER] or `_` [wild card][WildcardPattern] patterns, as well as the form allowed by [SelfParam]. `mut` [IDENTIFIER] is currently allowed, but it is deprecated and will become a hard error in the future. +<!-- https://github.com/rust-lang/rust/issues/35203 --> + +```rust +trait T { + fn f1(&self); + fn f2(x: Self, _: i32); +} +``` + +```rust,compile_fail,E0642 +trait T { + fn f2(&x: &i32); // ERROR: patterns aren't allowed in functions without bodies +} +``` + +r[items.traits.params.patterns-with-body] +Parameters in associated functions with a body only allow irrefutable patterns. + +```rust +trait T { + fn f1((a, b): (i32, i32)) {} // OK: is irrefutable +} +``` + +```rust,compile_fail,E0005 +trait T { + fn f1(123: i32) {} // ERROR: pattern is refutable + fn f2(Some(x): Option<i32>) {} // ERROR: pattern is refutable +} +``` + +r[items.traits.params.pattern-required.edition2018] +> [!EDITION-2018] +> Prior to the 2018 edition, the pattern for an associated function parameter is optional: +> +> ```rust,edition2015 +> // 2015 Edition +> trait T { +> fn f(i32); // OK: parameter identifiers are not required +> } +> ``` +> +> Beginning in the 2018 edition, patterns are no longer optional. + +r[items.traits.params.restriction-patterns.edition2018] +> [!EDITION-2018] +> Prior to the 2018 edition, parameters in associated functions with a body are limited to the following kinds of patterns: +> +> * [IDENTIFIER] +> * `mut` [IDENTIFIER] +> * [`_`][WildcardPattern] +> * `&` [IDENTIFIER] +> * `&&` [IDENTIFIER] +> +> ```rust,edition2015,compile_fail,E0642 +> // 2015 Edition +> trait T { +> fn f1((a, b): (i32, i32)) {} // ERROR: pattern not allowed +> } +> ``` +> +> Beginning in 2018, all irrefutable patterns are allowed as described in [items.traits.params.patterns-with-body]. + +r[items.traits.associated-visibility] +## Item visibility + +r[items.traits.associated-visibility.intro] +Trait items syntactically allow a [Visibility] annotation, but this is rejected when the trait is validated. This allows items to be parsed with a unified syntax across different contexts where they are used. As an example, an empty `vis` macro fragment specifier can be used for trait items, where the macro rule may be used in other situations where visibility is allowed. + +```rust +macro_rules! create_method { + ($vis:vis $name:ident) => { + $vis fn $name(&self) {} + }; +} + +trait T1 { + // Empty `vis` is allowed. + create_method! { method_of_t1 } +} + +struct S; + +impl S { + // Visibility is allowed here. + create_method! { pub method_of_s } +} + +impl T1 for S {} + +fn main() { + let s = S; + s.method_of_t1(); + s.method_of_s(); +} +``` + +[WildcardPattern]: ../patterns.md#wildcard-pattern +[bounds]: ../trait-bounds.md +[trait object]: ../types/trait-object.md +[associated items]: associated-items.md +[method]: associated-items.md#methods +[supertraits]: #supertraits +[implementations]: implementations.md +[generics]: generics.md +[where clauses]: generics.md#where-clauses +[generic functions]: functions.md#generic-functions +[unsafe]: ../unsafety.md +[trait implementation]: implementations.md#trait-implementations +[`Send`]: ../special-types-and-traits.md#send +[`Sync`]: ../special-types-and-traits.md#sync +[`Arc<Self>`]: ../special-types-and-traits.md#arct +[`Box<Self>`]: ../special-types-and-traits.md#boxt +[`Pin<P>`]: ../special-types-and-traits.md#pinp +[`Rc<Self>`]: ../special-types-and-traits.md#rct +[`async`]: functions.md#async-functions +[`const`]: functions.md#const-functions +[type namespace]: ../names/namespaces.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/type-aliases.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/type-aliases.md new file mode 100644 index 00000000..9a9dec0e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/type-aliases.md @@ -0,0 +1,51 @@ +r[items.type] +# Type aliases + +r[items.type.syntax] +```grammar,items +TypeAlias -> + `type` IDENTIFIER GenericParams? ( `:` Bounds? )? + WhereClause? + ( `=` Type WhereClause?)? `;` +``` + +r[items.type.intro] +A _type alias_ defines a new name for an existing [type] in the [type namespace] of the module or block where it is located. Type aliases are declared with the keyword `type`. Every value has a single, specific type, but may implement several different traits, and may be compatible with several different type constraints. + +For example, the following defines the type `Point` as a synonym for the type `(u8, u8)`, the type of pairs of unsigned 8 bit integers: + +```rust +type Point = (u8, u8); +let p: Point = (41, 68); +``` + +r[items.type.constructor-alias] +A type alias to a tuple-struct or unit-struct cannot be used to qualify that type's constructor: + +```rust,compile_fail +struct MyStruct(u32); + +use MyStruct as UseAlias; +type TypeAlias = MyStruct; + +let _ = UseAlias(5); // OK +let _ = TypeAlias(5); // Doesn't work +``` + +r[items.type.associated-type] +A type alias, when not used as an [associated type], must include a [Type][grammar-Type] and may not include [Bounds]. + +r[items.type.associated-trait] +A type alias, when used as an [associated type] in a [trait], must not include a [Type][grammar-Type] specification but may include [Bounds]. + +r[items.type.associated-impl] +A type alias, when used as an [associated type] in a [trait impl], must include a [Type][grammar-Type] specification and may not include [Bounds]. + +r[items.type.deprecated] +Where clauses before the equals sign on a type alias in a [trait impl] (like `type TypeAlias<T> where T: Foo = Bar<T>`) are deprecated. Where clauses after the equals sign (like `type TypeAlias<T> = Bar<T> where T: Foo`) are preferred. + +[associated type]: associated-items.md#associated-types +[trait impl]: implementations.md#trait-implementations +[trait]: traits.md +[type namespace]: ../names/namespaces.md +[type]: ../types.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/unions.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/unions.md new file mode 100644 index 00000000..7b3d836e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/unions.md @@ -0,0 +1,191 @@ +r[items.union] +# Unions + +r[items.union.syntax] +```grammar,items +Union -> + `union` IDENTIFIER GenericParams? WhereClause? `{` StructFields? `}` +``` + +r[items.union.intro] +A union declaration uses the same syntax as a struct declaration, except with `union` in place of `struct`. + +r[items.union.namespace] +A union declaration defines the given name in the [type namespace] of the module or block where it is located. + +```rust +#[repr(C)] +union MyUnion { + f1: u32, + f2: f32, +} +``` + +r[items.union.common-storage] +The key property of unions is that all fields of a union share common storage. As a result, writes to one field of a union can overwrite its other fields, and size of a union is determined by the size of its largest field. + +r[items.union.field-restrictions] +Union field types are restricted to the following subset of types: + +r[items.union.field-copy] +- `Copy` types + +r[items.union.field-references] +- References (`&T` and `&mut T` for arbitrary `T`) + +r[items.union.field-manually-drop] +- `ManuallyDrop<T>` (for arbitrary `T`) + +r[items.union.field-tuple] +- Tuples and arrays containing only allowed union field types + +r[items.union.drop] +This restriction ensures, in particular, that union fields never need to be dropped. Like for structs and enums, it is possible to `impl Drop` for a union to manually define what happens when it gets dropped. + +r[items.union.fieldless] +Unions without any fields are not accepted by the compiler, but can be accepted by macros. + +r[items.union.init] +## Initialization of a union + +r[items.union.init.intro] +A value of a union type can be created using the same syntax that is used for struct types, except that it must specify exactly one field: + +```rust +# union MyUnion { f1: u32, f2: f32 } +# +let u = MyUnion { f1: 1 }; +``` + +r[items.union.init.result] +The expression above creates a value of type `MyUnion` and initializes the storage using field `f1`. The union can be accessed using the same syntax as struct fields: + +```rust +# union MyUnion { f1: u32, f2: f32 } +# +# let u = MyUnion { f1: 1 }; +let f = unsafe { u.f1 }; +``` + +r[items.union.fields] +## Reading and writing union fields + +r[items.union.fields.intro] +Unions have no notion of an "active field". Instead, every union access just interprets the storage as the type of the field used for the access. + +r[items.union.fields.read] +Reading a union field reads the bits of the union at the field's type. + +r[items.union.fields.offset] +Fields might have a non-zero offset (except when [the C representation] is used); in that case the bits starting at the offset of the fields are read. + +r[items.union.fields.validity] +It is the programmer's responsibility to make sure that the data is valid at the field's type. Failing to do so results in [undefined behavior]. For example, reading the value `3` from a field of the [boolean type] is undefined behavior. Effectively, writing to and then reading from a union with [the C representation] is analogous to a [`transmute`] from the type used for writing to the type used for reading. + +r[items.union.fields.read-safety] +Consequently, all reads of union fields have to be placed in `unsafe` blocks: + +```rust +# union MyUnion { f1: u32, f2: f32 } +# let u = MyUnion { f1: 1 }; +# +unsafe { + let f = u.f1; +} +``` + +Commonly, code using unions will provide safe wrappers around unsafe union field accesses. + +r[items.union.fields.write-safety] +In contrast, writes to union fields are safe, since they just overwrite arbitrary data, but cannot cause undefined behavior. (Note that union field types can never have drop glue, so a union field write will never implicitly drop anything.) + +r[items.union.pattern] +## Pattern matching on unions + +r[items.union.pattern.intro] +Another way to access union fields is to use pattern matching. + +r[items.union.pattern.one-field] +Pattern matching on union fields uses the same syntax as struct patterns, except that the pattern must specify exactly one field. + +r[items.union.pattern.safety] +Since pattern matching is like reading the union with a particular field, it has to be placed in `unsafe` blocks as well. + +```rust +# union MyUnion { f1: u32, f2: f32 } +# +fn f(u: MyUnion) { + unsafe { + match u { + MyUnion { f1: 10 } => { println!("ten"); } + MyUnion { f2 } => { println!("{}", f2); } + } + } +} +``` + +> [!WARNING] +> The order in which the subpatterns of a pattern are tested is not specified. A union field named in a pattern may be read even when the pattern as a whole does not match. Reading a union field is undefined behavior unless it holds a valid value of its type (see [items.union.fields.validity]). Nothing else in the pattern can be relied on to prevent the read. +> +> In particular, when implementing a C-style tagged union, avoid matching the tag and the corresponding union field within a single pattern: the union field may be read even when the tag does not match. +> +> To read a union field only when a condition holds, test the condition and read the field in separate steps whose evaluation order is specified. For a C tagged union, match on the tag first and read the union field within the matched arm: +> +> ```rust +> #[repr(u32)] +> enum Tag { I, F } +> +> #[repr(C)] +> union U { +> i: i32, +> f: f32, +> } +> +> #[repr(C)] +> struct Value { +> tag: Tag, +> u: U, +> } +> +> fn is_zero(v: Value) -> bool { +> match v.tag { +> Tag::I => unsafe { v.u.i == 0 }, +> Tag::F => unsafe { v.u.f == 0.0 }, +> } +> } +> ``` + +r[items.union.ref] +## References to union fields + +r[items.union.ref.intro] +Since union fields share common storage, gaining write access to one field of a union can give write access to all its remaining fields. + +r[items.union.ref.borrow] +Borrow checking rules have to be adjusted to account for this fact. As a result, if one field of a union is borrowed, all its remaining fields are borrowed as well for the same lifetime. + +```rust,compile_fail +# union MyUnion { f1: u32, f2: f32 } +// ERROR: cannot borrow `u` (via `u.f2`) as mutable more than once at a time +fn test() { + let mut u = MyUnion { f1: 1 }; + unsafe { + let b1 = &mut u.f1; +// ---- first mutable borrow occurs here (via `u.f1`) + let b2 = &mut u.f2; +// ^^^^ second mutable borrow occurs here (via `u.f2`) + *b1 = 5; + } +// - first borrow ends here + assert_eq!(unsafe { u.f1 }, 5); +} +``` + +r[items.union.ref.use] +As you could see, in many aspects (except for layouts, safety, and ownership) unions behave exactly like structs, largely as a consequence of inheriting their syntactic shape from structs. This is also true for many unmentioned aspects of Rust language (such as privacy, name resolution, type inference, generics, trait implementations, inherent implementations, coherence, pattern checking, etc etc etc). + +[`transmute`]: std::mem::transmute +[boolean type]: ../types/boolean.md +[the C representation]: ../type-layout.md#reprc-unions +[type namespace]: ../names/namespaces.md +[undefined behavior]: ../behavior-considered-undefined.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/items/use-declarations.md b/stdlib/kvlang/reference/rust/reference-repo/src/items/use-declarations.md new file mode 100644 index 00000000..24fa703f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/items/use-declarations.md @@ -0,0 +1,493 @@ +r[items.use] +# Use declarations + +r[items.use.syntax] +```grammar,items +UseDeclaration -> `use` UseTree `;` + +UseTree -> + (SimplePath? `::`)? `*` + | (SimplePath? `::`)? `{` (UseTree ( `,` UseTree )* `,`?)? `}` + | SimplePath ( `as` ( IDENTIFIER | `_` ) )? +``` + +r[items.use.intro] +A _use declaration_ creates one or more local name bindings synonymous with some other [path]. Usually a `use` declaration is used to shorten the path required to refer to a module item. These declarations may appear in [modules] and [blocks], usually at the top. A `use` declaration is also sometimes called an _import_, or, if it is public, a _re-export_. + +[path]: ../paths.md +[modules]: modules.md +[blocks]: ../expressions/block-expr.md + +r[items.use.forms] +Use declarations support a number of convenient shortcuts: + +r[items.use.forms-multiple] +* Simultaneously binding a list of paths with a common prefix, using the brace syntax `use a::b::{c, d, e::f, g::h::i};` + +r[items.use.forms-self] +* Simultaneously binding a list of paths with a common prefix and their common parent module, using the `self` keyword, such as `use a::b::{self, c, d::e};` + +r[items.use.forms-as] +* Rebinding the target name as a new local name, using the syntax `use p::q::r as x;`. This can also be used with the last two features: `use a::b::{self as ab, c as abc}`. + +r[items.use.forms-glob] +* Binding all paths matching a given prefix, using the asterisk wildcard syntax `use a::b::*;`. + +r[items.use.forms-nesting] +* Nesting groups of the previous features multiple times, such as `use a::b::{self as ab, c, d::{*, e::f}};` + +An example of `use` declarations: + +```rust +use std::collections::hash_map::{self, HashMap}; + +fn foo<T>(_: T){} +fn bar(map1: HashMap<String, usize>, map2: hash_map::HashMap<String, usize>){} + +fn main() { + // use declarations can also exist inside of functions + use std::option::Option::{Some, None}; + + // Equivalent to 'foo(vec![std::option::Option::Some(1.0f64), + // std::option::Option::None]);' + foo(vec![Some(1.0f64), None]); + + // Both `hash_map` and `HashMap` are in scope. + let map1 = HashMap::new(); + let map2 = hash_map::HashMap::new(); + bar(map1, map2); +} +``` + +r[items.use.visibility] +## `use` Visibility + +r[items.use.visibility.intro] +Like items, `use` declarations are private to the containing module, by default. Also like items, a `use` declaration can be public, if qualified by the `pub` keyword. Such a `use` declaration serves to _re-export_ a name. A public `use` declaration can therefore _redirect_ some public name to a different target definition: even a definition with a private canonical path, inside a different module. + +r[items.use.visibility.unambiguous] +If a sequence of such redirections form a cycle or cannot be resolved unambiguously, they represent a compile-time error. + +An example of re-exporting: + +```rust +mod quux { + pub use self::foo::{bar, baz}; + pub mod foo { + pub fn bar() {} + pub fn baz() {} + } +} + +fn main() { + quux::bar(); + quux::baz(); +} +``` + +In this example, the module `quux` re-exports two public names defined in `foo`. + +r[items.use.path] +## `use` Paths + +r[items.use.path.intro] +The [paths] that are allowed in a `use` item follow the [SimplePath] grammar and are similar to the paths that may be used in an expression. They may create bindings for: + +* Nameable [items] +* [Enum variants] +* [Built-in types] +* [Attributes] +* [Derive macros] +* [`macro_rules`] + +r[items.use.path.disallowed] +They cannot import [associated items], [generic parameters], [local variables], paths with [`Self`], or [tool attributes]. More restrictions are described below. + +r[items.use.path.namespace] +`use` will create bindings for all [namespaces] from the imported entities, with the exception that a `self` import will only import from the type namespace (as described below). For example, the following illustrates creating bindings for the same name in two namespaces: + +```rust +mod stuff { + pub struct Foo(pub i32); +} + +// Imports the `Foo` type and the `Foo` constructor. +use stuff::Foo; + +fn example() { + let ctor = Foo; // Uses `Foo` from the value namespace. + let x: Foo = ctor(123); // Uses `Foo` From the type namespace. +} +``` + +r[items.use.path.edition2018] +> [!EDITION-2018] +> In the 2015 edition, `use` paths are relative to the crate root. For example: +> +> ```rust,edition2015 +> mod foo { +> pub mod example { pub mod iter {} } +> pub mod baz { pub fn foobaz() {} } +> } +> mod bar { +> // Resolves `foo` from the crate root. +> use foo::example::iter; +> // The `::` prefix explicitly resolves `foo` +> // from the crate root. +> use ::foo::baz::foobaz; +> } +> +> # fn main() {} +> ``` +> +> The 2015 edition does not allow use declarations to reference the [extern prelude]. Thus, [`extern crate`] declarations are still required in 2015 to reference an external crate in a `use` declaration. Beginning with the 2018 edition, `use` declarations can specify an external crate dependency the same way `extern crate` can. + +r[items.use.as] +## `as` renames + +The `as` keyword can be used to change the name of an imported entity. For example: + +```rust +// Creates a non-public alias `bar` for the function `foo`. +use inner::foo as bar; + +mod inner { + pub fn foo() {} +} +``` + +r[items.use.multiple-syntax] +## Brace syntax + +r[items.use.multiple-syntax.intro] +Braces can be used in the last segment of the path to import multiple entities from the previous segment, or, if there are no previous segments, from the current scope. Braces can be nested, creating a tree of paths, where each grouping of segments is logically combined with its parent to create a full path. + +```rust +// Creates bindings to: +// - `std::collections::BTreeSet` +// - `std::collections::hash_map` +// - `std::collections::hash_map::HashMap` +use std::collections::{BTreeSet, hash_map::{self, HashMap}}; +``` + +r[items.use.multiple-syntax.empty] +An empty brace does not import anything, though the leading path is validated that it is accessible. +<!-- This is slightly wrong, see: https://github.com/rust-lang/rust/issues/61826 --> + +r[items.use.multiple-syntax.edition2018] +> [!EDITION-2018] +> In the 2015 edition, paths are relative to the crate root, so an import such as `use {foo, bar};` will import the names `foo` and `bar` from the crate root, whereas starting in 2018, those names are relative to the current scope. + +r[items.use.self] +## `self` imports + +r[items.use.self.intro] +The keyword `self` may be used within [brace syntax] to create a binding of the parent entity under its own name. + +```rust +mod stuff { + pub fn foo() {} + pub fn bar() {} +} +mod example { + // Creates a binding for `stuff` and `foo`. + use crate::stuff::{self, foo}; + pub fn baz() { + foo(); + stuff::bar(); + } +} +# fn main() {} +``` + +> [!NOTE] +> `self` may also be used as the first segment of a path. The use of `self` as the first segment and inside a `use` brace is logically the same; it means the current module of the parent segment, or the current module if there is no parent segment. See [`self`] in the paths chapter for more information on the meaning of a leading `self`. + +r[items.use.self.trailing] +`self` may appear as the last segment of a `use` path, preceded by `::`. A path of the form `P::self` is equivalent to `P::{self}`, and `P::self as name` is equivalent to `P::{self as name}`. + +```rust +mod m { + pub enum E { V1, V2 } +} +use m::self as _; // Equivalent to `use m::{self as _};`. +use m::E::self; // Equivalent to `use m::E::{self};`. +# fn main() {} +``` + +> [!NOTE] +> See [paths.qualifiers.mod-self.trailing] for restrictions on the preceding path. + +r[items.use.self.module] +When `self` is used within [brace syntax], the path preceding the brace group must resolve to a [module], [enumeration], or [trait]. + +```rust +mod m { + pub enum E { V1, V2 } + pub trait Tr { fn f(&self); } +} +use m::{self as _}; // OK: Modules can be parents of `self`. +use m::E::{self, V1}; // OK: Enums can be parents of `self`. +use m::Tr::{self}; // OK: Traits can be parents of `self`. +# fn main() {} +``` + +```rust,compile_fail,E0432 +struct S {} +use S::{self as _}; // ERROR: Structs cannot be parents of `self`. +# fn main() {} +``` + +r[items.use.self.namespace] +`self` only creates a binding from the [type namespace] of the parent entity. For example, in the following, only the `foo` mod is imported: + +```rust,compile_fail +mod bar { + pub mod foo {} + pub fn foo() {} +} + +// This only imports the module `foo`. The function `foo` lives in +// the value namespace and is not imported. +use bar::foo::{self}; + +fn main() { + foo(); //~ ERROR `foo` is a module +} +``` + +r[items.use.glob] +## Glob imports + +r[items.use.glob.intro] +The `*` character may be used as the last segment of a `use` path to import all importable entities from the entity of the preceding segment. For example: + +```rust +// Creates a non-public alias to `bar`. +use foo::*; + +mod foo { + fn i_am_private() {} + enum Example { + V1, + V2, + } + pub fn bar() { + // Creates local aliases to `V1` and `V2` + // of the `Example` enum. + use Example::*; + let x = V1; + } +} +``` + +r[items.use.glob.shadowing] +Items and named imports are allowed to shadow names from glob imports in the same [namespace]. That is, if there is a name already defined by another item in the same namespace, the glob import will be shadowed. For example: + +```rust +// This creates a binding to the `clashing::Foo` tuple struct +// constructor, but does not import its type because that would +// conflict with the `Foo` struct defined here. +// +// Note that the order of definition here is unimportant. +use clashing::*; +struct Foo { + field: f32, +} + +fn do_stuff() { + // Uses the constructor from `clashing::Foo`. + let f1 = Foo(123); + // The struct expression uses the type from + // the `Foo` struct defined above. + let f2 = Foo { field: 1.0 }; + // `Bar` is also in scope due to the glob import. + let z = Bar {}; +} + +mod clashing { + pub struct Foo(pub i32); + pub struct Bar {} +} +``` + +> [!NOTE] +> For areas where shadowing is not allowed, see [name resolution ambiguities]. + +r[items.use.glob.last-segment-only] +`*` cannot be used as the first or intermediate segments. + +r[items.use.glob.self-import] +`*` cannot be used to import a module's contents into itself (such as `use self::*;`). + +r[items.use.glob.edition2018] +> [!EDITION-2018] +> In the 2015 edition, paths are relative to the crate root, so an import such as `use *;` is valid, and it means to import everything from the crate root. This cannot be used in the crate root itself. + +r[items.use.as-underscore] +## Underscore imports + +r[items.use.as-underscore.intro] +Items can be imported without binding to a name by using an underscore with the form `use path as _`. This is particularly useful to import a trait so that its methods may be used without importing the trait's symbol, for example if the trait's symbol may conflict with another symbol. Another example is to link an external crate without importing its name. + +```rust +mod foo { + pub trait Zoo { + fn zoo(&self) {} + } + + impl<T> Zoo for T {} +} + +use self::foo::Zoo as _; +struct Zoo; // Underscore import avoids name conflict with this item. + +fn main() { + let z = Zoo; + z.zoo(); +} +``` + +r[items.use.as-underscore.glob] +Asterisk glob imports will import items imported with `_` in their unnameable form. + +r[items.use.as-underscore.macro] +The unique, unnameable symbols are created after macro expansion so that macros may safely emit multiple references to `_` imports. For example, the following should not produce an error: + +```rust +macro_rules! m { + ($item: item) => { $item $item } +} + +m!(use std as _;); +// This expands to: +// use std as _; +// use std as _; +``` + +r[items.use.restrictions] +## Restrictions + +r[items.use.restrictions.intro] +The following rules are restrictions for valid `use` declarations. + +r[items.use.restrictions.crate-alias] +When using `crate` to import the current crate, you must use `as` to define the binding name. + +> [!EXAMPLE] +> ```rust +> use crate as root; +> use crate::{self as root2}; +> +> // Not allowed: +> // use crate; +> // use crate::{self}; +> ``` + +r[items.use.restrictions.macro-crate-alias] +When using [`$crate`] in a macro transcriber to import the current crate, you must use `as` to define the binding name. + +> [!EXAMPLE] +> ```rust +> macro_rules! import_crate_root { +> () => { +> use $crate as my_crate; +> use $crate::{self as my_crate2}; +> }; +> } +> ``` + +r[items.use.restrictions.self-alias] +When using `self` to import the current module, you must use `as` to define the binding name. + +> [!EXAMPLE] +> ```rust +> use {self as this_module}; +> use self as this_module2; +> use self::{self as this_module3}; +> +> // Not allowed: +> // use {self}; +> // use self; +> // use self::{self}; +> ``` + +r[items.use.restrictions.super-alias] +When using `super` to import a parent module, you must use `as` to define the binding name. + +> [!EXAMPLE] +> ```rust +> mod a { +> mod b { +> use super as parent; +> use super::{self as parent2}; +> use self::super as parent3; +> use super::super as grandparent; +> use super::super::{self as grandparent2}; +> +> // Not allowed: +> // use super; +> // use super::{self}; +> // use self::super; +> // use super::super; +> // use super::super::{self}; +> } +> } +> ``` + +r[items.use.restrictions.extern-prelude] +`::` as the [extern prelude] cannot be imported. + +> [!EXAMPLE] +> ```rust,edition2018,compile_fail +> use ::{self as root}; //~ Error +> ``` + +> [!EDITION-2018] +> In the 2015 edition, the prefix `::` refers to the crate root, so `use ::{self as root};` is allowed because it is same as `use crate::{self as root};`. Starting with the 2018 edition the `::` prefix refers to the extern prelude, which cannot be directly imported. +> +> ```rust,edition2015 +> use ::{self as root}; //~ Ok +> ``` + +r[items.use.restrictions.duplicate-name] +As with any item definition, `use` imports cannot create duplicate bindings of the same name in the same namespace in a module or block. + +r[items.use.restrictions.variant] +`use` paths cannot refer to enum variants through a [type alias]. + +> [!EXAMPLE] +> ```rust,compile_fail +> enum MyEnum { +> MyVariant +> } +> type TypeAlias = MyEnum; +> +> use MyEnum::MyVariant; //~ OK +> use TypeAlias::MyVariant; //~ ERROR +> ``` + +[`$crate`]: paths.qualifiers.macro-crate +[Attributes]: ../attributes.md +[brace syntax]: items.use.multiple-syntax +[Built-in types]: ../types.md +[Derive macros]: macro.proc.derive +[Enum variants]: enumerations.md +[enumeration]: items.enum +[`extern crate`]: extern-crates.md +[`macro_rules`]: ../macros-by-example.md +[`self`]: ../paths.md#self +[associated items]: associated-items.md +[extern prelude]: ../names/preludes.md#extern-prelude +[generic parameters]: generics.md +[items]: ../items.md +[local variables]: ../variables.md +[module]: items.mod +[name resolution ambiguities]: names.resolution.expansion.imports.ambiguity +[namespace]: ../names/namespaces.md +[namespaces]: ../names/namespaces.md +[paths]: ../paths.md +[tool attributes]: ../attributes.md#tool-attributes +[trait]: items.traits +[type alias]: type-aliases.md +[type namespace]: ../names/namespaces.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/keywords.md b/stdlib/kvlang/reference/rust/reference-repo/src/keywords.md new file mode 100644 index 00000000..33aee602 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/keywords.md @@ -0,0 +1,167 @@ +r[lex.keywords] +# Keywords + +r[lex.keywords.intro] +Rust divides keywords into three categories: + +* [strict](#strict-keywords) +* [reserved](#reserved-keywords) +* [weak](#weak-keywords) + +r[lex.keywords.strict] +## Strict keywords + +r[lex.keywords.strict.intro] +Strict keywords can only be used in their correct contexts. They cannot be used as the names of: + +* [Items] +* [Variables] and function parameters +* Fields and [variants] +* [Type parameters] +* Lifetime parameters or [loop labels] +* [Macros] or [attributes] +* [Macro placeholders] +* [Crates] + +r[lex.keywords.strict.syntax] +```grammar,lexer +@root STRICT_KEYWORDS -> + `_` + | `as` + | `async` + | `await` + | `break` + | `const` + | `continue` + | `crate` + | `dyn` + | `else` + | `enum` + | `extern` + | `false` + | `fn` + | `for` + | `if` + | `impl` + | `in` + | `let` + | `loop` + | `match` + | `mod` + | `move` + | `mut` + | `pub` + | `ref` + | `return` + | `self` + | `Self` + | `static` + | `struct` + | `super` + | `trait` + | `true` + | `type` + | `unsafe` + | `use` + | `where` + | `while` +``` + +r[lex.keywords.strict.edition2018] +> [!EDITION-2018] +> The following keywords were added in the 2018 edition: +> +> - `async` +> - `await` +> - `dyn` + +r[lex.keywords.reserved] +## Reserved keywords + +r[lex.keywords.reserved.intro] +Reserved keywords aren't used yet, but they are reserved for future use. They have the same restrictions as strict keywords. The reasoning behind this is to make current programs forward compatible with future versions of Rust by forbidding them to use these keywords. + +r[lex.keywords.reserved.syntax] +```grammar,lexer +@root RESERVED_KEYWORDS -> + `abstract` + | `become` + | `box` + | `do` + | `final` + | `gen` + | `macro` + | `override` + | `priv` + | `try` + | `typeof` + | `unsized` + | `virtual` + | `yield` +``` + +r[lex.keywords.reserved.edition2018] +> [!EDITION-2018] +> The `try` keyword was added as a reserved keyword in the 2018 edition. + +r[lex.keywords.reserved.edition2024] +> [!EDITION-2024] +> The `gen` keyword was added as a reserved keyword in the 2024 edition. + +r[lex.keywords.weak] +## Weak keywords + +r[lex.keywords.weak.intro] +Weak keywords have special meaning only in certain contexts. For example, it is possible to declare a variable or method with the name `union`. + +r[lex.keywords.weak.syntax] +```grammar,lexer +@root WEAK_KEYWORDS -> + `'static` + | `macro_rules` + | `raw` + | `safe` + | `union` +``` + +r[lex.keywords.weak.macro_rules] +* `macro_rules` is used to create custom [macros]. + +r[lex.keywords.weak.union] +* `union` is used to declare a [union] and is only a keyword when used in a union declaration. + +r[lex.keywords.weak.lifetime-static] +* `'static` is used for the static lifetime and cannot be used as a [generic lifetime parameter] or [loop label] + + ```compile_fail + // error[E0262]: invalid lifetime parameter name: `'static` + fn invalid_lifetime_parameter<'static>(s: &'static str) -> &'static str { s } + ``` + +r[lex.keywords.weak.safe] +* `safe` is used for functions and statics, which has meaning in [external blocks]. + +r[lex.keywords.weak.raw] +* `raw` is used for [raw borrow operators], and is only a keyword when matching a raw borrow operator form (such as `&raw const expr` or `&raw mut expr`). + +r[lex.keywords.weak.dyn.edition2018] +> [!EDITION-2018] +> In the 2015 edition, [`dyn`] is a keyword when used in a type position followed by a path that does not start with `::` or `<`, a lifetime, a question mark, a `for` keyword or an opening parenthesis. +> +> Beginning in the 2018 edition, `dyn` has been promoted to a strict keyword. + +[items]: items.md +[Variables]: variables.md +[Type parameters]: types/parameters.md +[loop labels]: expressions/loop-expr.md#loop-labels +[Macros]: macros.md +[attributes]: attributes.md +[Macro placeholders]: macros-by-example.md +[Crates]: crates-and-source-files.md +[union]: items/unions.md +[variants]: items/enumerations.md +[`dyn`]: types/trait-object.md +[loop label]: expressions/loop-expr.md#loop-labels +[generic lifetime parameter]: items/generics.md +[external blocks]: items/external-blocks.md +[raw borrow operators]: expressions/operator-expr.md#raw-borrow-operators diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/lexical-structure.md b/stdlib/kvlang/reference/rust/reference-repo/src/lexical-structure.md new file mode 100644 index 00000000..d70e97ac --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/lexical-structure.md @@ -0,0 +1,3 @@ +# Lexical structure + +<!-- Editor Note: Oh, there's nothing here --> diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/lifetime-elision.md b/stdlib/kvlang/reference/rust/reference-repo/src/lifetime-elision.md new file mode 100644 index 00000000..a4a372ea --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/lifetime-elision.md @@ -0,0 +1,226 @@ +r[lifetime-elision] +# Lifetime elision + +r[lifetime-elision.intro] +Rust has rules that allow lifetimes to be elided in various places where the compiler can infer a sensible default choice. + +r[lifetime-elision.function] +## Lifetime elision in functions + +r[lifetime-elision.function.intro] +In order to make common patterns more ergonomic, lifetime arguments can be *elided* in [function item], [function pointer], and [closure trait] signatures. The following rules are used to infer lifetime parameters for elided lifetimes. + +r[lifetime-elision.function.lifetimes-not-inferred] +It is an error to elide lifetime parameters that cannot be inferred. + +r[lifetime-elision.function.explicit-placeholder] +The placeholder lifetime, `'_`, can also be used to have a lifetime inferred in the same way. For lifetimes in paths, using `'_` is preferred. + +r[lifetime-elision.function.only-functions] +Trait object lifetimes follow different rules discussed [below](#default-trait-object-lifetimes). + +r[lifetime-elision.function.implicit-lifetime-parameters] +* Each elided lifetime in the parameters becomes a distinct lifetime parameter. + +r[lifetime-elision.function.output-lifetime] +* If there is exactly one lifetime used in the parameters (elided or not), that lifetime is assigned to *all* elided output lifetimes. + +r[lifetime-elision.function.receiver-lifetime] +In method signatures there is another rule + +* If the receiver has type `&Self` or `&mut Self`, then the lifetime of that reference to `Self` is assigned to all elided output lifetime parameters. + +Examples: + +```rust +# trait T {} +# trait ToCStr {} +# struct Thing<'a> {f: &'a i32} +# struct Command; +# +# trait Example { +fn print1(s: &str); // elided +fn print2(s: &'_ str); // also elided +fn print3<'a>(s: &'a str); // expanded + +fn debug1(lvl: usize, s: &str); // elided +fn debug2<'a>(lvl: usize, s: &'a str); // expanded + +fn substr1(s: &str, until: usize) -> &str; // elided +fn substr2<'a>(s: &'a str, until: usize) -> &'a str; // expanded + +fn get_mut1(&mut self) -> &mut dyn T; // elided +fn get_mut2<'a>(&'a mut self) -> &'a mut dyn T; // expanded + +fn args1<T: ToCStr>(&mut self, args: &[T]) -> &mut Command; // elided +fn args2<'a, 'b, T: ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command; // expanded + +fn other_args1<'a>(arg: &str) -> &'a str; // elided +fn other_args2<'a, 'b>(arg: &'b str) -> &'a str; // expanded + +fn new1(buf: &mut [u8]) -> Thing<'_>; // elided - preferred +fn new2(buf: &mut [u8]) -> Thing; // elided +fn new3<'a>(buf: &'a mut [u8]) -> Thing<'a>; // expanded +# } + +type FunPtr1 = fn(&str) -> &str; // elided +type FunPtr2 = for<'a> fn(&'a str) -> &'a str; // expanded + +type FunTrait1 = dyn Fn(&str) -> &str; // elided +type FunTrait2 = dyn for<'a> Fn(&'a str) -> &'a str; // expanded +``` + +```rust,compile_fail +// The following examples show situations where it is not allowed to elide the +// lifetime parameter. + +# trait Example { +// Cannot infer, because there are no parameters to infer from. +fn get_str() -> &str; // ILLEGAL + +// Cannot infer, ambiguous if it is borrowed from the first or second parameter. +fn frob(s: &str, t: &str) -> &str; // ILLEGAL +# } +``` + +r[lifetime-elision.trait-object] +## Default trait object lifetimes + +r[lifetime-elision.trait-object.intro] +The assumed lifetime of references held by a [trait object] is called its _default object lifetime bound_. These were defined in [RFC 599] and amended in [RFC 1156]. + +r[lifetime-elision.trait-object.explicit-bound] +These default object lifetime bounds are used instead of the lifetime parameter elision rules defined above when the lifetime bound is omitted entirely. + +r[lifetime-elision.trait-object.explicit-placeholder] +If `'_` is used as the lifetime bound then the bound follows the usual elision rules. + +r[lifetime-elision.trait-object.containing-type] +If the trait object is used as a type argument of a generic type then the containing type is first used to try to infer a bound. + +r[lifetime-elision.trait-object.containing-type-unique] +* If there is a unique bound from the containing type then that is the default. + +r[lifetime-elision.trait-object.containing-type-explicit] +* If there is more than one bound from the containing type then an explicit bound must be specified. + +r[lifetime-elision.trait-object.trait-bounds] +If neither of those rules apply, then the bounds on the trait are used: + +r[lifetime-elision.trait-object.trait-unique] +* If the trait is defined with a single lifetime _bound_ then that bound is used. + +r[lifetime-elision.trait-object.static-lifetime] +* If `'static` is used for any lifetime bound then `'static` is used. + +r[lifetime-elision.trait-object.default] +* If the trait has no lifetime bounds, then the lifetime is inferred in expressions and is `'static` outside of expressions. + +```rust +// For the following trait... +trait Foo { } + +// These two are the same because Box<T> has no lifetime bound on T +type T1 = Box<dyn Foo>; +type T2 = Box<dyn Foo + 'static>; + +// ...and so are these: +impl dyn Foo {} +impl dyn Foo + 'static {} + +// ...so are these, because &'a T requires T: 'a +type T3<'a> = &'a dyn Foo; +type T4<'a> = &'a (dyn Foo + 'a); + +// std::cell::Ref<'a, T> also requires T: 'a, so these are the same +type T5<'a> = std::cell::Ref<'a, dyn Foo>; +type T6<'a> = std::cell::Ref<'a, dyn Foo + 'a>; +``` + +```rust,compile_fail +// This is an example of an error. +# trait Foo { } +struct TwoBounds<'a, 'b, T: ?Sized + 'a + 'b> { + f1: &'a i32, + f2: &'b i32, + f3: T, +} +type T7<'a, 'b> = TwoBounds<'a, 'b, dyn Foo>; +// ^^^^^^^ +// Error: the lifetime bound for this object type cannot be deduced from context +``` + +r[lifetime-elision.trait-object.innermost-type] +Note that the innermost object sets the bound, so `&'a Box<dyn Foo>` is still `&'a Box<dyn Foo + 'static>`. + +```rust +// For the following trait... +trait Bar<'a>: 'a { } + +// ...these two are the same: +type T1<'a> = Box<dyn Bar<'a>>; +type T2<'a> = Box<dyn Bar<'a> + 'a>; + +// ...and so are these: +impl<'a> dyn Bar<'a> {} +impl<'a> dyn Bar<'a> + 'a {} +``` + +r[lifetime-elision.const-static] +## `const` and `static` elision + +r[lifetime-elision.const-static.implicit-static] +Both [constant] and [static] declarations of reference types have *implicit* `'static` lifetimes unless an explicit lifetime is specified. As such, the constant declarations involving `'static` above may be written without the lifetimes. + +```rust +// STRING: &'static str +const STRING: &str = "bitstring"; + +struct BitsNStrings<'a> { + mybits: [u32; 2], + mystring: &'a str, +} + +// BITS_N_STRINGS: BitsNStrings<'static> +const BITS_N_STRINGS: BitsNStrings<'_> = BitsNStrings { + mybits: [1, 2], + mystring: STRING, +}; +``` + +r[lifetime-elision.const-static.fn-references] +Note that if the `static` or `const` items include function or closure references, which themselves include references, the compiler will first try the standard elision rules. If it is unable to resolve the lifetimes by its usual rules, then it will error. By way of example: + +```rust +# struct Foo; +# struct Bar; +# struct Baz; +# fn somefunc(a: &Foo, b: &Bar, c: &Baz) -> usize {42} +// Resolved as `for<'a> fn(&'a str) -> &'a str`. +const RESOLVED_SINGLE: fn(&str) -> &str = |x| x; + +// Resolved as `for<'a, 'b, 'c> Fn(&'a Foo, &'b Bar, &'c Baz) -> usize`. +const RESOLVED_MULTIPLE: &dyn Fn(&Foo, &Bar, &Baz) -> usize = &somefunc; +``` + +```rust,compile_fail +# struct Foo; +# struct Bar; +# struct Baz; +# fn somefunc<'a,'b>(a: &'a Foo, b: &'b Bar) -> &'a Baz {unimplemented!()} +// There is insufficient information to bound the return reference lifetime +// relative to the argument lifetimes, so this is an error. +const RESOLVED_STATIC: &dyn Fn(&Foo, &Bar) -> &Baz = &somefunc; +// ^ +// this function's return type contains a borrowed value, but the signature +// does not say whether it is borrowed from argument 1 or argument 2 +``` + +[closure trait]: types/closure.md +[constant]: items/constant-items.md +[function item]: types/function-item.md +[function pointer]: types/function-pointer.md +[RFC 599]: https://github.com/rust-lang/rfcs/blob/master/text/0599-default-object-bound.md +[RFC 1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md +[static]: items/static-items.md +[trait object]: types/trait-object.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/linkage.md b/stdlib/kvlang/reference/rust/reference-repo/src/linkage.md new file mode 100644 index 00000000..5f5dd9b8 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/linkage.md @@ -0,0 +1,183 @@ +r[link] +# Linkage + +r[link.intro] +> [!NOTE] +> This section is described more in terms of the compiler than of the language. + +The compiler supports various methods to link crates together both statically and dynamically. This section will explore the various methods to link crates together, and more information about native libraries can be found in the [FFI section of the book][ffi]. + +[ffi]: ../book/ch20-01-unsafe-rust.html#using-extern-functions-to-call-external-code + +r[link.type] +In one session of compilation, the compiler can generate multiple artifacts through the use of either command line flags or the `crate_type` attribute. If one or more command line flags are specified, all `crate_type` attributes will be ignored in favor of only building the artifacts specified by command line. + +r[link.bin] +* `--crate-type=bin`, `#![crate_type = "bin"]` - A runnable executable will be produced. This requires that there is a `main` function in the crate which will be run when the program begins executing. This will link in all Rust and native dependencies, producing a single distributable binary. This is the default crate type. + +r[link.lib] +* `--crate-type=lib`, `#![crate_type = "lib"]` - A Rust library will be produced. This is an ambiguous concept as to what exactly is produced because a library can manifest itself in several forms. The purpose of this generic `lib` option is to generate the "compiler recommended" style of library. The output library will always be usable by rustc, but the actual type of library may change from time-to-time. The remaining output types are all different flavors of libraries, and the `lib` type can be seen as an alias for one of them (but the actual one is compiler-defined). + +r[link.dylib] +* `--crate-type=dylib`, `#![crate_type = "dylib"]` - A dynamic Rust library will be produced. This is different from the `lib` output type in that this forces dynamic library generation. The resulting dynamic library can be used as a dependency for other libraries and/or executables. This output type will create `*.so` files on Linux, `*.dylib` files on macOS, and `*.dll` files on Windows. + +r[link.staticlib] +* `--crate-type=staticlib`, `#![crate_type = "staticlib"]` - A static system library will be produced. This is different from other library outputs in that the compiler will never attempt to link to `staticlib` outputs. The purpose of this output type is to create a static library containing all of the local crate's code along with all upstream dependencies. This output type will create `*.a` files on Linux, macOS and Windows (MinGW), and `*.lib` files on Windows (MSVC). This format is recommended for use in situations such as linking Rust code into an existing non-Rust application because it will not have dynamic dependencies on other Rust code. + + Note that any dynamic dependencies that the static library may have (such as dependencies on system libraries, or dependencies on Rust libraries that are compiled as dynamic libraries) will have to be specified manually when linking that static library from somewhere. The `--print=native-static-libs` flag may help with this. + + Note that, because the resulting static library contains the code of all the dependencies, including the standard library, and also exports all public symbols of them, linking the static library into an executable or shared library may need special care. In case of a shared library the list of exported symbols will have to be limited via e.g. a linker or symbol version script, exported symbols list (macOS), or module definition file (Windows). Additionally, unused sections can be removed to remove all code of dependencies that is not actually used (e.g. `--gc-sections` or `-dead_strip` for macOS). + +r[link.cdylib] +* `--crate-type=cdylib`, `#![crate_type = "cdylib"]` - A dynamic system library will be produced. This is used when compiling a dynamic library to be loaded from another language. This output type will create `*.so` files on Linux, `*.dylib` files on macOS, and `*.dll` files on Windows. + +r[link.rlib] +* `--crate-type=rlib`, `#![crate_type = "rlib"]` - A "Rust library" file will be produced. This is used as an intermediate artifact and can be thought of as a "static Rust library". These `rlib` files, unlike `staticlib` files, are interpreted by the compiler in future linkage. This essentially means that `rustc` will look for metadata in `rlib` files like it looks for metadata in dynamic libraries. This form of output is used to produce statically linked executables as well as `staticlib` outputs. + +r[link.proc-macro] +* `--crate-type=proc-macro`, `#![crate_type = "proc-macro"]` - The output produced is not specified, but if a `-L` path is provided to it then the compiler will recognize the output artifacts as a macro and it can be loaded for a program. Crates compiled with this crate type must only export [procedural macros]. The compiler will automatically set the `proc_macro` [configuration option]. The crates are always compiled with the same target that the compiler itself was built with. For example, if you are executing the compiler from Linux with an `x86_64` CPU, the target will be `x86_64-unknown-linux-gnu` even if the crate is a dependency of another crate being built for a different target. + +r[link.repetition] +Note that these outputs are stackable in the sense that if multiple are specified, then the compiler will produce each form of output without having to recompile. However, this only applies for outputs specified by the same method. If only `crate_type` attributes are specified, then they will all be built, but if one or more `--crate-type` command line flags are specified, then only those outputs will be built. + +r[link.dependency] +With all these different kinds of outputs, if crate A depends on crate B, then the compiler could find B in various different forms throughout the system. The only forms looked for by the compiler, however, are the `rlib` format and the dynamic library format. With these two options for a dependent library, the compiler must at some point make a choice between these two formats. With this in mind, the compiler follows these rules when determining what format of dependencies will be used: + +r[link.dependency-staticlib] +1. If a static library is being produced, all upstream dependencies are required to be available in `rlib` formats. This requirement stems from the reason that a dynamic library cannot be converted into a static format. + + Note that it is impossible to link in native dynamic dependencies to a static library, and in this case warnings will be printed about all unlinked native dynamic dependencies. + +r[link.dependency-rlib] + +2. If an `rlib` file is being produced, then there are no restrictions on what format the upstream dependencies are available in. It is simply required that all upstream dependencies be available for reading metadata from. + + The reason for this is that `rlib` files do not contain any of their upstream dependencies. It wouldn't be very efficient for all `rlib` files to contain a copy of `libstd.rlib`! + +r[link.dependency-prefer-dynamic] + +3. If an executable is being produced and the `-C prefer-dynamic` flag is not specified, then dependencies are first attempted to be found in the `rlib` format. If some dependencies are not available in an rlib format, then dynamic linking is attempted (see below). + +r[link.dependency-dynamic] + +4. If a dynamic library or an executable that is being dynamically linked is being produced, then the compiler will attempt to reconcile the available dependencies in either the rlib or dylib format to create a final product. + + A major goal of the compiler is to ensure that a library never appears more than once in any artifact. For example, if dynamic libraries B and C were each statically linked to library A, then a crate could not link to B and C together because there would be two copies of A. The compiler allows mixing the rlib and dylib formats, but this restriction must be satisfied. + + The compiler currently implements no method of hinting what format a library should be linked with. When dynamically linking, the compiler will attempt to maximize dynamic dependencies while still allowing some dependencies to be linked in via an rlib. + + For most situations, having all libraries available as a dylib is recommended if dynamically linking. For other situations, the compiler will emit a warning if it is unable to determine which formats to link each library with. + +In general, `--crate-type=bin` or `--crate-type=lib` should be sufficient for all compilation needs, and the other options are just available if more fine-grained control is desired over the output format of a crate. + +r[link.crt] +## Static and dynamic C runtimes + +r[link.crt.intro] +The standard library in general strives to support both statically linked and dynamically linked C runtimes for targets as appropriate. For example the `x86_64-pc-windows-msvc` and `x86_64-unknown-linux-musl` targets typically come with both runtimes and the user selects which one they'd like. All targets in the compiler have a default mode of linking to the C runtime. Typically targets are linked dynamically by default, but there are exceptions which are static by default such as: + +* `arm-unknown-linux-musleabi` +* `arm-unknown-linux-musleabihf` +* `armv7-unknown-linux-musleabihf` +* `i686-unknown-linux-musl` +* `x86_64-unknown-linux-musl` + +r[link.crt.crt-static] +The linkage of the C runtime is configured to respect the `crt-static` target feature. These target features are typically configured from the command line via flags to the compiler itself. For example to enable a static runtime you would execute: + +```sh +rustc -C target-feature=+crt-static foo.rs +``` + +whereas to link dynamically to the C runtime you would execute: + +```sh +rustc -C target-feature=-crt-static foo.rs +``` + +r[link.crt.ineffective] +Targets which do not support switching between linkage of the C runtime will ignore this flag. It's recommended to inspect the resulting binary to ensure that it's linked as you would expect after the compiler succeeds. + +r[link.crt.target_feature] +Crates may also learn about how the C runtime is being linked. Code on MSVC, for example, needs to be compiled differently (e.g. with `/MT` or `/MD`) depending on the runtime being linked. This is exported currently through the [`cfg` attribute `target_feature` option]: + +```rust +#[cfg(target_feature = "crt-static")] +fn foo() { + println!("the C runtime should be statically linked"); +} + +#[cfg(not(target_feature = "crt-static"))] +fn foo() { + println!("the C runtime should be dynamically linked"); +} +``` + +Also note that Cargo build scripts can learn about this feature through [environment variables][cargo]. In a build script you can detect the linkage via: + +```rust +use std::env; + +fn main() { + let linkage = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new()); + + if linkage.contains("crt-static") { + println!("the C runtime will be statically linked"); + } else { + println!("the C runtime will be dynamically linked"); + } +} +``` + +[cargo]: ../cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts + +To use this feature locally, you typically will use the `RUSTFLAGS` environment variable to specify flags to the compiler through Cargo. For example to compile a statically linked binary on MSVC you would execute: + +```sh +RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-pc-windows-msvc +``` + +r[link.foreign-code] +## Mixed Rust and foreign codebases + +r[link.foreign-code.foreign-linkers] +If you are mixing Rust with foreign code (e.g. C, C++) and wish to make a single binary containing both types of code, you have two approaches for the final binary link: + +* Use `rustc`. Pass any non-Rust libraries using `-L <directory>` and `-l<library>` rustc arguments, and/or `#[link]` directives in your Rust code. If you need to link against `.o` files you can use `-Clink-arg=file.o`. +* Use your foreign linker. In this case, you first need to generate a Rust `staticlib` target and pass that into your foreign linker invocation. If you need to link multiple Rust subsystems, you will need to generate a _single_ `staticlib` perhaps using lots of `extern crate` statements to include multiple Rust `rlib`s. Multiple Rust `staticlib` files are likely to conflict. + +Passing `rlib`s directly into your foreign linker is currently unsupported. + +> [!NOTE] +> Rust code compiled or linked with a different instance of the Rust runtime counts as "foreign code" for the purpose of this section. + +r[link.unwinding] +### Prohibited linkage and unwinding + +r[link.unwinding.intro] +Panic unwinding can only be used if the binary is built consistently according to the following rules. + +r[link.unwinding.potential] +A Rust artifact is called *potentially unwinding* if any of the following conditions is met: +- The artifact uses the [`unwind` panic handler][panic.panic_handler]. +- The artifact contains a crate built with the `unwind` [panic strategy] that makes a call to a function using a `-unwind` ABI. +- The artifact makes a `"Rust"` ABI call to code running in another Rust artifact that has a separate copy of the Rust runtime, and that other artifact is potentially unwinding. + +> [!NOTE] +> This definition captures whether a `"Rust"` ABI call inside a Rust artifact can ever unwind. + +r[link.unwinding.prohibited] +If a Rust artifact is potentially unwinding, then all its crates must be built with the `unwind` [panic strategy]. Otherwise, unwinding can cause undefined behavior. + +> [!NOTE] +> If you are using `rustc` to link, these rules are enforced automatically. If you are *not* using `rustc` to link, you must take care to ensure that unwinding is handled consistently across the entire binary. Linking without `rustc` includes using `dlopen` or similar facilities where linking is done by the system runtime without `rustc` being involved. This can only happen when mixing code with different [`-C panic`] flags, so most users do not have to be concerned about this. + +> [!NOTE] +> To guarantee that a library will be sound (and linkable with `rustc`) regardless of the panic runtime used at link-time, the [`ffi_unwind_calls` lint] may be used. The lint flags any calls to `-unwind` foreign functions or function pointers. + +[`cfg` attribute `target_feature` option]: conditional-compilation.md#target_feature +[`ffi_unwind_calls` lint]: ../rustc/lints/listing/allowed-by-default.html#ffi-unwind-calls +[configuration option]: conditional-compilation.md +[procedural macros]: procedural-macros.md +[panic strategy]: panic.md#panic-strategy +[`-C panic`]: ../rustc/codegen-options/index.html#panic diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/macro-ambiguity.md b/stdlib/kvlang/reference/rust/reference-repo/src/macro-ambiguity.md new file mode 100644 index 00000000..959b60e1 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/macro-ambiguity.md @@ -0,0 +1,299 @@ +r[macro.ambiguity] +# Appendix: Macro follow-set ambiguity formal specification + +r[macro.ambiguity.intro] +This page documents the formal specification of the follow rules for [Macros By Example]. They were originally specified in [RFC 550], from which the bulk of this text is copied, and expanded upon in subsequent RFCs. + +r[macro.ambiguity.convention] +## Definitions & conventions + +r[macro.ambiguity.convention.defs] + - `macro`: anything invocable as `foo!(...)` in source code. + - `MBE`: macro-by-example, a macro defined by `macro_rules`. + - `matcher`: the left-hand-side of a rule in a `macro_rules` invocation, or a subportion thereof. + - `macro parser`: the bit of code in the Rust parser that will parse the input using a grammar derived from all of the matchers. + - `fragment`: The class of Rust syntax that a given matcher will accept (or "match"). + - `repetition` : a fragment that follows a regular repeating pattern + - `NT`: non-terminal, the various "meta-variables" or repetition matchers that can appear in a matcher, specified in MBE syntax with a leading `$` character. + - `simple NT`: a "meta-variable" non-terminal (further discussion below). + - `complex NT`: a repetition matching non-terminal, specified via repetition operators (`*`, `+`, `?`). + - `token`: an atomic element of a matcher; i.e. identifiers, operators, open/close delimiters, *and* simple NT's. + - `token tree`: a tree structure formed from tokens (the leaves), complex NT's, and finite sequences of token trees. + - `delimiter token`: a token that is meant to divide the end of one fragment and the start of the next fragment. + - `separator token`: an optional delimiter token in an complex NT that separates each pair of elements in the matched repetition. + - `separated complex NT`: a complex NT that has its own separator token. + - `delimited sequence`: a sequence of token trees with appropriate open- and close-delimiters at the start and end of the sequence. + - `empty fragment`: The class of invisible Rust syntax that separates tokens, i.e. whitespace, or (in some lexical contexts), the empty token sequence. + - `fragment specifier`: The identifier in a simple NT that specifies which fragment the NT accepts. + - `language`: a context-free language. + +Example: + +```rust,compile_fail +macro_rules! i_am_an_mbe { + (start $foo:expr $($i:ident),* end) => ($foo) +} +``` + +r[macro.ambiguity.convention.matcher] +`(start $foo:expr $($i:ident),* end)` is a matcher. The whole matcher is a delimited sequence (with open- and close-delimiters `(` and `)`), and `$foo` and `$i` are simple NT's with `expr` and `ident` as their respective fragment specifiers. + +r[macro.ambiguity.convention.complex-nt] +`$(i:ident),*` is *also* an NT; it is a complex NT that matches a comma-separated repetition of identifiers. The `,` is the separator token for the complex NT; it occurs in between each pair of elements (if any) of the matched fragment. + +Another example of a complex NT is `$(hi $e:expr ;)+`, which matches any fragment of the form `hi <expr>; hi <expr>; ...` where `hi <expr>;` occurs at least once. Note that this complex NT does not have a dedicated separator token. + +(Note that Rust's parser ensures that delimited sequences always occur with proper nesting of token tree structure and correct matching of open- and close-delimiters.) + +r[macro.ambiguity.convention.vars] +We will tend to use the variable "M" to stand for a matcher, variables "t" and "u" for arbitrary individual tokens, and the variables "tt" and "uu" for arbitrary token trees. (The use of "tt" does present potential ambiguity with its additional role as a fragment specifier; but it will be clear from context which interpretation is meant.) + +r[macro.ambiguity.convention.set] +"SEP" will range over separator tokens, "OP" over the repetition operators `*`, `+`, and `?`, "OPEN"/"CLOSE" over matching token pairs surrounding a delimited sequence (e.g. `[` and `]`). + +r[macro.ambiguity.convention.sequence-vars] +Greek letters "α" "β" "γ" "δ" stand for potentially empty token-tree sequences. (However, the Greek letter "ε" (epsilon) has a special role in the presentation and does not stand for a token-tree sequence.) + + * This Greek letter convention is usually just employed when the presence of a sequence is a technical detail; in particular, when we wish to *emphasize* that we are operating on a sequence of token-trees, we will use the notation "tt ..." for the sequence, not a Greek letter. + +Note that a matcher is merely a token tree. A "simple NT", as mentioned above, is an meta-variable NT; thus it is a non-repetition. For example, `$foo:ty` is a simple NT but `$($foo:ty)+` is a complex NT. + +Note also that in the context of this formalism, the term "token" generally *includes* simple NTs. + +Finally, it is useful for the reader to keep in mind that according to the definitions of this formalism, no simple NT matches the empty fragment, and likewise no token matches the empty fragment of Rust syntax. (Thus, the *only* NT that can match the empty fragment is a complex NT.) This is not actually true, because the `vis` matcher can match an empty fragment. Thus, for the purposes of the formalism, we will treat `$v:vis` as actually being `$($v:vis)?`, with a requirement that the matcher match an empty fragment. + +r[macro.ambiguity.invariant] +### The matcher invariants + +r[macro.ambiguity.invariant.list] +To be valid, a matcher must meet the following three invariants. The definitions of FIRST and FOLLOW are described later. + +1. For any two successive token tree sequences in a matcher `M` (i.e. `M = ... tt uu ...`) with `uu ...` nonempty, we must have FOLLOW(`... tt`) ∪ {ε} ⊇ FIRST(`uu ...`). +1. For any separated complex NT in a matcher, `M = ... $(tt ...) SEP OP ...`, we must have `SEP` ∈ FOLLOW(`tt ...`). +1. For an unseparated complex NT in a matcher, `M = ... $(tt ...) OP ...`, if OP = `*` or `+`, we must have FOLLOW(`tt ...`) ⊇ FIRST(`tt ...`). + +r[macro.ambiguity.invariant.follow-matcher] +The first invariant says that whatever actual token that comes after a matcher, if any, must be somewhere in the predetermined follow set. This ensures that a legal macro definition will continue to assign the same determination as to where `... tt` ends and `uu ...` begins, even as new syntactic forms are added to the language. + +r[macro.ambiguity.invariant.separated-complex-nt] +The second invariant says that a separated complex NT must use a separator token that is part of the predetermined follow set for the internal contents of the NT. This ensures that a legal macro definition will continue to parse an input fragment into the same delimited sequence of `tt ...`'s, even as new syntactic forms are added to the language. + +r[macro.ambiguity.invariant.unseparated-complex-nt] +The third invariant says that when we have a complex NT that can match two or more copies of the same thing with no separation in between, it must be permissible for them to be placed next to each other as per the first invariant. This invariant also requires they be nonempty, which eliminates a possible ambiguity. + +**NOTE: The third invariant is currently unenforced due to historical oversight and significant reliance on the behaviour. It is currently undecided what to do about this going forward. Macros that do not respect the behaviour may become invalid in a future edition of Rust. See the [tracking issue].** + +r[macro.ambiguity.sets] +### FIRST and FOLLOW, informally + +r[macro.ambiguity.sets.intro] +A given matcher M maps to three sets: FIRST(M), LAST(M) and FOLLOW(M). + +Each of the three sets is made up of tokens. FIRST(M) and LAST(M) may also contain a distinguished non-token element ε ("epsilon"), which indicates that M can match the empty fragment. (But FOLLOW(M) is always just a set of tokens.) + +Informally: + +r[macro.ambiguity.sets.first] + * FIRST(M): collects the tokens potentially used first when matching a fragment to M. + +r[macro.ambiguity.sets.last] + * LAST(M): collects the tokens potentially used last when matching a fragment to M. + +r[macro.ambiguity.sets.follow] + * FOLLOW(M): the set of tokens allowed to follow immediately after some fragment matched by M. + + In other words: t ∈ FOLLOW(M) if and only if there exists (potentially empty) token sequences α, β, γ, δ where: + + * M matches β, + + * t matches γ, and + + * The concatenation α β γ δ is a parseable Rust program. + +r[macro.ambiguity.sets.universe] +We use the shorthand ANYTOKEN to denote the set of all tokens (including simple NTs). For example, if any token is legal after a matcher M, then FOLLOW(M) = ANYTOKEN. + +(To review one's understanding of the above informal descriptions, the reader at this point may want to jump ahead to the [examples of FIRST/LAST](#examples-of-first-and-last) before reading their formal definitions.) + +r[macro.ambiguity.sets.def] +### FIRST, LAST + +r[macro.ambiguity.sets.def.intro] +Below are formal inductive definitions for FIRST and LAST. + +r[macro.ambiguity.sets.def.notation] +"A ∪ B" denotes set union, "A ∩ B" denotes set intersection, and "A \ B" denotes set difference (i.e. all elements of A that are not present in B). + +r[macro.ambiguity.sets.def.first] +#### FIRST + +r[macro.ambiguity.sets.def.first.intro] +FIRST(M) is defined by case analysis on the sequence M and the structure of its first token-tree (if any): + +r[macro.ambiguity.sets.def.first.epsilon] + * if M is the empty sequence, then FIRST(M) = { ε }, + +r[macro.ambiguity.sets.def.first.token] + * if M starts with a token t, then FIRST(M) = { t }, + + (Note: this covers the case where M starts with a delimited token-tree sequence, `M = OPEN tt ... CLOSE ...`, in which case `t = OPEN` and thus FIRST(M) = { `OPEN` }.) + + (Note: this critically relies on the property that no simple NT matches the empty fragment.) + +r[macro.ambiguity.sets.def.first.complex] + * Otherwise, M is a token-tree sequence starting with a complex NT: `M = $( tt ... ) OP α`, or `M = $( tt ... ) SEP OP α`, (where `α` is the (potentially empty) sequence of token trees for the rest of the matcher). + + * Let SEP\_SET(M) = { SEP } if SEP is present and ε ∈ FIRST(`tt ...`); otherwise SEP\_SET(M) = {}. + + * Let ALPHA\_SET(M) = FIRST(`α`) if OP = `*` or `?` and ALPHA\_SET(M) = {} if OP = `+`. + * FIRST(M) = (FIRST(`tt ...`) \\ {ε}) ∪ SEP\_SET(M) ∪ ALPHA\_SET(M). + +The definition for complex NTs deserves some justification. SEP\_SET(M) defines the possibility that the separator could be a valid first token for M, which happens when there is a separator defined and the repeated fragment could be empty. ALPHA\_SET(M) defines the possibility that the complex NT could be empty, meaning that M's valid first tokens are those of the following token-tree sequences `α`. This occurs when either `*` or `?` is used, in which case there could be zero repetitions. In theory, this could also occur if `+` was used with a potentially-empty repeating fragment, but this is forbidden by the third invariant. + +From there, clearly FIRST(M) can include any token from SEP\_SET(M) or ALPHA\_SET(M), and if the complex NT match is nonempty, then any token starting FIRST(`tt ...`) could work too. The last piece to consider is ε. SEP\_SET(M) and FIRST(`tt ...`) \ {ε} cannot contain ε, but ALPHA\_SET(M) could. Hence, this definition allows M to accept ε if and only if ε ∈ ALPHA\_SET(M) does. This is correct because for M to accept ε in the complex NT case, both the complex NT and α must accept it. If OP = `+`, meaning that the complex NT cannot be empty, then by definition ε ∉ ALPHA\_SET(M). Otherwise, the complex NT can accept zero repetitions, and then ALPHA\_SET(M) = FOLLOW(`α`). So this definition is correct with respect to \varepsilon as well. + +r[macro.ambiguity.sets.def.last] +#### LAST + +r[macro.ambiguity.sets.def.last.intro] +LAST(M), defined by case analysis on M itself (a sequence of token-trees): + +r[macro.ambiguity.sets.def.last.empty] + * if M is the empty sequence, then LAST(M) = { ε } + +r[macro.ambiguity.sets.def.last.token] + * if M is a singleton token t, then LAST(M) = { t } + +r[macro.ambiguity.sets.def.last.rep-star] + * if M is the singleton complex NT repeating zero or more times, `M = $( tt ... ) *`, or `M = $( tt ... ) SEP *` + + * Let sep_set = { SEP } if SEP present; otherwise sep_set = {}. + + * if ε ∈ LAST(`tt ...`) then LAST(M) = LAST(`tt ...`) ∪ sep_set + + * otherwise, the sequence `tt ...` must be non-empty; LAST(M) = LAST(`tt ...`) ∪ {ε}. + +r[macro.ambiguity.sets.def.last.rep-plus] + * if M is the singleton complex NT repeating one or more times, `M = $( tt ... ) +`, or `M = $( tt ... ) SEP +` + + * Let sep_set = { SEP } if SEP present; otherwise sep_set = {}. + + * if ε ∈ LAST(`tt ...`) then LAST(M) = LAST(`tt ...`) ∪ sep_set + + * otherwise, the sequence `tt ...` must be non-empty; LAST(M) = LAST(`tt ...`) + +r[macro.ambiguity.sets.def.last.rep-question] + * if M is the singleton complex NT repeating zero or one time, `M = $( tt ...) ?`, then LAST(M) = LAST(`tt ...`) ∪ {ε}. + +r[macro.ambiguity.sets.def.last.delim] + * if M is a delimited token-tree sequence `OPEN tt ... CLOSE`, then LAST(M) = { `CLOSE` }. + +r[macro.ambiguity.sets.def.last.sequence] + * if M is a non-empty sequence of token-trees `tt uu ...`, + + * If ε ∈ LAST(`uu ...`), then LAST(M) = LAST(`tt`) ∪ (LAST(`uu ...`) \ { ε }). + + * Otherwise, the sequence `uu ...` must be non-empty; then LAST(M) = LAST(`uu ...`). + +### Examples of FIRST and LAST + +Below are some examples of FIRST and LAST. (Note in particular how the special ε element is introduced and eliminated based on the interaction between the pieces of the input.) + +Our first example is presented in a tree structure to elaborate on how the analysis of the matcher composes. (Some of the simpler subtrees have been elided.) + +```text +INPUT: $( $d:ident $e:expr );* $( $( h )* );* $( f ; )+ g + ~~~~~~~~ ~~~~~~~ ~ + | | | +FIRST: { $d:ident } { $e:expr } { h } + + +INPUT: $( $d:ident $e:expr );* $( $( h )* );* $( f ; )+ + ~~~~~~~~~~~~~~~~~~ ~~~~~~~ ~~~ + | | | +FIRST: { $d:ident } { h, ε } { f } + +INPUT: $( $d:ident $e:expr );* $( $( h )* );* $( f ; )+ g + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~ ~ + | | | | +FIRST: { $d:ident, ε } { h, ε, ; } { f } { g } + + +INPUT: $( $d:ident $e:expr );* $( $( h )* );* $( f ; )+ g + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +FIRST: { $d:ident, h, ;, f } +``` + +Thus: + + * FIRST(`$($d:ident $e:expr );* $( $(h)* );* $( f ;)+ g`) = { `$d:ident`, `h`, `;`, `f` } + +Note however that: + + * FIRST(`$($d:ident $e:expr );* $( $(h)* );* $($( f ;)+ g)*`) = { `$d:ident`, `h`, `;`, `f`, ε } + +Here are similar examples but now for LAST. + + * LAST(`$d:ident $e:expr`) = { `$e:expr` } + * LAST(`$( $d:ident $e:expr );*`) = { `$e:expr`, ε } + * LAST(`$( $d:ident $e:expr );* $(h)*`) = { `$e:expr`, ε, `h` } + * LAST(`$( $d:ident $e:expr );* $(h)* $( f ;)+`) = { `;` } + * LAST(`$( $d:ident $e:expr );* $(h)* $( f ;)+ g`) = { `g` } + +r[macro.ambiguity.sets.def.follow] +### FOLLOW(M) + +r[macro.ambiguity.sets.def.follow.intro] +Finally, the definition for FOLLOW(M) is built up as follows. pat, expr, etc. represent simple nonterminals with the given fragment specifier. + +r[macro.ambiguity.sets.def.follow.pat] + * FOLLOW(pat) = {`=>`, `,`, `=`, `|`, `if`, `in`}`. + +r[macro.ambiguity.sets.def.follow.expr-stmt] + * FOLLOW(expr) = FOLLOW(expr_2021) = FOLLOW(stmt) = {`=>`, `,`, `;`}`. + +r[macro.ambiguity.sets.def.follow.ty-path] + * FOLLOW(ty) = FOLLOW(path) = {`{`, `[`, `,`, `=>`, `:`, `=`, `>`, `>>`, `;`, `|`, `as`, `where`, block nonterminals}. + +r[macro.ambiguity.sets.def.follow.vis] + * FOLLOW(vis) = {`,`l any keyword or identifier except a non-raw `priv`; any token that can begin a type; ident, ty, and path nonterminals}. + +r[macro.ambiguity.sets.def.follow.simple] + * FOLLOW(t) = ANYTOKEN for any other simple token, including block, ident, tt, item, lifetime, literal and meta simple nonterminals, and all terminals. + +r[macro.ambiguity.sets.def.follow.other-matcher] + * FOLLOW(M), for any other M, is defined as the intersection, as t ranges over (LAST(M) \ {ε}), of FOLLOW(t). + +r[macro.ambiguity.sets.def.follow.type-first] +The tokens that can begin a type are, as of this writing, {`(`, `[`, `!`, `*`, `&`, `&&`, `?`, lifetimes, `>`, `>>`, `::`, any non-keyword identifier, `super`, `self`, `Self`, `extern`, `crate`, `$crate`, `_`, `for`, `impl`, `fn`, `unsafe`, `typeof`, `dyn`}, although this list may not be complete because people won't always remember to update the appendix when new ones are added. + +Examples of FOLLOW for complex M: + + * FOLLOW(`$( $d:ident $e:expr )*`) = FOLLOW(`$e:expr`) + * FOLLOW(`$( $d:ident $e:expr )* $(;)*`) = FOLLOW(`$e:expr`) ∩ ANYTOKEN = FOLLOW(`$e:expr`) + * FOLLOW(`$( $d:ident $e:expr )* $(;)* $( f |)+`) = ANYTOKEN + +### Examples of valid and invalid matchers + +With the above specification in hand, we can present arguments for why particular matchers are legal and others are not. + + * `($ty:ty < foo ,)` : illegal, because FIRST(`< foo ,`) = { `<` } ⊈ FOLLOW(`ty`) + + * `($ty:ty , foo <)` : legal, because FIRST(`, foo <`) = { `,` } is ⊆ FOLLOW(`ty`). + + * `($pa:pat $pb:pat $ty:ty ,)` : illegal, because FIRST(`$pb:pat $ty:ty ,`) = { `$pb:pat` } ⊈ FOLLOW(`pat`), and also FIRST(`$ty:ty ,`) = { `$ty:ty` } ⊈ FOLLOW(`pat`). + + * `( $($a:tt $b:tt)* ; )` : legal, because FIRST(`$b:tt`) = { `$b:tt` } is ⊆ FOLLOW(`tt`) = ANYTOKEN, as is FIRST(`;`) = { `;` }. + + * `( $($t:tt),* , $(t:tt),* )` : legal, (though any attempt to actually use this macro will signal a local ambiguity error during expansion). + + * `($ty:ty $(; not sep)* -)` : illegal, because FIRST(`$(; not sep)* -`) = { `;`, `-` } is not in FOLLOW(`ty`). + + * `($($ty:ty)-+)` : illegal, because separator `-` is not in FOLLOW(`ty`). + + * `($($e:expr)*)` : illegal, because expr NTs are not in FOLLOW(expr NT). + +[Macros by Example]: macros-by-example.md +[RFC 550]: https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md +[tracking issue]: https://github.com/rust-lang/rust/issues/56575 diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/macros-by-example.md b/stdlib/kvlang/reference/rust/reference-repo/src/macros-by-example.md new file mode 100644 index 00000000..267304c7 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/macros-by-example.md @@ -0,0 +1,738 @@ +r[macro.decl] +# Macros by example + +r[macro.decl.syntax] +```grammar,macros +MacroRulesDefinition -> + `macro_rules` `!` IDENTIFIER MacroRulesDef + +MacroRulesDef -> + `(` MacroRules `)` `;` + | `[` MacroRules `]` `;` + | `{` MacroRules `}` + +MacroRules -> + MacroRule ( `;` MacroRule )* `;`? + +MacroRule -> + MacroMatcher `=>` MacroTranscriber + +MacroMatcher -> + `(` MacroMatch* `)` + | `[` MacroMatch* `]` + | `{` MacroMatch* `}` + +MacroMatch -> + Token _except `$` and [delimiters][lex.token.delim]_ + | MacroMatcher + | `$` ( IDENTIFIER_OR_KEYWORD _except `crate`_ | RAW_IDENTIFIER ) `:` MacroFragSpec + | `$` `(` MacroMatch+ `)` MacroRepSep? MacroRepOp + +MacroFragSpec -> + `block` | `expr` | `expr_2021` | `ident` | `item` | `lifetime` | `literal` + | `meta` | `pat` | `pat_param` | `path` | `stmt` | `tt` | `ty` | `vis` + +MacroRepSep -> Token _except [delimiters][lex.token.delim] and [MacroRepOp]_ + +MacroRepOp -> `*` | `+` | `?` + +MacroTranscriber -> DelimTokenTree +``` + +r[macro.decl.intro] +`macro_rules` allows users to define syntax extension in a declarative way. We call such extensions "macros by example" or simply "macros". + +Each macro by example has a name, and one or more _rules_. Each rule has two parts: a _matcher_, describing the syntax that it matches, and a _transcriber_, describing the syntax that will replace a successfully matched invocation. Both the matcher and the transcriber must be surrounded by delimiters. Macros can expand to expressions, statements, items (including traits, impls, and foreign items), types, or patterns. + +r[macro.decl.transcription] +## Transcribing + +r[macro.decl.transcription.intro] +When a macro is invoked, the macro expander looks up macro invocations by name, and tries each macro rule in turn. It transcribes the first successful match; if this results in an error, then future matches are not tried. + +r[macro.decl.transcription.lookahead] +When matching, no lookahead is performed; if the compiler cannot unambiguously determine how to parse the macro invocation one token at a time, then it is an error. In the following example, the compiler does not look ahead past the identifier to see if the following token is a `)`, even though that would allow it to parse the invocation unambiguously: + +```rust,compile_fail +macro_rules! ambiguity { + ($($i:ident)* $j:ident) => { }; +} + +ambiguity!(error); // Error: local ambiguity +``` + +r[macro.decl.transcription.syntax] +In both the matcher and the transcriber, the `$` token is used to invoke special behaviours from the macro engine (described below in [Metavariables] and [Repetitions]). Tokens that aren't part of such an invocation are matched and transcribed literally, with one exception. The exception is that the outer delimiters for the matcher will match any pair of delimiters. Thus, for instance, the matcher `(())` will match `{()}` but not `{{}}`. The character `$` cannot be matched or transcribed literally. + +r[macro.decl.transcription.fragment] +### Forwarding a matched fragment + +When forwarding a matched fragment to another macro-by-example, matchers in the second macro will see an opaque AST of the fragment type. The second macro can't use literal tokens to match the fragments in the matcher, only a fragment specifier of the same type. The `ident`, `lifetime`, and `tt` fragment types are an exception, and *can* be matched by literal tokens. The following illustrates this restriction: + +```rust,compile_fail +macro_rules! foo { + ($l:expr) => { bar!($l); } +// ERROR: ^^ no rules expected this token in macro call +} + +macro_rules! bar { + (3) => {} +} + +foo!(3); +``` + +The following illustrates how tokens can be directly matched after matching a `tt` fragment: + +```rust +// compiles OK +macro_rules! foo { + ($l:tt) => { bar!($l); } +} + +macro_rules! bar { + (3) => {} +} + +foo!(3); +``` + +r[macro.decl.meta] +## Metavariables + +r[macro.decl.meta.intro] +In the matcher, `$` _name_ `:` _fragment-specifier_ matches a Rust syntax fragment of the kind specified and binds it to the metavariable `$`_name_. + +r[macro.decl.meta.specifier] +Valid fragment specifiers are: + + * `block`: a [BlockExpressionNoInnerAttributes] + * `expr`: an [Expression] + * `expr_2021`: an [Expression] except [UnderscoreExpression] and [ConstBlockExpression] (see [macro.decl.meta.edition2024]) + * `ident`: an [IDENTIFIER_OR_KEYWORD] except `_`, [RAW_IDENTIFIER], or [`$crate`] + * `item`: an [Item] + * `lifetime`: a [LIFETIME_TOKEN] + * `literal`: matches `-`<sup>?</sup>[LiteralExpression] + * `meta`: an [Attr], the contents of an attribute + * `pat`: a [Pattern] (see [macro.decl.meta.edition2021]) + * `pat_param`: a [PatternNoTopAlt] + * `path`: a [TypePath] + * `stmt`: a [Statement][grammar-Statement] without the trailing semicolon (except for item statements that require semicolons) + * `tt`: a [TokenTree] (a single [token] or tokens in matching delimiters `()`, `[]`, or `{}`) + * `ty`: a [Type][grammar-Type] + * `vis`: a possibly empty [Visibility] qualifier + +r[macro.decl.meta.transcription] +In the transcriber, metavariables are referred to simply by `$`_name_, since the fragment kind is specified in the matcher. Metavariables are replaced with the syntax element that matched them. Metavariables can be transcribed more than once or not at all. + +r[macro.decl.meta.dollar-crate] +The keyword metavariable [`$crate`] can be used to refer to the current crate. + +r[macro.decl.meta.edition2021] +> [!EDITION-2021] +> Starting with the 2021 edition, `pat` fragment-specifiers match top-level or-patterns (that is, they accept [Pattern]). +> +> Before the 2021 edition, they match exactly the same fragments as `pat_param` (that is, they accept [PatternNoTopAlt]). +> +> The relevant edition is the one in effect for the `macro_rules!` definition. + +r[macro.decl.meta.edition2024] +> [!EDITION-2024] +> Before the 2024 edition, `expr` fragment specifiers do not match [UnderscoreExpression] or [ConstBlockExpression] at the top level. They are allowed within subexpressions. +> +> The `expr_2021` fragment specifier exists to maintain backwards compatibility with editions before 2024. + +r[macro.decl.repetition] +## Repetitions + +r[macro.decl.repetition.intro] +In both the matcher and transcriber, repetitions are indicated by placing the tokens to be repeated inside `$(`…`)`, followed by a repetition operator, optionally with a separator token between. + +r[macro.decl.repetition.separator] +The separator token can be any token other than a delimiter or one of the repetition operators, but `;` and `,` are the most common. For instance, `$( $i:ident ),*` represents any number of identifiers separated by commas. Nested repetitions are permitted. + +r[macro.decl.repetition.operators] +The repetition operators are: + +- `*` --- indicates any number of repetitions. +- `+` --- indicates any number but at least one. +- `?` --- indicates an optional fragment with zero or one occurrence. + +r[macro.decl.repetition.optional-restriction] +Since `?` represents at most one occurrence, it cannot be used with a separator. + +r[macro.decl.repetition.fragment] +The repeated fragment both matches and transcribes to the specified number of the fragment, separated by the separator token. Metavariables are matched to every repetition of their corresponding fragment. For instance, the `$( $i:ident ),*` example above matches `$i` to all of the identifiers in the list. + +During transcription, additional restrictions apply to repetitions so that the compiler knows how to expand them properly: + +1. A metavariable must appear in exactly the same number, kind, and nesting order of repetitions in the transcriber as it did in the matcher. So for the matcher `$( $i:ident ),*`, the transcribers `=> { $i }`, `=> { $( $( $i )* )* }`, and `=> { $( $i )+ }` are all illegal, but `=> { $( $i );* }` is correct and replaces a comma-separated list of identifiers with a semicolon-separated list. +2. Each repetition in the transcriber must contain at least one metavariable to decide how many times to expand it. If multiple metavariables appear in the same repetition, they must be bound to the same number of fragments. For instance, `( $( $i:ident ),* ; $( $j:ident ),* ) => (( $( ($i,$j) ),* ))` must bind the same number of `$i` fragments as `$j` fragments. This means that invoking the macro with `(a, b, c; d, e, f)` is legal and expands to `((a,d), (b,e), (c,f))`, but `(a, b, c; d, e)` is illegal because it does not have the same number. This requirement applies to every layer of nested repetitions. + +r[macro.decl.scope] +## Scoping, exporting, and importing + +r[macro.decl.scope.intro] +For historical reasons, the scoping of macros by example does not work entirely like items. Macros have two forms of scope: textual scope, and path-based scope. Textual scope is based on the order that things appear in source files, or even across multiple files, and is the default scoping. It is explained further below. Path-based scope works exactly the same way that item scoping does. The scoping, exporting, and importing of macros is controlled largely by attributes. + +r[macro.decl.scope.unqualified] +When a macro is invoked by an unqualified identifier (not part of a multi-part path), it is first looked up in textual scoping. If this does not yield any results, then it is looked up in path-based scoping. If the macro's name is qualified with a path, then it is only looked up in path-based scoping. + +<!-- ignore: requires external crates --> +```rust,ignore +use lazy_static::lazy_static; // Path-based import. + +macro_rules! lazy_static { // Textual definition. + (lazy) => {}; +} + +lazy_static!{lazy} // Textual lookup finds our macro first. +self::lazy_static!{} // Path-based lookup ignores our macro, finds imported one. +``` + +r[macro.decl.scope.textual] +### Textual scope + +r[macro.decl.scope.textual.intro] +Textual scope is based largely on the order that things appear in source files, and works similarly to the scope of local variables declared with `let` except it also applies at the module level. When `macro_rules!` is used to define a macro, the macro enters the scope after the definition (note that it can still be used recursively, since names are looked up from the invocation site), up until its surrounding scope, typically a module, is closed. This can enter child modules and even span across multiple files: + +<!-- ignore: requires external modules --> +```rust,ignore +//// src/lib.rs +mod has_macro { + // m!{} // Error: m is not in scope. + + macro_rules! m { + () => {}; + } + m!{} // OK: appears after declaration of m. + + mod uses_macro; +} + +// m!{} // Error: m is not in scope. + +//// src/has_macro/uses_macro.rs + +m!{} // OK: appears after declaration of m in src/lib.rs +``` + +r[macro.decl.scope.textual.shadow] +It is not an error to define a macro multiple times; the most recent declaration will shadow the previous one unless it has gone out of scope. + +```rust +macro_rules! m { + (1) => {}; +} + +m!(1); + +mod inner { + m!(1); + + macro_rules! m { + (2) => {}; + } + // m!(1); // Error: no rule matches '1' + m!(2); + + macro_rules! m { + (3) => {}; + } + m!(3); +} + +m!(1); +``` + +r[macro.decl.scope.textual.function-local] +Macros can be declared and used locally inside functions as well, and work similarly: + +```rust +fn foo() { + // m!(); // Error: m is not in scope. + macro_rules! m { + () => {}; + } + m!(); +} + +// m!(); // Error: m is not in scope. +``` + +r[macro.decl.scope.textual.shadow-path-based] +Textual scope name bindings for macros shadow path-based scope bindings to macros. + +```rust +macro_rules! m2 { + () => { + println!("m2"); + }; +} + +// Resolves to path-based candidate from use declaration below. +m!(); // prints "m2\n" + +// Introduce second candidate for `m` with textual scope. +// +// This shadows path-based candidate from below for the rest of this +// example. +macro_rules! m { + () => { + println!("m"); + }; +} + +// Introduce `m2` macro as path-based candidate. +// +// This item is in scope for this entire example, not just below the +// use declaration. +use m2 as m; + +// Resolves to the textual macro candidate from above the use +// declaration. +m!(); // prints "m\n" +``` + +> [!NOTE] +> For areas where shadowing is not allowed, see [name resolution ambiguities]. + +r[macro.decl.scope.path-based] +### Path-based scope + +r[macro.decl.scope.path-based.intro] +By default, a macro has no path-based scope. Macros can gain path-based scope in two ways: + +- [Use declaration re-export] +- [`macro_export`] + +r[macro.decl.scope.path.reexport] +Macros can be re-exported to give them path-based scope from a module other than the crate root. + +```rust +mac::m!(); // OK: Path-based lookup finds `m` in the mac module. + +mod mac { + // Introduce macro `m` with textual scope. + macro_rules! m { + () => {}; + } + + // Reexport with path-based scope from within `m`'s textual scope. + pub(crate) use m; +} +``` + +r[macro.decl.scope.path-based.visibility] +Macros have an implicit visibility of `pub(crate)`. `#[macro_export]` changes the implicit visibility to `pub`. + +```rust +// Implicit visibility is `pub(crate)`. +macro_rules! private_m { + () => {}; +} + +// Implicit visibility is `pub`. +#[macro_export] +macro_rules! pub_m { + () => {}; +} + +pub(crate) use private_m as private_macro; // OK. +pub use pub_m as pub_macro; // OK. +``` + +```rust,compile_fail,E0364 +# // Implicit visibility is `pub(crate)`. +# macro_rules! private_m { +# () => {}; +# } +# +# // Implicit visibility is `pub`. +# #[macro_export] +# macro_rules! pub_m { +# () => {}; +# } +# +# pub(crate) use private_m as private_macro; // OK. +# pub use pub_m as pub_macro; // OK. +# +pub use private_m; // ERROR: `private_m` is only public within + // the crate and cannot be re-exported outside. +``` + +<!-- template:attributes --> +r[macro.decl.scope.macro_use] +### The `macro_use` attribute + +r[macro.decl.scope.macro_use.intro] +The *`macro_use` [attribute][attributes]* has two purposes: it may be used on modules to extend the scope of macros defined within them, and it may be used on [`extern crate`][items.extern-crate] to import macros from another crate into the [`macro_use` prelude]. + +> [!EXAMPLE] +> ```rust +> #[macro_use] +> mod inner { +> macro_rules! m { +> () => {}; +> } +> } +> m!(); +> ``` +> +> ```rust,ignore +> #[macro_use] +> extern crate log; +> ``` + +r[macro.decl.scope.macro_use.syntax] +When used on modules, the `macro_use` attribute uses the [MetaWord] syntax. + +When used on `extern crate`, it uses the [MetaWord] and [MetaListIdents] syntaxes. For more on how these syntaxes may be used, see [macro.decl.scope.macro_use.prelude]. + +r[macro.decl.scope.macro_use.allowed-positions] +The `macro_use` attribute may be applied to modules or `extern crate`. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[macro.decl.scope.macro_use.extern-crate-self] +The `macro_use` attribute may not be used on [`extern crate self`]. + +r[macro.decl.scope.macro_use.duplicates] +The `macro_use` attribute may be used any number of times on a form. + +Multiple instances of `macro_use` in the [MetaListIdents] syntax may be specified. The union of all specified macros will be imported. + +> [!NOTE] +> On modules, `rustc` lints against any [MetaWord] `macro_use` attributes following the first. +> +> On `extern crate`, `rustc` lints against any `macro_use` attributes that have no effect due to not importing any macros not already imported by another `macro_use` attribute. If two or more [MetaListIdents] `macro_use` attributes import the same macro, the first is linted against. If any [MetaWord] `macro_use` attributes are present, all [MetaListIdents] `macro_use` attributes are linted against. If two or more [MetaWord] `macro_use` attributes are present, the ones following the first are linted against. + +r[macro.decl.scope.macro_use.mod-decl] +When `macro_use` is used on a module, the module's macro scope extends beyond the module's lexical scope. + +> [!EXAMPLE] +> ```rust +> #[macro_use] +> mod inner { +> macro_rules! m { +> () => {}; +> } +> } +> m!(); // OK +> ``` + +r[macro.decl.scope.macro_use.prelude] +Specifying `macro_use` on an `extern crate` declaration in the crate root imports exported macros from that crate. + +Macros imported this way are imported into the [`macro_use` prelude], not textually, which means that they can be shadowed by any other name. Macros imported by `macro_use` can be used before the import statement. + +> [!NOTE] +> `rustc` currently prefers the last macro imported in case of conflict. Don't rely on this. This behavior is unusual, as imports in Rust are generally order-independent. This behavior of `macro_use` may change in the future. +> +> For details, see [Rust issue #148025](https://github.com/rust-lang/rust/issues/148025). + +When using the [MetaWord] syntax, all exported macros are imported. When using the [MetaListIdents] syntax, only the specified macros are imported. + +> [!EXAMPLE] +> <!-- ignore: requires external crates --> +> ```rust,ignore +> #[macro_use(lazy_static)] // Or `#[macro_use]` to import all macros. +> extern crate lazy_static; +> +> lazy_static!{} +> // self::lazy_static!{} // ERROR: lazy_static is not defined in `self`. +> ``` + +r[macro.decl.scope.macro_use.export] +Macros to be imported with `macro_use` must be exported with [`macro_export`][macro.decl.scope.macro_export]. + +<!-- template:attributes --> +r[macro.decl.scope.macro_export] +### The `macro_export` attribute + +r[macro.decl.scope.macro_export.intro] +The *`macro_export` [attribute][attributes]* exports the macro from the crate and makes it available in the root of the crate for path-based resolution. + +> [!EXAMPLE] +> ```rust +> self::m!(); +> // ^^^^ OK: Path-based lookup finds `m` in the current module. +> m!(); // As above. +> +> mod inner { +> super::m!(); +> crate::m!(); +> } +> +> mod mac { +> #[macro_export] +> macro_rules! m { +> () => {}; +> } +> } +> ``` + +r[macro.decl.scope.macro_export.syntax] +The `macro_export` attribute uses the [MetaWord] and [MetaListIdents] syntaxes. With the [MetaListIdents] syntax, it accepts a single [`local_inner_macros`][macro.decl.scope.macro_export.local_inner_macros] value. + +r[macro.decl.scope.macro_export.allowed-positions] +The `macro_export` attribute may be applied to `macro_rules` definitions. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[macro.decl.scope.macro_export.duplicates] +Only the first use of `macro_export` on a macro has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[macro.decl.scope.macro_export.path-based] +By default, macros only have [textual scope][macro.decl.scope.textual] and cannot be resolved by path. When the `macro_export` attribute is used, the macro is made available in the crate root and can be referred to by its path. + +> [!EXAMPLE] +> Without `macro_export`, macros only have textual scope, so path-based resolution of the macro fails. +> +> ```rust,compile_fail,E0433 +> macro_rules! m { +> () => {}; +> } +> self::m!(); // ERROR +> crate::m!(); // ERROR +> # fn main() {} +> ``` +> +> With `macro_export`, path-based resolution works. +> +> ```rust +> #[macro_export] +> macro_rules! m { +> () => {}; +> } +> self::m!(); // OK +> crate::m!(); // OK +> # fn main() {} +> ``` + +r[macro.decl.scope.macro_export.export] +The `macro_export` attribute causes a macro to be exported from the crate root so that it can be referred to in other crates by path. + +> [!EXAMPLE] +> Given the following in a `log` crate: +> +> ```rust +> #[macro_export] +> macro_rules! warn { +> ($message:expr) => { eprintln!("WARN: {}", $message) }; +> } +> ``` +> +> From another crate, you can refer to the macro by path: +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> fn main() { +> log::warn!("example warning"); +> } +> ``` + +r[macro.decl.scope.macro_export.macro_use] +`macro_export` allows the use of [`macro_use`][macro.decl.scope.macro_use] on an `extern crate` to import the macro into the [`macro_use` prelude]. + +> [!EXAMPLE] +> Given the following in a `log` crate: +> +> ```rust +> #[macro_export] +> macro_rules! warn { +> ($message:expr) => { eprintln!("WARN: {}", $message) }; +> } +> ``` +> +> Using `macro_use` in a dependent crate allows you to use the macro from the prelude: +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> #[macro_use] +> extern crate log; +> +> pub mod util { +> pub fn do_thing() { +> // Resolved via macro prelude. +> warn!("example warning"); +> } +> } +> ``` + +r[macro.decl.scope.macro_export.local_inner_macros] +Adding `local_inner_macros` to the `macro_export` attribute causes all single-segment macro invocations in the macro definition to have an implicit `$crate::` prefix. + +> [!NOTE] +> This is intended primarily as a tool to migrate code written before [`$crate`] was added to the language to work with Rust 2018's path-based imports of macros. Its use is discouraged in new code. + +> [!EXAMPLE] +> ```rust +> #[macro_export(local_inner_macros)] +> macro_rules! helped { +> () => { helper!() } // Automatically converted to $crate::helper!(). +> } +> +> #[macro_export] +> macro_rules! helper { +> () => { () } +> } +> ``` + +r[macro.decl.hygiene] +## Hygiene + +r[macro.decl.hygiene.intro] +Macros by example have _mixed-site hygiene_. This means that [loop labels], [block labels], and local variables are looked up at the macro definition site while other symbols are looked up at the macro invocation site. For example: + +```rust +let x = 1; +fn func() { + unreachable!("this is never called") +} + +macro_rules! check { + () => { + assert_eq!(x, 1); // Uses `x` from the definition site. + func(); // Uses `func` from the invocation site. + }; +} + +{ + let x = 2; + fn func() { /* does not panic */ } + check!(); +} +``` + +Labels and local variables defined in macro expansion are not shared between invocations, so this code doesn’t compile: + +```rust,compile_fail,E0425 +macro_rules! m { + (define) => { + let x = 1; + }; + (refer) => { + dbg!(x); + }; +} + +m!(define); +m!(refer); +``` + +r[macro.decl.hygiene.crate] +A special case is the `$crate` metavariable. It refers to the crate defining the macro, and can be used at the start of the path to look up items or macros which are not in scope at the invocation site. + +<!-- ignore: requires external crates --> +```rust,ignore +//// Definitions in the `helper_macro` crate. +#[macro_export] +macro_rules! helped { + // () => { helper!() } // This might lead to an error due to 'helper' not being in scope. + () => { $crate::helper!() } +} + +#[macro_export] +macro_rules! helper { + () => { () } +} + +//// Usage in another crate. +// Note that `helper_macro::helper` is not imported! +use helper_macro::helped; + +fn unit() { + helped!(); +} +``` + +Note that, because `$crate` refers to the current crate, it must be used with a fully qualified module path when referring to non-macro items: + +```rust +pub mod inner { + #[macro_export] + macro_rules! call_foo { + () => { $crate::inner::foo() }; + } + + pub fn foo() {} +} +``` + +r[macro.decl.hygiene.vis] +Additionally, even though `$crate` allows a macro to refer to items within its own crate when expanding, its use has no effect on visibility. An item or macro referred to must still be visible from the invocation site. In the following example, any attempt to invoke `call_foo!()` from outside its crate will fail because `foo()` is not public. + +```rust +#[macro_export] +macro_rules! call_foo { + () => { $crate::foo() }; +} + +fn foo() {} +``` + +> [!NOTE] +> Prior to Rust 1.30, `$crate` and [`local_inner_macros`][macro.decl.scope.macro_export.local_inner_macros] were unsupported. They were added alongside [path-based imports of macros][macro.decl.scope.macro_export], to ensure that helper macros did not need to be manually imported by users of a macro-exporting crate. Crates written for earlier versions of Rust that use helper macros need to be modified to use `$crate` or `local_inner_macros` to work well with path-based imports. + +r[macro.decl.follow-set] +## Follow-set ambiguity restrictions + +r[macro.decl.follow-set.intro] +The parser used by the macro system is reasonably powerful, but it is limited in order to prevent ambiguity in current or future versions of the language. + +r[macro.decl.follow-set.token-restriction] +In particular, in addition to the rule about ambiguous expansions, a nonterminal matched by a metavariable must be followed by a token which has been decided can be safely used after that kind of match. + +As an example, a macro matcher like `$i:expr [ , ]` could in theory be accepted in Rust today, since `[,]` cannot be part of a legal expression and therefore the parse would always be unambiguous. However, because `[` can start trailing expressions, `[` is not a character which can safely be ruled out as coming after an expression. If `[,]` were accepted in a later version of Rust, this matcher would become ambiguous or would misparse, breaking working code. Matchers like `$i:expr,` or `$i:expr;` would be legal, however, because `,` and `;` are legal expression separators. The specific rules are: + +r[macro.decl.follow-set.token-expr-stmt] + * `expr` and `stmt` may only be followed by one of: `=>`, `,`, or `;`. + +r[macro.decl.follow-set.token-pat_param] + * `pat_param` may only be followed by one of: `=>`, `,`, `=`, `|`, `if`, or `in`. + +r[macro.decl.follow-set.token-pat] + * `pat` may only be followed by one of: `=>`, `,`, `=`, `if`, or `in`. + +r[macro.decl.follow-set.token-path-ty] + * `path` and `ty` may only be followed by one of: `=>`, `,`, `=`, `|`, `;`, `:`, `>`, `>>`, `[`, `{`, `as`, `where`, or a macro variable of `block` fragment specifier. + +r[macro.decl.follow-set.token-vis] + * `vis` may only be followed by one of: `,`, an identifier other than a non-raw `priv`, any token that can begin a type, or a metavariable with a `ident`, `ty`, or `path` fragment specifier. + +r[macro.decl.follow-set.token-other] + * All other fragment specifiers have no restrictions. + +r[macro.decl.follow-set.edition2021] +> [!EDITION-2021] +> Before the 2021 edition, `pat` may also be followed by `|`. + +r[macro.decl.follow-set.repetition] +When repetitions are involved, then the rules apply to every possible number of expansions, taking separators into account. This means: + + * If the repetition includes a separator, that separator must be able to follow the contents of the repetition. + * If the repetition can repeat multiple times (`*` or `+`), then the contents must be able to follow themselves. + * The contents of the repetition must be able to follow whatever comes before, and whatever comes after must be able to follow the contents of the repetition. + * If the repetition can match zero times (`*` or `?`), then whatever comes after must be able to follow whatever comes before. + +For more detail, see the [formal specification]. + +[Metavariables]: #metavariables +[Repetitions]: #repetitions +[`macro_export`]: #the-macro_export-attribute +[`$crate`]: macro.decl.hygiene.crate +[`extern crate self`]: items.extern-crate.self +[`macro_use` prelude]: names/preludes.md#macro_use-prelude +[block labels]: expr.loop.block-labels +[delimiters]: tokens.md#delimiters +[formal specification]: macro-ambiguity.md +[loop labels]: expressions/loop-expr.md#loop-labels +[name resolution ambiguities]: names/name-resolution.md#r-names.resolution.expansion.imports.ambiguity +[token]: tokens.md +[use declaration re-export]: items/use-declarations.md#use-visibility diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/macros.md b/stdlib/kvlang/reference/rust/reference-repo/src/macros.md new file mode 100644 index 00000000..17fa834f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/macros.md @@ -0,0 +1,122 @@ +r[macro] +# Macros + +r[macro.intro] +The functionality and syntax of Rust can be extended with custom definitions called macros. They are given names, and invoked through a consistent syntax: `some_extension!(...)`. + +There are two ways to define new macros: + +* [Macros by example] define new syntax in a higher-level, declarative way. +* [Procedural macros] define function-like macros, custom derives, and custom attributes using functions that operate on input tokens. + +r[macro.invocation] +## Macro invocation + +r[macro.invocation.syntax] +```grammar,macros +MacroInvocation -> + SimplePath `!` DelimTokenTree + +DelimTokenTree -> + `(` TokenTree* `)` + | `[` TokenTree* `]` + | `{` TokenTree* `}` + +TokenTree -> + Token _except [delimiters][lex.token.delim]_ | DelimTokenTree + +MacroInvocationSemi -> + SimplePath `!` `(` TokenTree* `)` `;` + | SimplePath `!` `[` TokenTree* `]` `;` + | SimplePath `!` `{` TokenTree* `}` +``` + +r[macro.invocation.intro] +A macro invocation expands a macro at compile time and replaces the invocation with the result of the macro. Macros may be invoked in the following situations: + +r[macro.invocation.expr] +* [Expressions] and [statements] + +r[macro.invocation.pattern] +* [Patterns] + +r[macro.invocation.type] +* [Types] + +r[macro.invocation.item] +* [Items] including [associated items] + +r[macro.invocation.nested] +* [`macro_rules`] transcribers + +r[macro.invocation.extern] +* [External blocks] + +r[macro.invocation.item-statement] +When used as an item or a statement, the [MacroInvocationSemi] form is used where a semicolon is required at the end when not using curly braces. [Visibility qualifiers] are never allowed before a macro invocation or [`macro_rules`] definition. + +```rust +// Used as an expression. +let x = vec![1,2,3]; + +// Used as a statement. +println!("Hello!"); + +// Used in a pattern. +macro_rules! pat { + ($i:ident) => (Some($i)) +} + +if let pat!(x) = Some(1) { + assert_eq!(x, 1); +} + +// Used in a type. +macro_rules! Tuple { + { $A:ty, $B:ty } => { ($A, $B) }; +} + +type N2 = Tuple!(i32, i32); + +// Used as an item. +# use std::cell::RefCell; +thread_local!(static FOO: RefCell<u32> = RefCell::new(1)); + +// Used as an associated item. +macro_rules! const_maker { + ($t:ty, $v:tt) => { const CONST: $t = $v; }; +} +trait T { + const_maker!{i32, 7} +} + +// Macro calls within macros. +macro_rules! example { + () => { println!("Macro call in a macro!") }; +} +// Outer macro `example` is expanded, then inner macro `println` is expanded. +example!(); +``` + +r[macro.invocation.name-resolution] + +Macros invocations can be resolved via two kinds of scopes: + +- Textual Scope + - [Textual scope `macro_rules`](macros-by-example.md#r-macro.decl.scope.textual) +- Path-based scope + - [Path-based scope `macro_rules`](macros-by-example.md#r-macro.decl.scope.path-based) + - [Procedural macros] + +[External blocks]: items/external-blocks.md +[Macros by Example]: macros-by-example.md +[Procedural Macros]: procedural-macros.md +[`macro_rules`]: macros-by-example.md +[associated items]: items/associated-items.md +[delimiters]: tokens.md#delimiters +[expressions]: expressions.md +[items]: items.md +[patterns]: patterns.md +[statements]: statements.md +[types]: types.md +[visibility qualifiers]: visibility-and-privacy.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/memory-allocation-and-lifetime.md b/stdlib/kvlang/reference/rust/reference-repo/src/memory-allocation-and-lifetime.md new file mode 100644 index 00000000..a72577b6 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/memory-allocation-and-lifetime.md @@ -0,0 +1,8 @@ +r[alloc] +# Memory allocation and lifetime + +r[alloc.static] +The _items_ of a program are those functions, modules, and types that have their value calculated at compile-time and stored uniquely in the memory image of the rust process. Items are neither dynamically allocated nor freed. + +r[alloc.dynamic] +The _heap_ is a general term that describes boxes. The lifetime of an allocation in the heap depends on the lifetime of the box values pointing to it. Since box values may themselves be passed in and out of frames, or stored in the heap, heap allocations may outlive the frame they are allocated within. An allocation in the heap is guaranteed to reside at a single location in the heap for the whole lifetime of the allocation - it will never be relocated as a result of moving a box value. diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/memory-model.md b/stdlib/kvlang/reference/rust/reference-repo/src/memory-model.md new file mode 100644 index 00000000..b4efe0f8 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/memory-model.md @@ -0,0 +1,27 @@ +r[memory] +# Memory model + +r[memory.intro] +> [!WARNING] +> The memory model of Rust is incomplete and not fully decided. + +r[memory.bytes] +## Bytes + +r[memory.bytes.intro] +The most basic unit of memory in Rust is a byte. + +> [!NOTE] +> While bytes are typically lowered to hardware bytes, Rust uses an "abstract" notion of bytes that can make distinctions which are absent in hardware, such as being uninitialized, or storing part of a pointer. Those distinctions can affect whether your program has undefined behavior, so they still have tangible impact on how compiled Rust programs behave. + +r[memory.bytes.contents] +Each byte may have one of the following values: + +r[memory.bytes.init] +* An initialized byte containing a `u8` value and optional [provenance][std::ptr#provenance], + +r[memory.bytes.uninit] +* An uninitialized byte. + +> [!NOTE] +> The above list is not yet guaranteed to be exhaustive. diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/names.md b/stdlib/kvlang/reference/rust/reference-repo/src/names.md new file mode 100644 index 00000000..412f9ed6 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/names.md @@ -0,0 +1,168 @@ +r[names] +# Names + +r[names.intro] +An *entity* is a language construct that can be referred to in some way within the source program, usually via a [path]. Entities include [types], [items], [generic parameters], [variable bindings], [loop labels], [lifetimes], [fields], [attributes], and [lints]. + +A *declaration* is a syntactical construct that can introduce a *name* to refer to an entity. Entity names are valid within a [*scope*] --- a region of source text where that name may be referenced. + +Some entities are [explicitly declared](#explicitly-declared-entities) in the source code, and some are [implicitly declared](#implicitly-declared-entities) as part of the language or compiler extensions. + +[*Paths*] are used to refer to an entity, possibly in another module or type. + +Lifetimes and loop labels use a [dedicated syntax][lifetimes-and-loop-labels] using a leading quote. + +Names are segregated into different [*namespaces*], allowing entities in different namespaces to share the same name without conflict. + +[*Name resolution*] is the compile-time process of tying paths, identifiers, and labels to entity declarations. + +Access to certain names may be restricted based on their [*visibility*]. + +r[names.explicit] +## Explicitly declared entities + +r[names.explicit.list] +Entities that explicitly introduce a name in the source code are: + +r[names.explicit.item-decl] +* [Items]: + * [Module declarations] + * [External crate declarations] + * [Use declarations] + * [Function declarations] and [function parameters] + * [Type aliases] + * [struct], [union], [enum], enum variant declarations, and their named fields + * [Constant item declarations] + * [Static item declarations] + * [Trait item declarations] and their [associated items] + * [External block items] + * [`macro_rules` declarations] and [matcher metavariables] + * [Implementation] associated items + +r[names.explicit.expr] +* [Expressions]: + * [Closure] parameters + * [`while let`] pattern bindings + * [`for`] pattern bindings + * [`if let`] pattern bindings + * [`match`] pattern bindings + * [Loop labels] + +r[names.explicit.generics] +* [Generic parameters] + +r[names.explicit.higher-ranked-bounds] +* [Higher ranked trait bounds] + +r[names.explicit.binding] +* [`let` statement] pattern bindings + +r[names.explicit.macro_use] +* The [`macro_use` attribute] can introduce macro names from another crate + +r[names.explicit.macro_export] +* The [`macro_export` attribute] can introduce an alias for the macro into the crate root + +r[names.explicit.macro-invocation] +Additionally, [macro invocations] and [attributes] can introduce names by expanding to one of the above items. + +r[names.implicit] +## Implicitly declared entities + +r[names.implicit.list] +The following entities are implicitly defined by the language, or are introduced by compiler options and extensions: + +r[names.implicit.primitive-types] +* [Language prelude]: + * [Boolean type] --- `bool` + * Textual types --- [`char`] and [`str`] + * [Integer types] --- `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128` + * [Machine-dependent integer types] --- `usize` and `isize` + * [floating-point types] --- `f32` and `f64` + +r[names.implicit.builtin-attributes] +* [Built-in attributes] + +r[names.implicit.prelude] +* [Standard library prelude] items, attributes, and macros + +r[names.implicit.stdlib] +* [Standard library][extern-prelude] crates in the root module + +r[names.implicit.extern-prelude] +* [External crates][extern-prelude] linked by the compiler + +r[names.implicit.tool-attributes] +* [Tool attributes] + +r[names.implicit.lints] +* [Lints] and [tool lint attributes] + +r[names.implicit.derive-helpers] +* [Derive helper attributes] are valid within an item without being explicitly imported + +r[names.implicit.lifetime-static] +* The [`'static`] lifetime + +r[names.implicit.root] +Additionally, the crate root module does not have a name, but can be referred to with certain [path qualifiers] or aliases. + +[*Name resolution*]: names/name-resolution.md +[*namespaces*]: names/namespaces.md +[*paths*]: paths.md +[*scope*]: names/scopes.md +[*visibility*]: visibility-and-privacy.md +[`'static`]: keywords.md#weak-keywords +[`char`]: types/char.md +[`for`]: expressions/loop-expr.md#iterator-loops +[`if let`]: expressions/if-expr.md#if-let-patterns +[`let` statement]: statements.md#let-statements +[`macro_export` attribute]: macros-by-example.md#the-macro_export-attribute +[`macro_rules` declarations]: macros-by-example.md +[`macro_use` attribute]: macros-by-example.md#the-macro_use-attribute +[`match`]: expressions/match-expr.md +[`str`]: types/str.md +[`while let`]: expressions/loop-expr.md#while-let-patterns +[associated items]: items/associated-items.md +[attributes]: attributes.md +[Boolean type]: types/boolean.md +[Built-in attributes]: attributes.md#built-in-attributes-index +[Closure]: expressions/closure-expr.md +[Constant item declarations]: items/constant-items.md +[Derive helper attributes]: procedural-macros.md#derive-macro-helper-attributes +[enum]: items/enumerations.md +[Expressions]: expressions.md +[extern-prelude]: names/preludes.md#extern-prelude +[External block items]: items/external-blocks.md +[External crate declarations]: items/extern-crates.md +[fields]: expressions/field-expr.md +[floating-point types]: types/numeric.md#floating-point-types +[Function declarations]: items/functions.md +[function parameters]: items/functions.md#function-parameters +[Generic parameters]: items/generics.md +[Higher ranked trait bounds]: trait-bounds.md#higher-ranked-trait-bounds +[Implementation]: items/implementations.md +[Integer types]: types/numeric.md#integer-types +[Items]: items.md +[Language prelude]: names/preludes.md#language-prelude +[lifetimes-and-loop-labels]: tokens.md#lifetimes-and-loop-labels +[lifetimes]: tokens.md#lifetimes-and-loop-labels +[Lints]: attributes/diagnostics.md#lint-check-attributes +[Loop labels]: expressions/loop-expr.md#loop-labels +[Machine-dependent integer types]: types/numeric.md#machine-dependent-integer-types +[macro invocations]: macros.md#macro-invocation +[matcher metavariables]: macros-by-example.md#metavariables +[Module declarations]: items/modules.md +[path]: paths.md +[path qualifiers]: paths.md#path-qualifiers +[Standard library prelude]: names/preludes.md#standard-library-prelude +[Static item declarations]: items/static-items.md +[struct]: items/structs.md +[Tool attributes]: attributes.md#tool-attributes +[tool lint attributes]: attributes/diagnostics.md#tool-lint-attributes +[Trait item declarations]: items/traits.md +[Type aliases]: items/type-aliases.md +[types]: types.md +[union]: items/unions.md +[Use declarations]: items/use-declarations.md +[variable bindings]: patterns.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/names/name-resolution.md b/stdlib/kvlang/reference/rust/reference-repo/src/names/name-resolution.md new file mode 100644 index 00000000..cd27be47 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/names/name-resolution.md @@ -0,0 +1,587 @@ +r[names.resolution] +# Name resolution + +r[names.resolution.intro] +_Name resolution_ is the process of tying paths and other identifiers to the declarations of those entities. Names are segregated into different [namespaces], allowing entities in different namespaces to share the same name without conflict. Each name is valid within a [scope], or a region of source text where that name may be referenced. Access to a name may be restricted based on its [visibility]. + +Name resolution is split into three stages throughout the compilation process. The first stage, *expansion-time resolution*, resolves all [`use` declarations] and [macro invocations]. The second stage, *primary resolution*, resolves all names that have not yet been resolved and that do not depend on type information to resolve. The last stage, *type-relative resolution*, resolves the remaining names once type information is available. + +> [!NOTE] +> Expansion-time resolution is also known as *early resolution*. Primary resolution is also known as *late resolution*. + +r[names.resolution.general] +## General + +r[names.resolution.general.intro] +The rules within this section apply to all stages of name resolution. + +r[names.resolution.general.scopes] +### Scopes + +r[names.resolution.general.scopes.intro] +> [!NOTE] +> This is a placeholder for future expansion about resolution of names within various scopes. + +r[names.resolution.expansion] +## Expansion-time name resolution + +r[names.resolution.expansion.intro] +Expansion-time name resolution is the stage of name resolution necessary to complete macro expansion and fully generate a crate's [AST]. This stage requires the resolution of macro invocations and `use` declarations. Resolving `use` declarations is required for macro invocations that resolve via [path-based scope]. Resolving macro invocations is required in order to expand them. + +r[names.resolution.expansion.unresolved-invocations] +After expansion-time name resolution, the AST must not contain any unexpanded macro invocations. Every macro invocation resolves to a valid definition that exists in the final AST or in an external crate. + +```rust,compile_fail +m!(); // ERROR: Cannot find macro `m` in this scope. +``` + +r[names.resolution.expansion.expansion-order-stability] +The resolution of names must be stable. After expansion, names in the fully expanded AST must resolve to the same definition regardless of the order in which macros are expanded and imports are resolved. + +r[names.resolution.expansion.speculation] +All name resolution candidates selected during macro expansion are considered speculative. Once the crate has been fully expanded, all speculative import resolutions are validated to ensure that macro expansion did not introduce any new ambiguities. + +> [!NOTE] +> Due to the iterative nature of macro expansion, this causes so-called time traveling ambiguities, such as when a macro or glob import introduces an item that is ambiguous with its own base path. +> +> ```rust,compile_fail,E0659 +> # fn main() {} +> macro_rules! f { +> () => { +> mod m { +> pub(crate) use f; +> } +> } +> } +> f!(); +> +> const _: () = { +> // Initially, we speculatively resolve `m` to the module in +> // the crate root. +> // +> // Expansion of `f` introduces a second `m` module inside this +> // body. +> // +> // Expansion-time resolution finalizes resolutions by re- +> // resolving all imports and macro invocations, sees the +> // introduced ambiguity and reports it as an error. +> m::f!(); // ERROR: `m` is ambiguous. +> }; +> ``` + +r[names.resolution.expansion.imports] +### Imports +r[names.resolution.expansion.imports.intro] +All `use` declarations are fully resolved during this stage of resolution. [Type-relative paths] cannot be resolved at this stage and will produce an error. + +```rust,no_run +mod m { + pub const C: () = (); + pub enum E { V } + pub type A = E; + impl E { + pub const C: () = (); + } +} + +// Valid imports resolved at expansion-time: +use m::C; // OK. +use m::E; // OK. +use m::A; // OK. +use m::E::V; // OK. + +// Valid expressions resolved during type-relative resolution: +let _ = m::A::V; // OK. +let _ = m::E::C; // OK. +``` + +```rust,compile_fail,E0432 +# mod m { +# pub const C: () = (); +# pub enum E { V } +# pub type A = E; +# impl E { +# pub const C: () = (); +# } +# } +// Invalid type-relative imports that can't resolve at expansion-time: +use m::A::V; // ERROR: Unresolved import `m::A::V`. +use m::E::C; // ERROR: Unresolved import `m::E::C`. +``` + +r[names.resolution.expansion.imports.shadowing] +Names introduced via `use` declarations in an [outer scope] are shadowed by candidates in the same namespace with the same name from an inner scope except where otherwise restricted by [name resolution ambiguities]. + +```rust,no_run +pub mod m1 { + pub mod ambig { + pub const C: u8 = 1; + } +} + +pub mod m2 { + pub mod ambig { + pub const C: u8 = 2; + } +} + +// This introduces the name `ambig` in the outer scope. +use m1::ambig; +const _: () = { + // This shadows `ambig` in the inner scope. + use m2::ambig; + // The inner candidate is selected here + // as the resolution of `ambig`. + use ambig::C; + assert!(C == 2); +}; +``` + +r[names.resolution.expansion.imports.shadowing-shared-scope] +Shadowing of names introduced via `use` declarations within a single scope is permitted in the following situations: + +- [`use` glob shadowing] +- [Macro textual scope shadowing] + +r[names.resolution.expansion.imports.ambiguity] +#### Ambiguities + +r[names.resolution.expansion.imports.ambiguity.intro] +There are certain situations during expansion-time resolution where there are multiple macro definitions, `use` declarations, or modules an import or macro invocation's name could refer to where the compiler cannot consistently determine which candidate should shadow the other. Shadowing cannot be permitted in these situations and the compiler instead emits ambiguity errors. + +r[names.resolution.expansion.imports.ambiguity.glob-vs-glob] +Names may not be resolved through ambiguous glob imports. Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used. Names with conflicting candidates from ambiguous glob imports may still be shadowed by non-glob imports and used without producing an error. The errors occur at time of use, not time of import. + +```rust,compile_fail,E0659 +mod m1 { + pub struct Ambig; +} + +mod m2 { + pub struct Ambig; +} + +// OK: This brings conficting names in the same namespace into scope +// but they have not been used yet. +use m1::*; +use m2::*; + +const _: () = { + // The error happens when the name with the conflicting candidates + // is used. + let x = Ambig; // ERROR: `Ambig` is ambiguous. +}; +``` + +```rust,no_run +# mod m1 { +# pub struct Ambig; +# } +# +# mod m2 { +# pub struct Ambig; +# } +# +# use m1::*; +# use m2::*; // OK: No name conflict. +const _: () = { + // This is permitted, since resolution is not through the + // ambiguous globs. + struct Ambig; + let x = Ambig; // OK. +}; +``` + +Multiple glob imports are allowed to import the same name, and that name is allowed to be used if the imports are of the same item (following reexports). The visibility of the name is the maximum visibility of the imports. + +```rust,no_run +mod m1 { + pub struct Ambig; +} + +mod m2 { + // This reexports the same `Ambig` item from a second module. + pub use super::m1::Ambig; +} + +mod m3 { + // These both import the same `Ambig`. + // + // The visibility of `Ambig` is `pub` because that is the + // maximum visibility between these two `use` declarations. + pub use super::m1::*; + use super::m2::*; +} + +mod m4 { + // `Ambig` can be used through the `m3` globs and still has + // `pub` visibility. + pub use crate::m3::Ambig; +} + +const _: () = { + // Therefore, we can use it here. + let _ = m4::Ambig; // OK. +}; +# fn main() {} +``` + +r[names.resolution.expansion.imports.ambiguity.glob-vs-outer] +Names in imports and macro invocations may not be resolved through glob imports when there is another candidate available in an [outer scope]. + +r[names.resolution.expansion.imports.ambiguity.panic-hack] +> [!NOTE] +> When one of [`core::panic!`] or [`std::panic!`] is brought into scope due to the [standard library prelude], and a user-written [glob import] brings the other into scope, `rustc` currently allows use of `panic!`, even though it is ambiguous. The user-written glob import takes precedence to resolve this ambiguity. +> +> In Rust 2021 and later, [`core::panic!`] and [`std::panic!`] operate identically. But in earlier editions, they differ; only [`std::panic!`] accepts a [`String`] as the format argument. +> +> E.g., this is an error: +> +> ```rust,edition2018,compile_fail,E0308 +> extern crate core; +> use ::core::prelude::v1::*; +> fn main() { +> panic!(std::string::String::new()); // ERROR. +> } +> ``` +> +> And this is accepted: +> +> <!-- ignore: Can't test with `no_std`. --> +> ```rust,edition2018,ignore +> #![no_std] +> extern crate std; +> use ::std::prelude::v1::*; +> fn main() { +> panic!(std::string::String::new()); // OK. +> } +> ``` +> +> Don't rely on this behavior; the plan is to remove it. +> +> For details, see [Rust issue #147319](https://github.com/rust-lang/rust/issues/147319). + +```rust,compile_fail,E0659 +mod glob { + pub mod ambig { + pub struct Name; + } +} + +// Outer `ambig` candidate. +pub mod ambig { + pub struct Name; +} + +const _: () = { + // Cannot resolve `ambig` through this glob + // because of the outer `ambig` candidate above. + use glob::*; + use ambig::Name; // ERROR: `ambig` is ambiguous. +}; +``` + +```rust,compile_fail,E0659 +// As above, but with macros. +pub mod m { + macro_rules! f { + () => {}; + } + pub(crate) use f; +} +pub mod glob { + macro_rules! f { + () => {}; + } + pub(crate) use f as ambig; +} + +use m::f as ambig; + +const _: () = { + use glob::*; + ambig!(); // ERROR: `ambig` is ambiguous. +}; +``` + +> [!NOTE] +> These ambiguity errors are specific to expansion-time resolution. Having multiple candidates available for a given name during later stages of resolution is not considered an error. So long as none of the imports themselves are ambiguous, there will always be a single unambiguous closest resolution. +> +> ```rust,no_run +> mod glob { +> pub const AMBIG: u8 = 1; +> } +> +> mod outer { +> pub const AMBIG: u8 = 2; +> } +> +> use outer::AMBIG; +> +> const C: () = { +> use glob::*; +> assert!(AMBIG == 1); +> // ^---- This `AMBIG` is resolved during primary resolution. +> }; +> ``` + +r[names.resolution.expansion.imports.ambiguity.path-vs-textual-macro] +Names may not be resolved through ambiguous macro reexports. Macro reexports are ambiguous when they would shadow a textual macro candidate for the same name in an [outer scope]. + +```rust,compile_fail,E0659 +// Textual macro candidate. +macro_rules! ambig { + () => {} +} + +// Path-based macro candidate. +macro_rules! path_based { + () => {} +} + +pub fn f() { + // This reexport of the `path_based` macro definition + // as `ambig` may not shadow the `ambig` macro definition + // which is resolved via textual macro scope. + use path_based as ambig; + ambig!(); // ERROR: `ambig` is ambiguous. +} +``` + +> [!NOTE] +> This restriction is needed due to implementation details in the compiler, specifically the current scope visitation logic and the complexity of supporting this behavior. This ambiguity error may be removed in the future. + +r[names.resolution.expansion.macros] +### Macros + +r[names.resolution.expansion.macros.intro] +Macros are resolved by iterating through the available scopes to find the available candidates. Macros are split into two sub-namespaces, one for function-like macros, and the other for attributes and derives. Resolution candidates from the incorrect sub-namespace are ignored. + +r[names.resolution.expansion.macros.visitation-order] +The available scope kinds are visited in the following order. Each of these scope kinds represent one or more scopes. + +* [Derive helpers] +* [Textual scope macros] +* [Path-based scope macros] +* [`macro_use` prelude] +* [Standard library prelude] +* [Builtin attributes] + +> [!NOTE] +> The compiler will attempt to resolve derive helpers that are used before their associated macro introduces them into scope. This scope is visited after the scope for resolving derive helper candidates that are correctly in scope. This behavior is slated for removal. +> +> For more info see [derive helper scope]. + +> [!NOTE] +> This visitation order may change in the future, such as interleaving the visitation of textual and path-based scope candidates based on their lexical scopes. + +> [!EDITION-2018] +> Starting in edition 2018 the `#[macro_use]` prelude is not visited when [`#[no_implicit_prelude]`][names.preludes.no_implicit_prelude] is present. + +r[names.resolution.expansion.macros.reserved-names] +The names `cfg` and `cfg_attr` are reserved in the macro attribute [sub-namespace]. + +r[names.resolution.expansion.macros.ambiguity] +#### Ambiguities + +r[names.resolution.expansion.macros.ambiguity.more-expanded-vs-outer] +Names may not be resolved through ambiguous candidates inside of macro expansions. Candidates inside of macro expansions are ambiguous when they would shadow a candidate for the same name from outside of the first candidate's macro expansion and the invocation of the name being resolved is also from outside of the first candidate's macro expansion. + +```rust,compile_fail,E0659 +macro_rules! define_ambig { + () => { + macro_rules! ambig { + () => {} + } + } +} + +// Introduce outer candidate definition for `ambig` macro invocation. +macro_rules! ambig { + () => {} +} + +// Introduce a second candidate definition for `ambig` inside of a +// macro expansion. +define_ambig!(); + +// The definition of `ambig` from the second invocation +// of `define_ambig` is the innermost canadidate. +// +// The definition of `ambig` from the first invocation of +// `define_ambig` is the second candidate. +// +// The compiler checks that the first candidate is inside of a macro +// expansion, that the second candidate is not from within the same +// macro expansion, and that the name being resolved is not from +// within the same macro expansion. +ambig!(); // ERROR: `ambig` is ambiguous. +``` + +The reverse is not considered ambiguous. + +```rust,no_run +# macro_rules! define_ambig { +# () => { +# macro_rules! ambig { +# () => {} +# } +# } +# } +// Swap order of definitions. +define_ambig!(); +macro_rules! ambig { + () => {} +} +// The innermost candidate is now less expanded so it may shadow more +// the macro expanded definition above it. +ambig!(); +``` + +Nor is it ambiguous if the invocation being resolved is within the innermost candidate's expansion. + +```rust,no_run +macro_rules! ambig { + () => {} +} + +macro_rules! define_and_invoke_ambig { + () => { + // Define innermost candidate. + macro_rules! ambig { + () => {} + } + + // Invocation of `ambig` is in the same expansion as the + // innermost candidate. + ambig!(); // OK + } +} + +define_and_invoke_ambig!(); +``` + +It doesn't matter if both definitions come from invocations of the same macro; the outermost candidate is still considered "less expanded" because it is not within the expansion containing the innermost candidate's definition. + +```rust,compile_fail,E0659 +# macro_rules! define_ambig { +# () => { +# macro_rules! ambig { +# () => {} +# } +# } +# } +define_ambig!(); +define_ambig!(); +ambig!(); // ERROR: `ambig` is ambiguous. +``` + +This also applies to imports so long as the innermost candidate for the name is from within a macro expansion. + +```rust,compile_fail,E0659 +macro_rules! define_ambig { + () => { + mod ambig { + pub struct Name; + } + } +} + +mod ambig { + pub struct Name; +} + +const _: () = { + // Introduce innermost candidate for + // `ambig` mod in this macro expansion. + define_ambig!(); + use ambig::Name; // ERROR: `ambig` is ambiguous. +}; +``` + +r[names.resolution.expansion.macros.ambiguity.built-in-attr] +User-defined attributes or derive macros may not shadow built-in non-macro attributes (e.g. inline). + +<!-- ignore: test doesn't support proc-macro --> +```rust,ignore +// with-helper/src/lib.rs +# use proc_macro::TokenStream; +#[proc_macro_derive(WithHelperAttr, attributes(non_exhaustive))] +// ^^^^^^^^^^^^^^ +// User-defined attribute candidate. +// ... +# pub fn derive_with_helper_attr(_item: TokenStream) -> TokenStream { +# TokenStream::new() +# } +``` + +<!-- ignore: requires external crates --> +```rust,ignore +// src/lib.rs +#[derive(with_helper::WithHelperAttr)] +#[non_exhaustive] // ERROR: `non_exhaustive` is ambiguous. +struct S; +``` + +> [!NOTE] +> This applies regardless of the name the built-in attribute is a candidate for: +> +> <!-- ignore: test doesn't support proc-macro --> +> ```rust,ignore +> // with-helper/src/lib.rs +> # use proc_macro::TokenStream; +> # +> #[proc_macro_derive(WithHelperAttr, attributes(helper))] +> // ^^^^^^ +> // User-defined attribute candidate. +> // ... +> # pub fn derive_with_helper_attr(_item: TokenStream) -> TokenStream { +> # TokenStream::new() +> # } +> ``` +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> // src/lib.rs +> use inline as helper; +> // ^----- Built-in attribute candidate via reexport. +> +> #[derive(with_helper::WithHelperAttr)] +> #[helper] // ERROR: `helper` is ambiguous. +> struct S; +> ``` + +r[names.resolution.primary] +## Primary name resolution +> [!NOTE] +> This is a placeholder for future expansion about primary name resolution. + +r[names.resolution.type-relative] +## Type-relative resolution +> [!NOTE] +> This is a placeholder for future expansion about type-dependent resolution. + +[AST]: glossary.ast +[Builtin attributes]: ./preludes.md#r-names.preludes.lang +[Derive helpers]: ../procedural-macros.md#r-macro.proc.derive.attributes +[Macros]: ../macros.md +[Path-based scope macros]: ../macros.md#r-macro.invocation.name-resolution +[Standard library prelude]: ./preludes.md#r-names.preludes.std +[Textual scope macros]: ../macros-by-example.md#r-macro.decl.scope.textual +[`let` bindings]: ../statements.md#let-statements +[`macro_use` prelude]: ./preludes.md#r-names.preludes.macro_use +[`use` declarations]: ../items/use-declarations.md +[`use` glob shadowing]: ../items/use-declarations.md#r-items.use.glob.shadowing +[derive helper scope]: ../procedural-macros.md#r-macro.proc.derive.attributes.scope +[glob import]: items.use.glob +[item definitions]: ../items.md +[macro invocations]: ../macros.md#macro-invocation +[macro textual scope shadowing]: macro.decl.scope.textual.shadow-path-based +[name resolution ambiguities]: #r-names.resolution.expansion.imports.ambiguity +[namespaces]: ../names/namespaces.md +[outer scope]: #r-names.resolution.general.scopes +[path-based scope]: ../macros.md#r-macro.invocation.name-resolution +[scope]: ../names/scopes.md +[sub-namespace]: ../names/namespaces.md#r-names.namespaces.sub-namespaces +[type-relative paths]: names.resolution.type-relative +[visibility]: ../visibility-and-privacy.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/names/namespaces.md b/stdlib/kvlang/reference/rust/reference-repo/src/names/namespaces.md new file mode 100644 index 00000000..77509126 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/names/namespaces.md @@ -0,0 +1,169 @@ +r[names.namespaces] +# Namespaces + +r[names.namespaces.intro] +A *namespace* is a logical grouping of declared [names]. Names are segregated into separate namespaces based on the kind of entity the name refers to. Namespaces allow the occurrence of a name in one namespace to not conflict with the same name in another namespace. + +There are several different namespaces that each contain different kinds of entities. The use of a name will look for the declaration of that name in different namespaces, based on the context, as described in the [name resolution] chapter. + +r[names.namespaces.kinds] +The following is a list of namespaces, with their corresponding entities: + +* Type Namespace + * [Module declarations] + * [External crate declarations] + * [External crate prelude] items + * [Struct], [union], [enum], enum variant declarations + * [Trait item declarations] + * [Type aliases] + * [Associated type declarations] + * Built-in types: [boolean], [numeric], [`char`], and [`str`] + * [Generic type parameters] + * [`Self` type] + * [Tool attribute modules] +* Value Namespace + * [Function declarations] + * [Constant item declarations] + * [Static item declarations] + * [Struct constructors] + * [Enum variant constructors] + * [`Self` constructors] + * [Generic const parameters] + * [Associated const declarations] + * [Associated function declarations] + * Local bindings --- [`let`], [`if let`], [`while let`], [`for`], [`match`] arms, [function parameters], [closure parameters] + * Captured [closure] variables +* Macro Namespace + * [`macro_rules` declarations] + * [Built-in attributes] + * [Tool attributes] + * [Function-like procedural macros] + * [Derive macros] + * [Derive macro helpers] + * [Attribute macros] +* Lifetime Namespace + * [Generic lifetime parameters] +* Label Namespace + * [Loop labels] + * [Block labels] + +An example of how overlapping names in different namespaces can be used unambiguously: + +```rust +// Foo introduces a type in the type namespace and a constructor in the value +// namespace. +struct Foo(u32); + +// The `Foo` macro is declared in the macro namespace. +macro_rules! Foo { + () => {}; +} + +// `Foo` in the `f` parameter type refers to `Foo` in the type namespace. +// `'Foo` introduces a new lifetime in the lifetime namespace. +fn example<'Foo>(f: Foo) { + // `Foo` refers to the `Foo` constructor in the value namespace. + let ctor = Foo; + // `Foo` refers to the `Foo` macro in the macro namespace. + Foo!{} + // `'Foo` introduces a label in the label namespace. + 'Foo: loop { + // `'Foo` refers to the `'Foo` lifetime parameter, and `Foo` + // refers to the type namespace. + let x: &'Foo Foo; + // `'Foo` refers to the label. + break 'Foo; + } +} +``` + +r[names.namespaces.without] +## Named entities without a namespace + +r[names.namespaces.without.intro] +The following entities have explicit names, but the names are not a part of any specific namespace. + +### Fields + +r[names.namespaces.without.fields] +Even though struct, enum, and union fields are named, the named fields do not live in an explicit namespace. They can only be accessed via a [field expression], which only inspects the field names of the specific type being accessed. + +### Use declarations + +r[names.namespaces.without.use] +A [use declaration] has named aliases that it imports into scope, but the `use` item itself does not belong to a specific namespace. Instead, it can introduce aliases into multiple namespaces, depending on the item kind being imported. + +r[names.namespaces.sub-namespaces] +## Sub-namespaces + +r[names.namespaces.sub-namespaces.intro] +The macro namespace is split into two sub-namespaces: one for [bang-style macros] and one for [attributes]. When an attribute is resolved, any bang-style macros in scope will be ignored. And conversely resolving a bang-style macro will ignore attribute macros in scope. This prevents one style from shadowing another. + +For example, the [`cfg` attribute] and the [`cfg` macro] are two different entities with the same name in the macro namespace, but they can still be used in their respective context. + +<!-- ignore: requires external crates --> +> [!NOTE] +> `use` imports still cannot create duplicate bindings of the same name in a module or block, regardless of sub-namespace. +> +> ```rust,ignore +> #[macro_export] +> macro_rules! mymac { +> () => {}; +> } +> +> use myattr::mymac; // error[E0252]: the name `mymac` is defined multiple times. +> ``` + +[`cfg` attribute]: ../conditional-compilation.md#the-cfg-attribute +[`cfg` macro]: ../conditional-compilation.md#the-cfg-macro +[`char`]: ../types/char.md +[`for`]: ../expressions/loop-expr.md#iterator-loops +[`if let`]: ../expressions/if-expr.md#if-let-patterns +[`let`]: ../statements.md#let-statements +[`macro_rules` declarations]: ../macros-by-example.md +[`match`]: ../expressions/match-expr.md +[`Self` constructors]: ../paths.md#self-1 +[`Self` type]: ../paths.md#self-1 +[`str`]: ../types/str.md +[`use` import]: ../items/use-declarations.md +[`while let`]: ../expressions/loop-expr.md#while-let-patterns +[Associated const declarations]: ../items/associated-items.md#associated-constants +[Associated function declarations]: ../items/associated-items.md#associated-functions-and-methods +[Associated type declarations]: ../items/associated-items.md#associated-types +[Attribute macros]: ../procedural-macros.md#the-proc_macro_attribute-attribute +[attributes]: ../attributes.md +[bang-style macros]: ../macros.md +[Block labels]: expr.loop.block-labels +[boolean]: ../types/boolean.md +[Built-in attributes]: ../attributes.md#built-in-attributes-index +[closure parameters]: ../expressions/closure-expr.md +[closure]: ../expressions/closure-expr.md +[Constant item declarations]: ../items/constant-items.md +[Derive macro helpers]: ../procedural-macros.md#derive-macro-helper-attributes +[Derive macros]: macro.proc.derive +[entity]: ../glossary.md#entity +[Enum variant constructors]: ../items/enumerations.md +[enum]: ../items/enumerations.md +[External crate declarations]: ../items/extern-crates.md +[External crate prelude]: preludes.md#extern-prelude +[field expression]: ../expressions/field-expr.md +[Function declarations]: ../items/functions.md +[function parameters]: ../items/functions.md#function-parameters +[Function-like procedural macros]: ../procedural-macros.md#the-proc_macro-attribute +[Generic const parameters]: ../items/generics.md#const-generics +[Generic lifetime parameters]: ../items/generics.md +[Generic type parameters]: ../items/generics.md +[Loop labels]: ../expressions/loop-expr.md#loop-labels +[Module declarations]: ../items/modules.md +[name resolution]: name-resolution.md +[names]: ../names.md +[numeric]: ../types/numeric.md +[Static item declarations]: ../items/static-items.md +[Struct constructors]: ../items/structs.md +[Struct]: ../items/structs.md +[Tool attribute modules]: ../attributes.md#tool-attributes +[Tool attributes]: ../attributes.md#tool-attributes +[Trait item declarations]: ../items/traits.md +[Type aliases]: ../items/type-aliases.md +[union]: ../items/unions.md +[use declaration]: ../items/use-declarations.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/names/preludes.md b/stdlib/kvlang/reference/rust/reference-repo/src/names/preludes.md new file mode 100644 index 00000000..0daf4a1d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/names/preludes.md @@ -0,0 +1,248 @@ +r[names.preludes] +# Preludes + +r[names.preludes.intro] +A *prelude* is a collection of names that are automatically brought into scope of every module in a crate. + +These prelude names are not part of the module itself: they are implicitly queried during [name resolution]. For example, even though something like [`Box`] is in scope in every module, you cannot refer to it as `self::Box` because it is not a member of the current module. + +r[names.preludes.kinds] +There are several different preludes: + +- [Standard library prelude] +- [Extern prelude] +- [Language prelude] +- [`macro_use` prelude] +- [Tool prelude] + +r[names.preludes.std] +## Standard library prelude + +r[names.preludes.std.intro] +Each crate has a standard library prelude, which consists of the names from a single standard library module. + +r[names.preludes.std.module] +The module used depends on the crate's edition, and on whether the [`no_std` attribute] is applied to the crate: + +Edition | `no_std` not applied | `no_std` applied +--------| --------------------------- | ---------------------------- +2015 | [`std::prelude::rust_2015`] | [`core::prelude::rust_2015`] +2018 | [`std::prelude::rust_2018`] | [`core::prelude::rust_2018`] +2021 | [`std::prelude::rust_2021`] | [`core::prelude::rust_2021`] +2024 | [`std::prelude::rust_2024`] | [`core::prelude::rust_2024`] + +> [!NOTE] +> [`std::prelude::rust_2015`] and [`std::prelude::rust_2018`] have the same contents as [`std::prelude::v1`]. +> +> [`core::prelude::rust_2015`] and [`core::prelude::rust_2018`] have the same contents as [`core::prelude::v1`]. + +> [!NOTE] +> When one of [`core::panic!`] or [`std::panic!`] is brought into scope due to the [standard library prelude], and a user-written [glob import] brings the other into scope, `rustc` currently allows use of `panic!`, even though it is ambiguous. The user-written glob import takes precedence to resolve this ambiguity. +> +> For details, see [names.resolution.expansion.imports.ambiguity.panic-hack]. + +r[names.preludes.extern] +## Extern prelude + +r[names.preludes.extern.intro] +External crates imported with [`extern crate`] in the root module or provided to the compiler (as with the `--extern` flag with `rustc`) are added to the *extern prelude*. If imported with an alias such as `extern crate orig_name as new_name`, then the symbol `new_name` is instead added to the prelude. + +r[names.preludes.extern.core] +The [`core`] crate is always added to the extern prelude. + +r[names.preludes.extern.std] +The [`std`] crate is added as long as the [`no_std` attribute] is not specified in the crate root. + +r[names.preludes.extern.edition2018] +> [!EDITION-2018] +> In the 2015 edition, crates in the extern prelude cannot be referenced via [use declarations], so it is generally standard practice to include `extern crate` declarations to bring them into scope. +> +> Beginning in the 2018 edition, [use declarations] can reference crates in the extern prelude, so it is considered unidiomatic to use `extern crate`. + +> [!NOTE] +> Additional crates that ship with `rustc`, such as [`alloc`], and [`test`](mod@test), are not automatically included with the `--extern` flag when using Cargo. They must be brought into scope with an `extern crate` declaration, even in the 2018 edition. +> +> ```rust +> extern crate alloc; +> use alloc::rc::Rc; +> ``` +> +> Cargo does bring in `proc_macro` to the extern prelude for proc-macro crates only. + +<!-- +See https://github.com/rust-lang/rust/issues/57288 for more about the alloc/test limitation. +--> + +<!-- template:attributes --> +r[names.preludes.extern.no_std] +### The `no_std` attribute + +r[names.preludes.extern.no_std.intro] +The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked automatically and the [standard library prelude] to instead use the `core` prelude. + +> [!EXAMPLE] +> <!-- ignore: test infrastructure can't handle no_std --> +> ```rust,ignore +> #![no_std] +> ``` + +> [!NOTE] +> Using `no_std` is useful when either the crate is targeting a platform that does not support the standard library or is purposefully not using the capabilities of the standard library. Those capabilities are mainly dynamic memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`). + +> [!WARNING] +> Using `no_std` does not prevent the standard library from being linked. It is still valid to write `extern crate std` in the crate or in one of its dependencies; this will cause the compiler to link the `std` crate into the program. + +r[names.preludes.extern.no_std.syntax] +The `no_std` attribute uses the [MetaWord] syntax. + +r[names.preludes.extern.no_std.allowed-positions] +The `no_std` attribute may only be applied to the crate root. + +r[names.preludes.extern.no_std.duplicates] +The `no_std` attribute may be used any number of times on a form. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[names.preludes.extern.no_std.module] +The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of the `std` prelude. + +r[names.preludes.extern.no_std.edition2018] +> [!EDITION-2018] +> Before the 2018 edition, `std` is injected into the crate root by default. If `no_std` is specified, `core` is injected instead. Starting with the 2018 edition, regardless of `no_std` being specified, neither is injected into the crate root. + +r[names.preludes.lang] +## Language prelude + +r[names.preludes.lang.intro] +The language prelude includes names of types and attributes that are built-in to the language. The language prelude is always in scope. + +r[names.preludes.lang.entities] +It includes the following: + +* [Type namespace] + * [Boolean type] --- `bool` + * [`char`] + * [`str`] + * [Integer types] --- `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128` + * [Machine-dependent integer types] --- `usize` and `isize` + * [floating-point types] --- `f32` and `f64` +* [Macro namespace] + * [Built-in attributes] + * [Built-in derive macros][attributes.derive.built-in] + +r[names.preludes.macro_use] +## `macro_use` prelude + +r[names.preludes.macro_use.intro] +The `macro_use` prelude includes macros from external crates that were imported by the [`macro_use` attribute] applied to an [`extern crate`]. + +r[names.preludes.tool] +## Tool prelude + +r[names.preludes.tool.intro] +The tool prelude includes tool names for external tools in the [type namespace]. See the [tool attributes] section for more details. + +<!-- template:attributes --> +r[names.preludes.no_implicit_prelude] +## The `no_implicit_prelude` attribute + +r[names.preludes.no_implicit_prelude.intro] +The *`no_implicit_prelude` [attribute]* is used to prevent implicit preludes from being brought into scope. + +> [!EXAMPLE] +> ```rust +> // The attribute can be applied to the crate root to affect +> // all modules. +> #![no_implicit_prelude] +> +> // Or it can be applied to a module to only affect that module +> // and its descendants. +> #[no_implicit_prelude] +> mod example { +> // ... +> } +> ``` + +r[names.preludes.no_implicit_prelude.syntax] +The `no_implicit_prelude` attribute uses the [MetaWord] syntax. + +r[names.preludes.no_implicit_prelude.allowed-positions] +The `no_implicit_prelude` attribute may only be applied to the crate or to a module. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[names.preludes.no_implicit_prelude.duplicates] +The `no_implicit_prelude` attribute may be used any number of times on a form. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[names.preludes.no_implicit_prelude.excluded-preludes] +The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], [`macro_use` prelude], and the [tool prelude] from being brought into scope for the module and its descendants. + +r[names.preludes.no_implicit_prelude.implicitly-imported-macros] +> [!NOTE] +> Despite `#![no_implicit_prelude]`, `rustc` currently brings certain macros implicitly into scope. Those macros are: +> +> - [`assert!`] +> - [`cfg!`] +> - [`cfg_select!`] +> - [`column!`] +> - [`compile_error!`] +> - [`concat!`] +> - [`concat_bytes!`] +> - [`env!`] +> - [`file!`] +> - [`format_args!`] +> - [`include!`] +> - [`include_bytes!`] +> - [`include_str!`] +> - [`line!`] +> - [`module_path!`] +> - [`option_env!`] +> - [`panic!`] +> - [`stringify!`] +> - [`unreachable!`] +> +> E.g., this works: +> +> ```rust +> #![no_implicit_prelude] +> fn main() { assert!(true); } +> ``` +> +> Don't rely on this behavior; it may be removed in the future. Always bring the items you need into scope explicitly when using `#![no_implicit_prelude]`. +> +> For details, see [Rust PR #62086](https://github.com/rust-lang/rust/pull/62086) and [Rust PR #139493](https://github.com/rust-lang/rust/pull/139493). + +r[names.preludes.no_implicit_prelude.lang] +The `no_implicit_prelude` attribute does not affect the [language prelude]. + +r[names.preludes.no_implicit_prelude.edition2018] +> [!EDITION-2018] +> In the 2015 edition, the `no_implicit_prelude` attribute does not affect the [`macro_use` prelude], and all macros exported from the standard library are still included in the `macro_use` prelude. Starting in the 2018 edition, the attribute does remove the `macro_use` prelude. + +[`char`]: ../types/char.md +[`extern crate`]: ../items/extern-crates.md +[`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute +[`macro_use` prelude]: #macro_use-prelude +[`no_std` attribute]: #the-no_std-attribute +[`str`]: ../types/str.md +[attribute]: ../attributes.md +[Boolean type]: ../types/boolean.md +[Built-in attributes]: ../attributes.md#built-in-attributes-index +[extern prelude]: #extern-prelude +[floating-point types]: ../types/numeric.md#floating-point-types +[glob import]: items.use.glob +[Integer types]: ../types/numeric.md#integer-types +[Language prelude]: #language-prelude +[Machine-dependent integer types]: ../types/numeric.md#machine-dependent-integer-types +[Macro namespace]: namespaces.md +[name resolution]: name-resolution.md +[standard library prelude]: names.preludes.std +[tool attributes]: ../attributes.md#tool-attributes +[Tool prelude]: #tool-prelude +[Type namespace]: namespaces.md +[use declarations]: ../items/use-declarations.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/names/scopes.md b/stdlib/kvlang/reference/rust/reference-repo/src/names/scopes.md new file mode 100644 index 00000000..3f65f9c1 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/names/scopes.md @@ -0,0 +1,384 @@ +r[names.scopes] +# Scopes + +r[names.scopes.intro] +A *scope* is the region of source text where a named [entity] may be referenced with that name. The following sections provide details on the scoping rules and behavior, which depend on the kind of entity and where it is declared. The process of how names are resolved to entities is described in the [name resolution] chapter. More information on "drop scopes" used for the purpose of running destructors may be found in the [destructors] chapter. + +r[names.scopes.items] +## Item scopes + +r[names.scopes.items.module] +The name of an [item][items] declared directly in a [module] has a scope that extends from the start of the module to the end of the module. These items are also members of the module and can be referred to with a [path] leading from their module. + +r[names.scopes.items.statement] +The name of an item declared as a [statement] has a scope that extends from the start of the block the item statement is in until the end of the block. + +r[names.scopes.items.duplicate] +It is an error to introduce an item with a duplicate name of another item in the same [namespace] within the same module or block. [Asterisk glob imports] have special behavior for dealing with duplicate names and shadowing, see the linked chapter for more details. + +r[names.scopes.items.shadow-prelude] +Items in a module may shadow items in a [prelude](#prelude-scopes). + +r[names.scopes.items.nested-modules] +Item names from outer modules are not in scope within a nested module. A [path] may be used to refer to an item in another module. + +r[names.scopes.associated-items] +### Associated item scopes + +r[names.scopes.associated-items.scope] +[Associated items] are not scoped and can only be referred to by using a [path] leading from the type or trait they are associated with. [Methods] can also be referred to via [call expressions]. + +r[names.scopes.associated-items.duplicate] +Similar to items within a module or block, it is an error to introduce an item within a trait or implementation that is a duplicate of another item in the trait or impl in the same namespace. + +r[names.scopes.pattern-bindings] +## Pattern binding scopes + +r[names.scopes.pattern-bindings.intro] +The scope of a local variable [pattern] binding depends on where it is used: + +r[names.scopes.pattern-bindings.let] +* [`let` statement] bindings range from just after the `let` statement until the end of the block where it is declared. +r[names.scopes.pattern-bindings.parameter] +* [Function parameter] bindings are within the body of the function. +r[names.scopes.pattern-bindings.closure] +* [Closure parameter] bindings are within the closure body. +r[names.scopes.pattern-bindings.loop] +* [`for`] bindings are within the loop body. +r[names.scopes.pattern-bindings.let-chains] +* [`if let`] and [`while let`] bindings are valid in the following conditions as well as the consequent block. +r[names.scopes.pattern-bindings.match-arm] +* [`match` arms] bindings are within the [match guard] and the match arm expression. +r[names.scopes.pattern-bindings.match-guard-let] +* [`match` guard `let`] bindings are valid in the following guard conditions and the match arm expression. + +r[names.scopes.pattern-bindings.items] +Local variable scopes do not extend into item declarations. +<!-- Not entirely, see https://github.com/rust-lang/rust/issues/33118 --> + +### Pattern binding shadowing + +r[names.scopes.pattern-bindings.shadow] +Pattern bindings are allowed to shadow any name in scope with the following exceptions which are an error: + +* [Const generic parameters] +* [Static items] +* [Const items] +* Constructors for [structs] and [enums] + +The following example illustrates how local bindings can shadow item declarations: + +```rust +fn shadow_example() { + // Since there are no local variables in scope yet, this resolves to the function. + foo(); // prints `function` + let foo = || println!("closure"); + fn foo() { println!("function"); } + // This resolves to the local closure since it shadows the item. + foo(); // prints `closure` +} +``` + +r[names.scopes.generic-parameters] +## Generic parameter scopes + +r[names.scopes.generic-parameters.param-list] +Generic parameters are declared in a [GenericParams] list. The scope of a generic parameter is within the item it is declared on. + +r[names.scopes.generic-parameters.order-independent] +All parameters are in scope within the generic parameter list regardless of the order they are declared. The following shows some examples where a parameter may be referenced before it is declared: + +```rust +// The 'b bound is referenced before it is declared. +fn params_scope<'a: 'b, 'b>() {} + +# trait SomeTrait<const Z: usize> {} +// The const N is referenced in the trait bound before it is declared. +fn f<T: SomeTrait<N>, const N: usize>() {} +``` + +r[names.scopes.generic-parameters.bounds] +Generic parameters are also in scope for type bounds and where clauses, for example: + +```rust +# trait SomeTrait<'a, T> {} +// The <'a, U> for `SomeTrait` refer to the 'a and U parameters of `bounds_scope`. +fn bounds_scope<'a, T: SomeTrait<'a, U>, U>() {} + +fn where_scope<'a, T, U>() + where T: SomeTrait<'a, U> +{} +``` + +r[names.scopes.generic-parameters.inner-items] +It is an error for [items] declared inside a function to refer to a generic parameter from their outer scope. + +```rust,compile_fail +fn example<T>() { + fn inner(x: T) {} // ERROR: can't use generic parameters from outer function +} +``` + +### Generic parameter shadowing + +r[names.scopes.generic-parameters.shadow] +It is an error to shadow a generic parameter with the exception that items declared within functions are allowed to shadow generic parameter names from the function. + +```rust +fn example<'a, T, const N: usize>() { + // Items within functions are allowed to shadow generic parameter in scope. + fn inner_lifetime<'a>() {} // OK + fn inner_type<T>() {} // OK + fn inner_const<const N: usize>() {} // OK +} +``` + +```rust,compile_fail +trait SomeTrait<'a, T, const N: usize> { + fn example_lifetime<'a>() {} // ERROR: 'a is already in use + fn example_type<T>() {} // ERROR: T is already in use + fn example_const<const N: usize>() {} // ERROR: N is already in use + fn example_mixed<const T: usize>() {} // ERROR: T is already in use +} +``` + +r[names.scopes.lifetimes] +### Lifetime scopes + +r[names.scopes.lifetimes.intro] +Lifetime parameters are declared in a [GenericParams] list and [higher-ranked trait bounds][hrtb]. + +r[names.scopes.lifetimes.special] +The `'static` lifetime and [placeholder lifetime] `'_` have a special meaning and cannot be declared as a parameter. + +#### Lifetime generic parameter scopes + +r[names.scopes.lifetimes.generic] +[Constant] and [static] items and [const contexts] only ever allow `'static` lifetime references, so no other lifetime may be in scope within them. [Associated consts] do allow referring to lifetimes declared in their trait or implementation. + +#### Higher-ranked trait bound scopes + +r[names.scopes.lifetimes.higher-ranked] +The scope of a lifetime parameter declared as a [higher-ranked trait bound][hrtb] depends on the scenario where it is used. + +* As a [TypeBoundWhereClauseItem] the declared lifetimes are in scope in the type and the type bounds. +* As a [TraitBound] the declared lifetimes are in scope within the bound type path. +* As a [BareFunctionType] the declared lifetimes are in scope within the function parameters and return type. + +```rust +# trait Trait<'a>{} + +fn where_clause<T>() + // 'a is in scope in both the type and the type bounds. + where for <'a> &'a T: Trait<'a> +{} + +fn bound<T>() + // 'a is in scope within the bound. + where T: for <'a> Trait<'a> +{} + +# struct Example<'a> { +# field: &'a u32 +# } + +// 'a is in scope in both the parameters and return type. +type FnExample = for<'a> fn(x: Example<'a>) -> Example<'a>; +``` + +#### Impl trait restrictions + +r[names.scopes.lifetimes.impl-trait] +[Impl trait] types can only reference lifetimes declared on a function or implementation. + +<!-- not able to demonstrate the scope error because the compiler panics + https://github.com/rust-lang/rust/issues/67830 +--> +```rust +# trait Trait1 { +# type Item; +# } +# trait Trait2<'a> {} +# +# struct Example; +# +# impl Trait1 for Example { +# type Item = Element; +# } +# +# struct Element; +# impl<'a> Trait2<'a> for Element {} +# +// The `impl Trait2` here is not allowed to refer to 'b but it is allowed to +// refer to 'a. +fn foo<'a>() -> impl for<'b> Trait1<Item = impl Trait2<'a> + use<'a>> { + // ... +# Example +} +``` + +r[names.scopes.loop-label] +## Loop label scopes + +r[names.scopes.loop-label.scope] +[Loop labels] may be declared by a [loop expression]. The scope of a loop label is from the point it is declared till the end of the loop expression. The scope does not extend into [items], [closures], [async blocks], [const arguments], [const contexts], and the iterator expression of the defining [`for` loop]. + +```rust +'a: for n in 0..3 { + if n % 2 == 0 { + break 'a; + } + fn inner() { + // Using 'a here would be an error. + // break 'a; + } +} + +// The label is in scope for the expression of `while` loops. +'a: while break 'a {} // Loop does not run. +'a: while let _ = break 'a {} // Loop does not run. + +// The label is not in scope in the defining `for` loop: +'a: for outer in 0..5 { + // This will break the outer loop, skipping the inner loop and stopping + // the outer loop. + 'a: for inner in { break 'a; 0..1 } { + println!("{}", inner); // This does not run. + } + println!("{}", outer); // This does not run, either. +} + +``` + +r[names.scopes.loop-label.shadow] +Loop labels may shadow labels of the same name in outer scopes. References to a label refer to the closest definition. + +```rust +// Loop label shadowing example. +'a: for outer in 0..5 { + 'a: for inner in 0..5 { + // This terminates the inner loop, but the outer loop continues to run. + break 'a; + } +} +``` + +r[names.scopes.prelude] +## Prelude scopes + +r[names.scopes.prelude.intro] +[Preludes] bring entities into scope of every module. The entities are not members of the module, but are implicitly queried during [name resolution]. + +r[names.scopes.prelude.shadow] +The prelude names may be shadowed by declarations in a module. + +r[names.scopes.prelude.layers] +The preludes are layered such that one shadows another if they contain entities of the same name. The order that preludes may shadow other preludes is the following where earlier entries may shadow later ones: + +1. [Extern prelude] +2. [Tool prelude] +3. [`macro_use` prelude] +4. [Standard library prelude] +5. [Language prelude] + +r[names.scopes.macro_rules] +## `macro_rules` scopes + +The scope of `macro_rules` macros is described in the [Macros By Example] chapter. The behavior depends on the use of the [`macro_use`] and [`macro_export`] attributes. + +r[names.scopes.derive] +## Derive macro helper attributes + +r[names.scopes.derive.scope] +[Derive macro helper attributes] are in scope in the item where their corresponding [`derive` attribute] is specified. The scope extends from just after the `derive` attribute to the end of the item. <!-- Note: Not strictly true, see https://github.com/rust-lang/rust/issues/79202, but this is the intention. --> + +r[names.scopes.derive.shadow] +Helper attributes shadow other attributes of the same name in scope. + +r[names.scopes.self] +## `Self` scope + +r[names.scopes.self.intro] +Although [`Self`] is a keyword with special meaning, it interacts with name resolution in a way similar to normal names. + +r[names.scopes.self.def-scope] +The implicit `Self` type in the definition of a [struct], [enum], [union], [trait], or [implementation] is treated similarly to a [generic parameter](#generic-parameter-scopes), and is in scope in the same way as a generic type parameter. + +r[names.scopes.self.impl-scope] +The implicit `Self` constructor in the value [namespace] of an [implementation] is in scope within the body of the implementation (the implementation's [associated items]). + +```rust +// Self type within struct definition. +struct Recursive { + f1: Option<Box<Self>> +} + +// Self type within generic parameters. +struct SelfGeneric<T: Into<Self>>(T); + +// Self value constructor within an implementation. +struct ImplExample(); +impl ImplExample { + fn example() -> Self { // Self type + Self() // Self value constructor + } +} +``` + +[`derive` attribute]: ../attributes/derive.md +[`for` loop]: ../expressions/loop-expr.md#iterator-loops +[`for`]: ../expressions/loop-expr.md#iterator-loops +[`if let`]: ../expressions/if-expr.md#if-let-patterns +[`while let`]: ../expressions/loop-expr.md#while-let-patterns +[`let` statement]: ../statements.md#let-statements +[`macro_export`]: ../macros-by-example.md#the-macro_export-attribute +[`macro_use` prelude]: preludes.md#macro_use-prelude +[`macro_use`]: ../macros-by-example.md#the-macro_use-attribute +[`match` arms]: ../expressions/match-expr.md +[`match` guard `let`]: expr.match.guard.let +[`Self`]: ../paths.md#self-1 +[Associated consts]: ../items/associated-items.md#associated-constants +[associated items]: ../items/associated-items.md +[Asterisk glob imports]: ../items/use-declarations.md +[async blocks]: ../expressions/block-expr.md#async-blocks +[call expressions]: ../expressions/call-expr.md +[Closure parameter]: ../expressions/closure-expr.md +[closures]: ../expressions/closure-expr.md +[const arguments]: ../items/generics.md#const-generics +[const contexts]: ../const_eval.md#const-context +[Const generic parameters]: ../items/generics.md#const-generics +[Const items]: ../items/constant-items.md +[Constant]: ../items/constant-items.md +[Derive macro helper attributes]: ../procedural-macros.md#derive-macro-helper-attributes +[destructors]: ../destructors.md +[entity]: ../names.md +[enum]: ../items/enumerations.mdr +[enums]: ../items/enumerations.md +[Extern prelude]: preludes.md#extern-prelude +[Function parameter]: ../items/functions.md#function-parameters +[hrtb]: ../trait-bounds.md#higher-ranked-trait-bounds +[Impl trait]: ../types/impl-trait.md +[implementation]: ../items/implementations.md +[items]: ../items.md +[Language prelude]: preludes.md#language-prelude +[loop expression]: ../expressions/loop-expr.md +[Loop labels]: ../expressions/loop-expr.md#loop-labels +[Macros By Example]: ../macros-by-example.md +[match guard]: ../expressions/match-expr.md#match-guards +[methods]: ../items/associated-items.md#methods +[module]: ../items/modules.md +[name resolution]: name-resolution.md +[namespace]: namespaces.md +[path]: ../paths.md +[pattern]: ../patterns.md +[placeholder lifetime]: ../lifetime-elision.md +[preludes]: preludes.md +[Standard library prelude]: preludes.md#standard-library-prelude +[statement]: ../statements.md +[Static items]: ../items/static-items.md +[static]: ../items/static-items.md +[struct]: ../items/structs.md +[structs]: ../items/structs.md +[Tool prelude]: preludes.md#tool-prelude +[trait]: ../items/traits.md +[union]: ../items/unions.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/notation.md b/stdlib/kvlang/reference/rust/reference-repo/src/notation.md new file mode 100644 index 00000000..7537c67d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/notation.md @@ -0,0 +1,78 @@ +r[notation] +# Notation + +r[notation.grammar] +## Grammar + +r[notation.grammar.syntax] + +The following notations are used by the *Lexer* and *Syntax* grammar snippets: + +| Notation | Examples | Meaning | +|-------------------|-------------------------------|-------------------------------------------| +| CAPITAL | KW_IF, INTEGER_LITERAL | A token produced by the lexer | +| _ItalicCamelCase_ | _LetStatement_, _Item_ | A syntactical production | +| `string` | `x`, `while`, `*` | The exact character(s) | +| x<sup>?</sup> | `pub`<sup>?</sup> | An optional item | +| x<sup>\*</sup> | _OuterAttribute_<sup>\*</sup> | 0 or more of x | +| x<sup>+</sup> | _MacroMatch_<sup>+</sup> | 1 or more of x | +| x<sup>a..b</sup> | HEX_DIGIT<sup>1..6</sup> | a to b repetitions of x, exclusive of b | +| x<sup>a..=b</sup> | HEX_DIGIT<sup>1..=5</sup> | a to b repetitions of x, inclusive of b | +| x<sup>n:a..=b</sup> | `#`<sup>n:1..=255</sup> | a to b repetitions of x (inclusive of b), with the count bound to the name n | +| x<sup>n</sup> | `#`<sup>n</sup> | x repeated the number of times bound to n by a previous labeled repetition | +| Rule1 Rule2 | `fn` _Name_ _Parameters_ | Sequence of rules in order | +| \| | `u8` \| `u16`, Block \| Item | Either one or another | +| ! | !COMMENT | Matches if the expression does not follow, without consuming any input | +| \[ ] | \[`b` `B`] | Any of the characters listed | +| \[ - ] | \[`a`-`z`] | Any of the characters in the range | +| ~\[ ] | ~\[`b` `B`] | Any characters, except those listed | +| ~`string` | ~`\n`, ~`*/` | Any characters, except this sequence | +| ( ) | (`,` _Parameter_)<sup>?</sup> | Groups items | +| ^ | `b'` ^ ASCII_FOR_CHAR | The rest of the sequence must match or parsing fails unconditionally ([hard cut operator]) | +| U+xxxx..xxxxxx | U+0060 | A single Unicode character | +| \<text\> | \<any ASCII char except CR\> | An English description of what should be matched | +| Rule <sub>suffix</sub> | IDENTIFIER_OR_KEYWORD <sub>_except `crate`_</sub> | A modification to the previous rule | +| // Comment. | // Single line comment. | A comment extending to the end of the line. | + +Sequences have a higher precedence than `|` alternation. + +r[notation.grammar.cut] +### The hard cut operator + +The grammar uses ordered alternation: the parser tries alternatives left to right and takes the first that matches. If an alternative fails partway through a sequence, the parser normally backtracks and tries the next alternative. The cut operator (`^`) prevents this. Once every expression to the left of `^` in a sequence has matched, the rest of the sequence must match or parsing fails unconditionally. + +Mizushima et al. introduced [cut operators][cut operator paper] to parsing expression grammars. In the PEG literature, a *soft cut* prevents backtracking only within the immediately enclosing ordered choice --- outer choices can still recover. A *hard cut* prevents all backtracking past the cut point; failure is definitive. The `^` used in this grammar is a hard cut. + +The hard cut operator is necessary because some tokens in Rust begin with a prefix that is itself a valid token. For example, `c"` begins a C string literal, but `c` alone is a valid identifier. Without the cut, if `c"\0"` failed to lex as a C string literal (because null bytes are not allowed in C strings), the parser could backtrack and lex it as two tokens: the identifier `c` and the string literal `"\0"`. The [cut after `c"`] prevents this --- once the opening delimiter is recognized, the parser cannot go back. The same reasoning applies to [byte literals], [byte string literals], [raw string literals], and other literals with prefixes that are themselves valid tokens. + +r[notation.grammar.string-tables] +### String table productions + +Some rules in the grammar — notably [unary operators], [binary +operators], and [keywords] — are given in a simplified form: as a listing +of printable strings. These cases form a subset of the rules regarding the +[token][tokens] rule, and are assumed to be the result of a lexical-analysis +phase feeding the parser, driven by a <abbr title="Deterministic Finite +Automaton">DFA</abbr>, operating over the disjunction of all such string table +entries. + +When such a string in `monospace` font occurs inside the grammar, +it is an implicit reference to a single member of such a string table +production. See [tokens] for more information. + +r[notation.grammar.visualizations] +### Grammar visualizations + +Below each grammar block is a button to toggle the display of a [syntax diagram]. A square element is a non-terminal rule, and a rounded rectangle is a terminal. + +[binary operators]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[byte literals]: tokens.md#r-lex.token.byte.syntax +[byte string literals]: tokens.md#r-lex.token.str-byte.syntax +[cut after `c"`]: tokens.md#r-lex.token.str-c.syntax +[cut operator paper]: https://kmizu.github.io/papers/paste513-mizushima.pdf +[hard cut operator]: notation.md#the-hard-cut-operator +[keywords]: keywords.md +[raw string literals]: tokens.md#r-lex.token.literal.str-raw.syntax +[syntax diagram]: https://en.wikipedia.org/wiki/Syntax_diagram +[tokens]: tokens.md +[unary operators]: expressions/operator-expr.md#borrow-operators diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/panic.md b/stdlib/kvlang/reference/rust/reference-repo/src/panic.md new file mode 100644 index 00000000..2be7e42f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/panic.md @@ -0,0 +1,150 @@ +r[panic] +# Panic + +r[panic.intro] +Rust provides a mechanism to prevent a function from returning normally, and instead "panic," which is a response to an error condition that is typically not expected to be recoverable within the context in which the error is encountered. + +r[panic.lang-ops] +Some language constructs, such as out-of-bounds [array indexing], panic automatically. + +r[panic.control] +There are also language features that provide a level of control over panic behavior: + +* A [_panic handler_][panic handler] defines the behavior of a panic. +* [FFI ABIs](items/functions.md#unwinding) may alter how panics behave. + +> [!NOTE] +> The standard library provides the capability to explicitly panic via the [`panic!` macro][panic!]. + +r[panic.panic_handler] +## The `panic_handler` attribute + +r[panic.panic_handler.intro] +The *`panic_handler` attribute* can be applied to a function to define the behavior of panics. + +r[panic.panic_handler.allowed-positions] +The `panic_handler` attribute can only be applied to a function with signature `fn(&PanicInfo) -> !`. + +> [!NOTE] +> The [`PanicInfo`] struct contains information about the location of the panic. + +r[panic.panic_handler.unique] +There must be a single `panic_handler` function in the dependency graph. + +Below is shown a `panic_handler` function that logs the panic message and then halts the thread. + +<!-- ignore: test infrastructure can't handle no_std --> +```rust,ignore +#![no_std] + +use core::fmt::{self, Write}; +use core::panic::PanicInfo; + +struct Sink { + // .. +# _0: (), +} +# +# impl Sink { +# fn new() -> Sink { Sink { _0: () }} +# } +# +# impl fmt::Write for Sink { +# fn write_str(&mut self, _: &str) -> fmt::Result { Ok(()) } +# } + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + let mut sink = Sink::new(); + + // logs "panicked at '$reason', src/main.rs:27:4" to some `sink` + let _ = writeln!(sink, "{}", info); + + loop {} +} +``` + +r[panic.panic_handler.std] +### Standard behavior + +r[panic.panic_handler.std.kinds] +`std` provides two different panic handlers: + +* `unwind` --- unwinds the stack and is potentially recoverable. +* `abort` ---- aborts the process and is non-recoverable. + +Not all targets may provide the `unwind` handler. + +> [!NOTE] +> The panic handler used when linking with `std` can be set with the [`-C panic`] CLI flag. The default for most targets is `unwind`. +> +> The standard library's panic behavior can be modified at runtime with the [`std::panic::set_hook`] function. + +r[panic.panic_handler.std.no_std] +Linking a [`no_std`] binary, dylib, cdylib, or staticlib will require specifying your own panic handler. + +r[panic.strategy] +## Panic strategy + +r[panic.strategy.intro] +The _panic strategy_ defines the kind of panic behavior that a crate is built to support. + +> [!NOTE] +> The panic strategy can be chosen in `rustc` with the [`-C panic`] CLI flag. +> +> When generating a binary, dylib, cdylib, or staticlib and linking with `std`, the `-C panic` CLI flag also influences which [panic handler] is used. + +> [!NOTE] +> When compiling code with the `abort` panic strategy, the optimizer may assume that unwinding across Rust frames is impossible, which can result in both code-size and runtime speed improvements. + +> [!NOTE] +> See [link.unwinding] for restrictions on linking crates with different panic strategies. An implication is that crates built with the `unwind` strategy can use the `abort` panic handler, but the `abort` strategy cannot use the `unwind` panic handler. + +r[panic.unwind] +## Unwinding + +r[panic.unwind.intro] +Panicking may either be recoverable or non-recoverable, though it can be configured (by choosing a non-unwinding panic handler) to always be non-recoverable. (The converse is not true: the `unwind` handler does not guarantee that all panics are recoverable, only that panicking via the `panic!` macro and similar standard library mechanisms is recoverable.) + +r[panic.unwind.destruction] +When a panic occurs, the `unwind` handler "unwinds" Rust frames, just as C++'s `throw` unwinds C++ frames, until the panic reaches the point of recovery (for instance at a thread boundary). This means that as the panic traverses Rust frames, live objects in those frames that [implement `Drop`][destructors] will have their `drop` methods called. Thus, when normal execution resumes, no-longer-accessible objects will have been "cleaned up" just as if they had gone out of scope normally. + +> [!NOTE] +> As long as this guarantee of resource-cleanup is preserved, "unwinding" may be implemented without actually using the mechanism used by C++ for the target platform. + +> [!NOTE] +> The standard library provides two mechanisms for recovering from a panic, [`std::panic::catch_unwind`] (which enables recovery within the panicking thread) and [`std::thread::spawn`] (which automatically sets up panic recovery for the spawned thread so that other threads may continue running). + +r[panic.unwind.ffi] +### Unwinding across FFI boundaries + +r[panic.unwind.ffi.intro] +It is possible to unwind across FFI boundaries using an [appropriate ABI declaration][unwind-abi]. While useful in certain cases, this creates unique opportunities for undefined behavior, especially when multiple language runtimes are involved. + +r[panic.unwind.ffi.undefined] +Unwinding with the wrong ABI is undefined behavior: + +* Causing an unwind into Rust code from a foreign function that was called via a function declaration or pointer declared with a non-unwinding ABI, such as `"C"`, `"system"`, etc. (For example, this case occurs when such a function written in C++ throws an exception that is uncaught and propagates to Rust.) +* Calling a Rust `extern` function that unwinds (with `extern "C-unwind"` or another ABI that permits unwinding) from code that does not support unwinding, such as code compiled with GCC or Clang using `-fno-exceptions` + +r[panic.unwind.ffi.catch-foreign] +Catching a foreign unwinding operation (such as a C++ exception) using [`std::panic::catch_unwind`], [`std::thread::JoinHandle::join`], or by letting it propagate beyond the Rust `main()` function or thread root will have one of two behaviors, and it is unspecified which will occur: + +* The process aborts. +* The function returns a [`Result::Err`] containing an opaque type. + +> [!NOTE] +> Rust code compiled or linked with a different instance of the Rust standard library counts as a "foreign exception" for the purpose of this guarantee. Thus, a library that uses `panic!` and is linked against one version of the Rust standard library, invoked from an application that uses a different version of the standard library, may cause the entire application to abort even if the library is only used within a child thread. + +r[panic.unwind.ffi.dispose-panic] +There are currently no guarantees about the behavior that occurs when a foreign runtime attempts to dispose of, or rethrow, a Rust `panic` payload. In other words, an unwind originated from a Rust runtime must either lead to termination of the process or be caught by the same runtime. + +[`-C panic`]: ../rustc/codegen-options/index.html#panic +[`no_std`]: names/preludes.md#the-no_std-attribute +[`PanicInfo`]: core::panic::PanicInfo +[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions +[attribute]: attributes.md +[destructors]: destructors.md +[panic handler]: #the-panic_handler-attribute +[runtime]: runtime.md +[unwind-abi]: items/functions.md#unwinding diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/paths.md b/stdlib/kvlang/reference/rust/reference-repo/src/paths.md new file mode 100644 index 00000000..81484efd --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/paths.md @@ -0,0 +1,521 @@ +r[paths] +# Paths + +r[paths.intro] +A *path* is a sequence of one or more path segments separated by `::` tokens. Paths are used to refer to [items], values, [types], [macros], and [attributes]. + +Two examples of simple paths consisting of only identifier segments: + +<!-- ignore: syntax fragment --> +```rust,ignore +x; +x::y::z; +``` + +## Types of paths + +r[paths.simple] +### Simple paths + +r[paths.simple.syntax] +```grammar,paths +SimplePath -> + `::`? SimplePathSegment (`::` SimplePathSegment)* + +SimplePathSegment -> + IDENTIFIER | `super` | `self` | `crate` | `$crate` +``` + +r[paths.simple.intro] +Simple paths are used in [visibility] markers, [attributes], [macros][mbe], and [`use`] items. For example: + +```rust +use std::io::{self, Write}; +mod m { + #[clippy::cyclomatic_complexity = "0"] + pub (in super) fn f1() {} +} +``` + +r[paths.expr] +### Paths in expressions + +r[paths.expr.syntax] +```grammar,paths +PathInExpression -> + `::`? PathExprSegment (`::` PathExprSegment)* + +PathExprSegment -> + PathIdentSegment (`::` GenericArgs)? + +PathIdentSegment -> + IDENTIFIER | `super` | `self` | `Self` | `crate` | `$crate` + +GenericArgs -> + `<` GenericArgList? `>` + | `(` TypeList? `)` (`->` TypeNoBounds)? + +GenericArgList -> + ( GenericArg `,` )* GenericArg `,`? + +TypeList -> + ( Type `,` )* Type `,`? + +GenericArg -> + Lifetime | Type | GenericArgsConst | GenericArgsBinding | GenericArgsBounds + +GenericArgsConst -> + BlockExpression + | LiteralExpression + | `-` LiteralExpression + | SimplePathSegment + +GenericArgsBinding -> + TypePathSegment `=` Type + +GenericArgsBounds -> + TypePathSegment `:` Bounds? +``` + +r[paths.expr.intro] +Paths in expressions allow for paths with generic arguments to be specified. They are used in various places in [expressions] and [patterns]. + +r[paths.expr.turbofish] +The `::` token is required before the opening `<` for generic arguments to avoid ambiguity with the less-than operator. This is colloquially known as "turbofish" syntax. + +```rust +(0..10).collect::<Vec<_>>(); +Vec::<u8>::with_capacity(1024); +``` + +r[paths.expr.argument-order] +The order of generic arguments is restricted to lifetime arguments, then type arguments, then const arguments, then equality constraints. + +r[paths.expr.complex-const-params] +Const arguments must be surrounded by braces unless they are a [literal], an [inferred const], or a single segment path. An [inferred const] may not be surrounded by braces. + +```rust +mod m { + pub const C: usize = 1; +} +const C: usize = m::C; +fn f<const N: usize>() -> [u8; N] { [0; N] } + +let _ = f::<1>(); // Literal. +let _: [_; 1] = f::<_>(); // Inferred const. +let _: [_; 1] = f::<(((_)))>(); // Inferred const. +let _ = f::<C>(); // Single segment path. +let _ = f::<{ m::C }>(); // Multi-segment path must be braced. +``` + +```rust,compile_fail +fn f<const N: usize>() -> [u8; N] { [0; _] } +let _: [_; 1] = f::<{ _ }>(); +// ^ ERROR `_` not allowed here +``` + +> [!NOTE] +> In a generic argument list, an [inferred const] is parsed as an [inferred type][InferredType] but then semantically treated as a separate kind of [const generic argument]. + +r[paths.expr.impl-trait-params] +The synthetic type parameters corresponding to `impl Trait` types are implicit, and these cannot be explicitly specified. + +r[paths.qualified] +## Qualified paths + +r[paths.qualified.syntax] +```grammar,paths +QualifiedPathInExpression -> QualifiedPathType (`::` PathExprSegment)+ + +QualifiedPathType -> `<` Type (`as` TypePath)? `>` + +QualifiedPathInType -> QualifiedPathType (`::` TypePathSegment)+ +``` + +r[paths.qualified.intro] +Fully qualified paths allow for disambiguating the path for [trait implementations] and for specifying [canonical paths](#canonical-paths). When used in a type specification, it supports using the type syntax specified below. + +```rust +struct S; +impl S { + fn f() { println!("S"); } +} +trait T1 { + fn f() { println!("T1 f"); } +} +impl T1 for S {} +trait T2 { + fn f() { println!("T2 f"); } +} +impl T2 for S {} +S::f(); // Calls the inherent impl. +<S as T1>::f(); // Calls the T1 trait function. +<S as T2>::f(); // Calls the T2 trait function. +``` + +r[paths.type] +### Paths in types + +r[paths.type.syntax] +```grammar,paths +TypePath -> `::`? TypePathSegment (`::` TypePathSegment)* + +TypePathSegment -> PathIdentSegment (`::`? GenericArgs)? +``` + +r[paths.type.intro] +Type paths are used within type definitions, trait bounds, and qualified paths. + +r[paths.type.turbofish] +Although the `::` token is allowed before the generics arguments, it is not required because there is no ambiguity like there is in [PathInExpression]. + +```rust +# mod ops { +# pub struct Range<T> {f1: T} +# pub trait Index<T> {} +# pub struct Example<'a> {f1: &'a i32} +# } +# struct S; +impl ops::Index<ops::Range<usize>> for S { /*...*/ } +fn i<'a>() -> impl Iterator<Item = ops::Example<'a>> { + // ... +# const EXAMPLE: Vec<ops::Example<'static>> = Vec::new(); +# EXAMPLE.into_iter() +} +type G = std::boxed::Box<dyn std::ops::FnOnce(isize) -> isize>; +``` + +r[paths.qualifiers] +## Path qualifiers + +r[paths.qualifiers.intro] +Paths can be denoted with various leading qualifiers to change the meaning of how it is resolved. + +> [!NOTE] +> [`use` declarations] have additional behaviors and restrictions for `self`, `super`, `crate`, and `$crate`. + +r[paths.qualifiers.global-root] +### `::` + +r[paths.qualifiers.global-root.intro] +Paths starting with `::` are considered to be *global paths* where the segments of the path start being resolved from a place which differs based on edition. Each identifier in the path must resolve to an item. + +r[paths.qualifiers.global-root.edition2018] +> [!EDITION-2018] +> In the 2015 Edition, identifiers resolve from the "crate root" (`crate::` in the 2018 edition), which contains a variety of different items, including external crates, default crates such as `std` or `core`, and items in the top level of the crate (including `use` imports). +> +> Beginning with the 2018 Edition, paths starting with `::` resolve from crates in the [extern prelude]. That is, they must be followed by the name of a crate. + +```rust +pub fn foo() { + // In the 2018 edition, this accesses `std` via the extern prelude. + // In the 2015 edition, this accesses `std` via the crate root. + let now = ::std::time::Instant::now(); + println!("{:?}", now); +} +``` + +```rust,edition2015 +// 2015 Edition +mod a { + pub fn foo() {} +} +mod b { + pub fn foo() { + ::a::foo(); // call `a`'s foo function + // In Rust 2018, `::a` would be interpreted as the crate `a`. + } +} +# fn main() {} +``` + +r[paths.qualifiers.mod-self] +### `self` + +r[paths.qualifiers.mod-self.intro] +`self` resolves the path relative to the current module. + +r[paths.qualifiers.mod-self.restriction] +`self` may only be used as the first segment of a path (without a preceding `::`) or as the last segment (preceded by `::`). + +r[paths.qualifiers.mod-self.trailing] +When `self` appears as the last segment of a path, it refers to the entity named by the preceding segment. The preceding path must resolve to a [module], [enumeration], or [trait]. + +```rust +mod m { + pub enum E { V1 } + pub trait Tr {} + pub(in crate::m::self) fn g() {} // OK: Modules can be parents of `self`. +} +type Ty = m::E::self; // OK: Enumerations can be parents of `self`. +fn f<T: m::Tr::self>() {} // OK: Traits can be parents of `self`. +# fn main() { let _: Ty = m::E::V1; } +``` + +```rust,compile_fail,E0223 +struct S; +type Ty = S::self; // ERROR: Structs cannot be parents of `self`. +# fn main() {} +``` + +> [!NOTE] +> See [items.use.self] for additional rules about `self` in `use` declarations. + +r[paths.qualifiers.self-pat] +In a method body, a path which consists of a single `self` segment resolves to the method's self parameter. + +```rust +fn foo() {} +fn bar() { + self::foo(); +} +struct S(bool); +impl S { + fn baz(self) { + self.0; + } +} +# fn main() {} +``` + +r[paths.qualifiers.type-self] +### `Self` + +r[paths.qualifiers.type-self.intro] +`Self`, with a capital "S", is used to refer to the current type being implemented or defined. It may be used in the following situations: + +r[paths.qualifiers.type-self.trait] +* In a [trait] definition, it refers to the type implementing the trait. + +r[paths.qualifiers.type-self.impl] +* In an [implementation], it refers to the type being implemented. When implementing a tuple or unit [struct], it also refers to the constructor in the [value namespace]. + +r[paths.qualifiers.type-self.type] +* In the definition of a [struct], [enumeration], or [union], it refers to the type being defined. The definition is not allowed to be infinitely recursive (there must be an indirection). + +r[paths.qualifiers.type-self.scope] +The scope of `Self` behaves similarly to a generic parameter; see the [`Self` scope] section for more details. + +r[paths.qualifiers.type-self.allowed-positions] +`Self` can only be used as the first segment, without a preceding `::`. + +r[paths.qualifiers.type-self.no-generics] +The `Self` path cannot include generic arguments (as in `Self::<i32>`). + +```rust +trait T { + type Item; + const C: i32; + // `Self` will be whatever type that implements `T`. + fn new() -> Self; + // `Self::Item` will be the type alias in the implementation. + fn f(&self) -> Self::Item; +} +struct S; +impl T for S { + type Item = i32; + const C: i32 = 9; + fn new() -> Self { // `Self` is the type `S`. + S + } + fn f(&self) -> Self::Item { // `Self::Item` is the type `i32`. + Self::C // `Self::C` is the constant value `9`. + } +} + +// `Self` is in scope within the generics of a trait definition, +// to refer to the type being defined. +trait Add<Rhs = Self> { + type Output; + // `Self` can also reference associated items of the + // type being implemented. + fn add(self, rhs: Rhs) -> Self::Output; +} + +struct NonEmptyList<T> { + head: T, + // A struct can reference itself (as long as it is not + // infinitely recursive). + tail: Option<Box<Self>>, +} +``` + +r[paths.qualifiers.super] +### `super` + +r[paths.qualifiers.super.intro] +`super` in a path resolves to the parent module. + +r[paths.qualifiers.super.allowed-positions] +It may only be used in leading segments of the path, possibly after an initial `self` segment. + +```rust +mod a { + pub fn foo() {} +} +mod b { + pub fn foo() { + super::a::foo(); // call a's foo function + } +} +# fn main() {} +``` + +r[paths.qualifiers.super.repetition] +`super` may be repeated several times after the first `super` or `self` to refer to ancestor modules. + +```rust +mod a { + fn foo() {} + + mod b { + mod c { + fn foo() { + super::super::foo(); // call a's foo function + self::super::super::foo(); // call a's foo function + } + } + } +} +# fn main() {} +``` + +r[paths.qualifiers.crate] +### `crate` + +r[paths.qualifiers.crate.intro] +`crate` resolves the path relative to the current crate. + +r[paths.qualifiers.crate.allowed-positions] +`crate` can only be used as the first segment, without a preceding `::`. + +```rust +fn foo() {} +mod a { + fn bar() { + crate::foo(); + } +} +# fn main() {} +``` + +r[paths.qualifiers.macro-crate] +### `$crate` + +r[paths.qualifiers.macro-crate.allowed-positions] +[`$crate`] is only used within [macro transcribers], and can only be used as the first segment, without a preceding `::`. + +r[paths.qualifiers.macro-crate.hygiene] +[`$crate`] will expand to a path to access items from the top level of the crate where the macro is defined, regardless of which crate the macro is invoked. + +```rust +pub fn increment(x: u32) -> u32 { + x + 1 +} + +#[macro_export] +macro_rules! inc { + ($x:expr) => ( $crate::increment($x) ) +} +# fn main() { } +``` + +r[paths.canonical] +## Canonical paths + +r[paths.canonical.intro] +Each item defined in a module or implementation has a *canonical path* that corresponds to where within its crate it is defined. + +r[paths.canonical.alias] +All other paths to these items are aliases. + +r[paths.canonical.def] +The canonical path is defined as a *path prefix* appended by the path segment the item itself defines. + +r[paths.canonical.non-canonical] +[Implementations] and [use declarations] do not have canonical paths, although the items that implementations define do have them. Items defined in block expressions do not have canonical paths. Items defined in a module that does not have a canonical path do not have a canonical path. Associated items defined in an implementation that refers to an item without a canonical path, e.g. as the implementing type, the trait being implemented, a type parameter or bound on a type parameter, do not have canonical paths. + +r[paths.canonical.module-prefix] +The path prefix for modules is the canonical path to that module. + +r[paths.canonical.bare-impl-prefix] +For bare implementations, it is the canonical path of the item being implemented surrounded by <span class="parenthetical">angle (`<>`)</span> brackets. + +r[paths.canonical.trait-impl-prefix] +For [trait implementations], it is the canonical path of the item being implemented followed by `as` followed by the canonical path to the trait all surrounded in <span class="parenthetical">angle (`<>`)</span> brackets. + +r[paths.canonical.local-canonical-path] +The canonical path is only meaningful within a given crate. There is no global namespace across crates; an item's canonical path merely identifies it within the crate. + +```rust +// Comments show the canonical path of the item. + +mod a { // crate::a + pub struct Struct; // crate::a::Struct + + pub trait Trait { // crate::a::Trait + fn f(&self); // crate::a::Trait::f + } + + impl Trait for Struct { + fn f(&self) {} // <crate::a::Struct as crate::a::Trait>::f + } + + impl Struct { + fn g(&self) {} // <crate::a::Struct>::g + } +} + +mod without { // crate::without + fn canonicals() { // crate::without::canonicals + struct OtherStruct; // None + + trait OtherTrait { // None + fn g(&self); // None + } + + impl OtherTrait for OtherStruct { + fn g(&self) {} // None + } + + impl OtherTrait for crate::a::Struct { + fn g(&self) {} // None + } + + impl crate::a::Trait for OtherStruct { + fn f(&self) {} // None + } + } +} + +# fn main() {} +``` + +[`$crate`]: macro.decl.hygiene.crate +[implementations]: items/implementations.md +[items]: items.md +[literal]: expressions/literal-expr.md +[use declarations]: items/use-declarations.md +[`Self` scope]: names/scopes.md#self-scope +[`use`]: items/use-declarations.md +[attributes]: attributes.md +[const generic argument]: items.generics.const.argument +[enumeration]: items/enumerations.md +[expressions]: expressions.md +[extern prelude]: names/preludes.md#extern-prelude +[implementation]: items/implementations.md +[inferred const]: items.generics.const.inferred +[macro transcribers]: macros-by-example.md +[macros]: macros.md +[mbe]: macros-by-example.md +[module]: items/modules.md +[patterns]: patterns.md +[struct]: items/structs.md +[trait implementations]: items/implementations.md#trait-implementations +[trait]: items/traits.md +[traits]: items/traits.md +[types]: types.md +[union]: items/unions.md +[`use` declarations]: items/use-declarations.md +[value namespace]: names/namespaces.md +[visibility]: visibility-and-privacy.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/patterns.md b/stdlib/kvlang/reference/rust/reference-repo/src/patterns.md new file mode 100644 index 00000000..cff9c0fe --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/patterns.md @@ -0,0 +1,1071 @@ +r[patterns] +# Patterns + +r[patterns.syntax] +```grammar,patterns +Pattern -> `|`? PatternNoTopAlt ( `|` PatternNoTopAlt )* + +PatternNoTopAlt -> + PatternWithoutModernRange + | ModernRangePattern + +PatternWithoutModernRange -> + LiteralPattern + | IdentifierPattern + | WildcardPattern + | RestPattern + | ReferencePattern + | StructPattern + | TupleStructPattern + | TuplePattern + | GroupedPattern + | SlicePattern + | PathPattern + | MacroInvocation + | ObsoleteRangePattern[^obsolete-range-edition] +``` + +[^obsolete-range-edition]: The [ObsoleteRangePattern] syntax is semantically invalid in the 2021 edition and beyond. + +r[patterns.intro] +Patterns are used to match values against structures and to, optionally, bind variables to values inside these structures. They are also used in variable declarations and parameters for functions and closures. + +The pattern in the following example does four things: + +* Tests if `person` has the `car` field filled with something. +* Tests if the person's `age` field is between 13 and 19, and binds its value to the `person_age` variable. +* Binds a reference to the `name` field to the variable `person_name`. +* Ignores the rest of the fields of `person`. The remaining fields can have any value and are not bound to any variables. + +```rust +# struct Car; +# struct Computer; +# struct Person { +# name: String, +# car: Option<Car>, +# computer: Option<Computer>, +# age: u8, +# } +# let person = Person { +# name: String::from("John"), +# car: Some(Car), +# computer: None, +# age: 15, +# }; +if let + Person { + car: Some(_), + age: person_age @ 13..=19, + name: ref person_name, + .. + } = person +{ + println!("{} has a car and is {} years old.", person_name, person_age); +} +``` + +r[patterns.use] +Patterns are used in: + +r[patterns.let] +* [`let` declarations](statements.md#let-statements) + +r[patterns.param] +* [Function](items/functions.md) and [closure](expressions/closure-expr.md) parameters + +r[patterns.match] +* [`match` expressions](expressions/match-expr.md) + +r[patterns.if-let] +* [`if let` expressions](expressions/if-expr.md) + +r[patterns.while-let] +* [`while let` expressions](expressions/loop-expr.md#while-let-patterns) + +r[patterns.for] +* [`for` expressions](expressions/loop-expr.md#iterator-loops) + +r[patterns.destructure] +## Destructuring + +r[patterns.destructure.intro] +Patterns can be used to *destructure* [structs], [enums], and [tuples]. Destructuring breaks up a value into its component pieces. The syntax used is almost the same as when creating such values. + +r[patterns.destructure.wildcard] +In a pattern whose [scrutinee] expression has a `struct`, `enum` or `tuple` type, a [wildcard pattern](#wildcard-pattern) (`_`) stands in for a *single* data field, whereas an [et cetera](#grammar-StructPatternEtCetera) or [rest pattern][patterns.rest] (`..`) stands in for *all* the remaining fields of a particular variant. + +r[patterns.destructure.named-field-shorthand] +When destructuring a data structure with named (but not numbered) fields, it is allowed to write `fieldname` as a shorthand for `fieldname: fieldname`. + +```rust +# enum Message { +# Quit, +# WriteString(String), +# Move { x: i32, y: i32 }, +# ChangeColor(u8, u8, u8), +# } +# let message = Message::Quit; +match message { + Message::Quit => println!("Quit"), + Message::WriteString(write) => println!("{}", &write), + Message::Move{ x, y: 0 } => println!("move {} horizontally", x), + Message::Move{ .. } => println!("other move"), + Message::ChangeColor { 0: red, 1: green, 2: _ } => { + println!("color change, red: {}, green: {}", red, green); + } +}; +``` + +r[patterns.refutable] +## Refutability + +A pattern is said to be *refutable* when it has the possibility of not being matched by the value it is being matched against. *Irrefutable* patterns, on the other hand, always match the value they are being matched against. Examples: + +```rust +let (x, y) = (1, 2); // "(x, y)" is an irrefutable pattern + +if let (a, 3) = (1, 2) { // "(a, 3)" is refutable, and will not match + panic!("Shouldn't reach here"); +} else if let (a, 4) = (3, 4) { // "(a, 4)" is refutable, and will match + println!("Matched ({}, 4)", a); +} +``` + +r[patterns.literal] +## Literal patterns + +r[patterns.literal.syntax] +```grammar,patterns +LiteralPattern -> `-`? LiteralExpression +``` + +r[patterns.literal.intro] +_Literal patterns_ match exactly the same value as what is created by the literal. Since negative numbers are not [literals], literals in patterns may be prefixed by an optional minus sign, which acts like the negation operator. + +> [!WARNING] +> C string and raw C string literals are accepted in literal patterns, but `&CStr` doesn't implement structural equality (`#[derive(Eq, PartialEq)]`) and therefore any such `match` on a `&CStr` will be rejected with a type error. + +r[patterns.literal.refutable] +Literal patterns are always refutable. + +Examples: + +```rust +for i in -2..5 { + match i { + -1 => println!("It's minus one"), + 1 => println!("It's a one"), + 2|4 => println!("It's either a two or a four"), + _ => println!("Matched none of the arms"), + } +} +``` + +r[patterns.ident] +## Identifier patterns + +r[patterns.ident.syntax] +```grammar,patterns +IdentifierPattern -> `ref`? `mut`? IDENTIFIER ( `@` PatternNoTopAlt )? +``` + +r[patterns.ident.intro] +Identifier patterns bind the value they match to a variable in the [value namespace]. + +r[patterns.ident.unique] +The identifier must be unique within the pattern. + +r[patterns.ident.scope] +The variable will shadow any variables of the same name in scope. The [scope] of the new binding depends on the context of where the pattern is used (such as a `let` binding or a `match` arm). + +r[patterns.ident.bare] +Patterns that consist of only an identifier, possibly with a `mut`, match any value and bind it to that identifier. This is the most commonly used pattern in variable declarations and parameters for functions and closures. + +```rust +let mut variable = 10; +fn sum(x: i32, y: i32) -> i32 { +# x + y +# } +``` + +r[patterns.ident.scrutinized] +To bind the matched value of a pattern to a variable, use the syntax `variable @ subpattern`. For example, the following binds the value 2 to `e` (not the entire range: the range here is a range subpattern). + +```rust +let x = 2; + +match x { + e @ 1 ..= 5 => println!("got a range element {}", e), + _ => println!("anything"), +} +``` + +r[patterns.ident.move] +By default, identifier patterns bind a variable to a copy of or move from the matched value depending on whether the matched value implements [`Copy`]. + +r[patterns.ident.ref] +This can be changed to bind to a reference by using the `ref` keyword, or to a mutable reference using `ref mut`. For example: + +```rust +# let a = Some(10); +match a { + None => (), + Some(value) => (), +} + +match a { + None => (), + Some(ref value) => (), +} +``` + +In the first match expression, the value is copied (or moved). In the second match, a reference to the same memory location is bound to the variable value. This syntax is needed because in destructuring subpatterns the `&` operator can't be applied to the value's fields. For example, the following is not valid: + +```rust,compile_fail +# struct Person { +# name: String, +# age: u8, +# } +# let value = Person { name: String::from("John"), age: 23 }; +if let Person { name: &person_name, age: 18..=150 } = value { } +``` + +To make it valid, write the following: + +```rust +# struct Person { +# name: String, +# age: u8, +# } +# let value = Person { name: String::from("John"), age: 23 }; +if let Person { name: ref person_name, age: 18..=150 } = value { } +``` + +r[patterns.ident.ref-ignored] +Thus, `ref` is not something that is being matched against. Its objective is exclusively to make the matched binding a reference, instead of potentially copying or moving what was matched. + +r[patterns.ident.precedent] +[Path patterns](#path-patterns) take precedence over identifier patterns. + +> [!NOTE] +> When a pattern is a single-segment identifier, the grammar is ambiguous whether it means an [IdentifierPattern] or a [PathPattern]. This ambiguity can only be resolved after [name resolution]. +> +> ```rust +> const EXPECTED_VALUE: u8 = 42; +> // ^^^^^^^^^^^^^^ That this constant is in scope affects how the +> // patterns below are treated. +> +> fn check_value(x: u8) -> Result<u8, u8> { +> match x { +> EXPECTED_VALUE => Ok(x), +> // ^^^^^^^^^^^^^^ Parsed as a `PathPattern` that resolves to +> // the constant `42`. +> other_value => Err(x), +> // ^^^^^^^^^^^ Parsed as an `IdentifierPattern`. +> } +> } +> +> // If `EXPECTED_VALUE` were treated as an `IdentifierPattern` above, +> // that pattern would always match, making the function always return +> // `Ok(_) regardless of the input. +> assert_eq!(check_value(42), Ok(42)); +> assert_eq!(check_value(43), Err(43)); +> ``` + +r[patterns.ident.constraint] +It is an error if `ref` or `ref mut` is specified and the identifier shadows a constant. + +r[patterns.ident.refutable] +Identifier patterns are irrefutable if the `@` subpattern is irrefutable or the subpattern is not specified. + +r[patterns.ident.binding] +### Binding modes + +r[patterns.ident.binding.intro] +To service better ergonomics, patterns operate in different *binding modes* in order to make it easier to bind references to values. When a reference value is matched by a non-reference pattern, it will be automatically treated as a `ref` or `ref mut` binding. Example: + +```rust +let x: &Option<i32> = &Some(3); +if let Some(y) = x { + // y was converted to `ref y` and its type is &i32 +} +``` + +r[patterns.ident.binding.non-reference] +*Non-reference patterns* include all patterns except bindings, [wildcard patterns](#wildcard-pattern) (`_`), [`const` patterns](#constant-patterns) of reference types, and [reference patterns](#reference-patterns). + +r[patterns.ident.binding.default-mode] +If a binding pattern does not explicitly have `ref`, `ref mut`, or `mut`, then it uses the *default binding mode* to determine how the variable is bound. + +r[patterns.ident.binding.move] +The default binding mode starts in "move" mode which uses move semantics. + +r[patterns.ident.binding.top-down] +When matching a pattern, the compiler starts from the outside of the pattern and works inwards. + +r[patterns.ident.binding.auto-deref] +Each time a reference is matched using a non-reference pattern, it will automatically dereference the value and update the default binding mode. + +r[patterns.ident.binding.ref] +References will set the default binding mode to `ref`. + +r[patterns.ident.binding.ref-mut] +Mutable references will set the mode to `ref mut` unless the mode is already `ref` in which case it remains `ref`. + +r[patterns.ident.binding.nested-references] +If the automatically dereferenced value is still a reference, it is dereferenced and this process repeats. + +r[patterns.ident.binding.mode-limitations-binding] +The binding pattern may only explicitly specify a `ref` or `ref mut` binding mode, or specify mutability with `mut`, when the default binding mode is "move". For example, these are not accepted: + +```rust,edition2024,compile_fail +let [mut x] = &[()]; //~ ERROR +let [ref x] = &[()]; //~ ERROR +let [ref mut x] = &mut [()]; //~ ERROR +``` + +r[patterns.ident.binding.mode-limitations-binding-edition2024] +> [!EDITION-2024] +> Before the 2024 edition, bindings could explicitly specify a `ref` or `ref mut` binding mode even when the default binding mode was not "move", and they could specify mutability on such bindings with `mut`. In these editions, specifying `mut` on a binding set the binding mode to "move" regardless of the current default binding mode. + +r[patterns.ident.binding.mode-limitations-reference] +Similarly, a reference pattern may only appear when the default binding mode is "move". For example, this is not accepted: + +```rust,edition2024,compile_fail +let [&x] = &[&()]; //~ ERROR +``` + +r[patterns.ident.binding.mode-limitations-reference-edition2024] +> [!EDITION-2024] +> Before the 2024 edition, reference patterns could appear even when the default binding mode was not "move", and had both the effect of matching against the scrutinee and of causing the default binding mode to be reset to "move". + +r[patterns.ident.binding.mixed] +Move bindings and reference bindings can be mixed together in the same pattern. Doing so will result in partial move of the object bound to and the object cannot be used afterwards. This applies only if the type cannot be copied. + +In the example below, `name` is moved out of `person`. Trying to use `person` as a whole or `person.name` would result in an error because of *partial move*. + +Example: + +```rust +# struct Person { +# name: String, +# age: u8, +# } +# let person = Person{ name: String::from("John"), age: 23 }; +// `name` is moved from person and `age` referenced +let Person { name, ref age } = person; +``` + +r[patterns.wildcard] +## Wildcard pattern + +r[patterns.wildcard.syntax] +```grammar,patterns +WildcardPattern -> `_` +``` + +r[patterns.wildcard.intro] +The _wildcard pattern_ (an underscore symbol) matches any value. It is used to ignore values when they don't matter. + +r[patterns.wildcard.struct-matcher] +Inside other patterns, it matches a single data field (as opposed to the `..`, which matches the remaining fields). + +r[patterns.wildcard.no-binding] +Unlike identifier patterns, it does not copy, move, or borrow the value it matches. + +Examples: + +```rust +# let x = 20; +let (a, _) = (10, x); // the x is always matched by _ +# assert_eq!(a, 10); + +// ignore a function/closure param +let real_part = |a: f64, _: f64| { a }; + +// ignore a field from a struct +# struct RGBA { +# r: f32, +# g: f32, +# b: f32, +# a: f32, +# } +# let color = RGBA{r: 0.4, g: 0.1, b: 0.9, a: 0.5}; +let RGBA{r: red, g: green, b: blue, a: _} = color; +# assert_eq!(color.r, red); +# assert_eq!(color.g, green); +# assert_eq!(color.b, blue); + +// accept any Some, with any value +# let x = Some(10); +if let Some(_) = x {} +``` + +r[patterns.wildcard.refutable] +The wildcard pattern is always irrefutable. + +r[patterns.rest] +## Rest pattern + +r[patterns.rest.syntax] +```grammar,patterns +RestPattern -> `..` +``` + +r[patterns.rest.intro] +The _rest pattern_ (the `..` token) acts as a variable-length pattern which matches zero or more elements that haven't been matched already before and after. + +r[patterns.rest.allowed-patterns] +It may only be used in [tuple](#tuple-patterns), [tuple struct](#tuple-struct-patterns), and [slice](#slice-patterns) patterns, and may only appear once as one of the elements in those patterns. It is also allowed in an [identifier pattern](#identifier-patterns) for [slice patterns](#slice-patterns) only. + +r[patterns.rest.refutable] +The rest pattern is always irrefutable. + +Examples: + +```rust +# let words = vec!["a", "b", "c"]; +# let slice = &words[..]; +match slice { + [] => println!("slice is empty"), + [one] => println!("single element {}", one), + [head, tail @ ..] => println!("head={} tail={:?}", head, tail), +} + +match slice { + // Ignore everything but the last element, which must be "!". + [.., "!"] => println!("!!!"), + + // `start` is a slice of everything except the last element, which must be "z". + [start @ .., "z"] => println!("starts with: {:?}", start), + + // `end` is a slice of everything but the first element, which must be "a". + ["a", end @ ..] => println!("ends with: {:?}", end), + + // 'whole' is the entire slice and `last` is the final element + whole @ [.., last] => println!("the last element of {:?} is {}", whole, last), + + rest => println!("{:?}", rest), +} + +if let [.., penultimate, _] = slice { + println!("next to last is {}", penultimate); +} + +# let tuple = (1, 2, 3, 4, 5); +// The rest pattern may also be used in tuple and tuple +// struct patterns. +match tuple { + (1, .., y, z) => println!("y={} z={}", y, z), + (.., 5) => println!("tail must be 5"), + (..) => println!("matches everything else"), +} +``` + +r[patterns.range] +## Range patterns + +r[patterns.range.syntax] +```grammar,patterns +ModernRangePattern -> + RangeExclusivePattern + | RangeInclusivePattern + | RangeFromPattern + | RangeToExclusivePattern + | RangeToInclusivePattern + +RangeExclusivePattern -> + RangePatternBound `..` RangePatternBound + +RangeInclusivePattern -> + RangePatternBound `..=` RangePatternBound + +RangeFromPattern -> + RangePatternBound `..` + +RangeToExclusivePattern -> + `..` RangePatternBound + +RangeToInclusivePattern -> + `..=` RangePatternBound + +ObsoleteRangePattern -> + RangePatternBound `...` RangePatternBound + +RangePatternBound -> + LiteralPattern + | PathExpression +``` + +r[patterns.range.intro] +*Range patterns* match scalar values within the range defined by their bounds. They comprise a *sigil* (`..` or `..=`) and a bound on one or both sides. + +A bound on the left of the sigil is called a *lower bound*. A bound on the right is called an *upper bound*. + +r[patterns.range.exclusive] +The *exclusive range pattern* matches all values from the lower bound up to, but not including the upper bound. It is written as its lower bound, followed by `..`, followed by the upper bound. + +For example, a pattern `'m'..'p'` will match only `'m'`, `'n'` and `'o'`, specifically **not** including `'p'`. + +r[patterns.range.inclusive] +The *inclusive range pattern* matches all values from the lower bound up to and including the upper bound. It is written as its lower bound, followed by `..=`, followed by the upper bound. + +For example, a pattern `'m'..='p'` will match only the values `'m'`, `'n'`, `'o'`, and `'p'`. + +r[patterns.range.from] +The *from range pattern* matches all values greater than or equal to the lower bound. It is written as its lower bound followed by `..`. + +For example, `1..` will match any integer greater than or equal to 1, such as 1, 9, or 9001, or 9007199254740991 (if it is of an appropriate size), but not 0, and not negative numbers for signed integers. + +r[patterns.range.to-exclusive] +The *to exclusive range pattern* matches all values less than the upper bound. It is written as `..` followed by the upper bound. + +For example, `..10` will match any integer less than 10, such as 9, 1, 0, and for signed integer types, all negative values. + +r[patterns.range.to-inclusive] +The *to inclusive range pattern* matches all values less than or equal to the upper bound. It is written as `..=` followed by the upper bound. + +For example, `..=10` will match any integer less than or equal to 10, such as 10, 1, 0, and for signed integer types, all negative values. + +r[patterns.range.constraint-nonempty] +A range pattern must be nonempty; it must span at least one value in the set of possible values for its type. In other words: + +* In `a..=b`, a ≤ b must be the case. For example, it is an error to have a range pattern `10..=0`, but `10..=10` is allowed. +* In `a..b`, a < b must be the case. For example, it is an error to have a range pattern `10..0` or `10..10`. +* In `..b`, b must not be the smallest value of its type. For example, it is an error to have a range pattern `..-128i8` or `..f64::NEG_INFINITY`. + +r[patterns.range.bound] +A bound is written as one of: + +* A character, byte, integer, or float literal. +* A `-` followed by an integer or float literal. +* A [path]. + +> [!NOTE] +> +> We syntactically accept more than this for a *[RangePatternBound]*. We later reject the other things semantically. + +r[patterns.range.constraint-bound-path] +If a bound is written as a path, after macro resolution, the path must resolve to a constant item of the type `char`, an integer type, or a float type. + +r[patterns.range.type] +The range pattern matches the type of its upper and lower bounds, which must be the same type. + +r[patterns.range.path-value] +If a bound is a [path], the bound matches the type and has the value of the [constant] the path resolves to. + +r[patterns.range.literal-value] +If a bound is a literal, the bound matches the type and has the value of the corresponding [literal expression]. + +r[patterns.range.negation] +If a bound is a literal preceded by a `-`, the bound matches the same type as the corresponding [literal expression] and has the value of [negating] the value of the corresponding literal expression. + +r[patterns.range.float-restriction] +For float range patterns, the constant may not be a `NaN`. + +Examples: + +```rust +# let c = 'f'; +let valid_variable = match c { + 'a'..='z' => true, + 'A'..='Z' => true, + 'α'..='ω' => true, + _ => false, +}; + +# let ph = 10; +println!("{}", match ph { + 0..7 => "acid", + 7 => "neutral", + 8..=14 => "base", + _ => unreachable!(), +}); + +# let uint: u32 = 5; +match uint { + 0 => "zero!", + 1.. => "positive number!", +}; + +// using paths to constants: +# const TROPOSPHERE_MIN : u8 = 6; +# const TROPOSPHERE_MAX : u8 = 20; +# +# const STRATOSPHERE_MIN : u8 = TROPOSPHERE_MAX + 1; +# const STRATOSPHERE_MAX : u8 = 50; +# +# const MESOSPHERE_MIN : u8 = STRATOSPHERE_MAX + 1; +# const MESOSPHERE_MAX : u8 = 85; +# +# let altitude = 70; +# +println!("{}", match altitude { + TROPOSPHERE_MIN..=TROPOSPHERE_MAX => "troposphere", + STRATOSPHERE_MIN..=STRATOSPHERE_MAX => "stratosphere", + MESOSPHERE_MIN..=MESOSPHERE_MAX => "mesosphere", + _ => "outer space, maybe", +}); + +# pub mod binary { +# pub const MEGA : u64 = 1024*1024; +# pub const GIGA : u64 = 1024*1024*1024; +# } +# let n_items = 20_832_425; +# let bytes_per_item = 12; +if let size @ binary::MEGA..=binary::GIGA = n_items * bytes_per_item { + println!("It fits and occupies {} bytes", size); +} + +# trait MaxValue { +# const MAX: u64; +# } +# impl MaxValue for u8 { +# const MAX: u64 = (1 << 8) - 1; +# } +# impl MaxValue for u16 { +# const MAX: u64 = (1 << 16) - 1; +# } +# impl MaxValue for u32 { +# const MAX: u64 = (1 << 32) - 1; +# } +// using qualified paths: +println!("{}", match 0xfacade { + 0 ..= <u8 as MaxValue>::MAX => "fits in a u8", + 0 ..= <u16 as MaxValue>::MAX => "fits in a u16", + 0 ..= <u32 as MaxValue>::MAX => "fits in a u32", + _ => "too big", +}); +``` + +r[patterns.range.refutable] +Range patterns for fix-width integer and `char` types are irrefutable when they span the entire set of possible values of a type. For example, `0u8..=255u8` is irrefutable. + +r[patterns.range.refutable-integer] +The range of values for an integer type is the closed range from its minimum to maximum value. + +r[patterns.range.refutable-char] +The range of values for a `char` type are precisely those ranges containing all Unicode Scalar Values: `'\u{0000}'..='\u{D7FF}'` and `'\u{E000}'..='\u{10FFFF}'`. + +r[patterns.range.constraint-slice] +[RangeFromPattern] cannot be used as a top-level pattern for subpatterns in [slice patterns](#slice-patterns). For example, the pattern `[1.., _]` is not a valid pattern. + +r[patterns.range.edition2021] +> [!EDITION-2021] +> Before the 2021 edition, range patterns with both a lower and upper bound may also be written using `...` in place of `..=`, with the same meaning. + +r[patterns.ref] +## Reference patterns + +r[patterns.ref.syntax] +```grammar,patterns +ReferencePattern -> (`&`|`&&`) `mut`? PatternWithoutModernRange +``` + +r[patterns.ref.intro] +Reference patterns dereference the pointers that are being matched and, thus, borrow them. + +For example, these two matches on `x: &i32` are equivalent: + +```rust +let int_reference = &3; + +let a = match *int_reference { 0 => "zero", _ => "some" }; +let b = match int_reference { &0 => "zero", _ => "some" }; + +assert_eq!(a, b); +``` + +r[patterns.ref.ref-ref] +The grammar production for reference patterns has to match the token `&&` to match a reference to a reference because it is a token by itself, not two `&` tokens. + +r[patterns.ref.mut] +Adding the `mut` keyword dereferences a mutable reference. The mutability must match the mutability of the reference. + +r[patterns.ref.refutable] +Reference patterns are always irrefutable. + +r[patterns.struct] +## Struct patterns + +r[patterns.struct.syntax] +```grammar,patterns +StructPattern -> + PathInExpression `{` + StructPatternElements? + `}` + +StructPatternElements -> + StructPatternFields (`,` | `,` StructPatternEtCetera)? + | StructPatternEtCetera + +StructPatternFields -> + StructPatternField (`,` StructPatternField)* + +StructPatternField -> + OuterAttribute* + ( + TUPLE_INDEX `:` Pattern + | IDENTIFIER `:` Pattern + | `ref`? `mut`? IDENTIFIER + ) + +StructPatternEtCetera -> `..` +``` + +r[patterns.struct.intro] +Struct patterns match struct, enum, and union values that match all criteria defined by its subpatterns. They are also used to [destructure](#destructuring) a struct, enum, or union value. + +r[patterns.struct.ignore-rest] +On a struct pattern, the fields are referenced by name, index (in the case of tuple structs) or ignored by use of `..`: + +```rust +# struct Point { +# x: u32, +# y: u32, +# } +# let s = Point {x: 1, y: 1}; +# +match s { + Point {x: 10, y: 20} => (), + Point {y: 10, x: 20} => (), // order doesn't matter + Point {x: 10, ..} => (), + Point {..} => (), +} + +# struct PointTuple ( +# u32, +# u32, +# ); +# let t = PointTuple(1, 2); +# +match t { + PointTuple {0: 10, 1: 20} => (), + PointTuple {1: 10, 0: 20} => (), // order doesn't matter + PointTuple {0: 10, ..} => (), + PointTuple {..} => (), +} + +# enum Message { +# Quit, +# Move { x: i32, y: i32 }, +# } +# let m = Message::Quit; +# +match m { + Message::Quit => (), + Message::Move {x: 10, y: 20} => (), + Message::Move {..} => (), +} +``` + +r[patterns.struct.constraint-struct] +If `..` is not used, a struct pattern used to match a struct is required to specify all fields: + +```rust +# struct Struct { +# a: i32, +# b: char, +# c: bool, +# } +# let mut struct_value = Struct{a: 10, b: 'X', c: false}; +# +match struct_value { + Struct{a: 10, b: 'X', c: false} => (), + Struct{a: 10, b: 'X', ref c} => (), + Struct{a: 10, b: 'X', ref mut c} => (), + Struct{a: 10, b: 'X', c: _} => (), + Struct{a: _, b: _, c: _} => (), +} +``` + +r[patterns.struct.constraint-union] +A struct pattern used to match a union must specify exactly one field (see [Pattern matching on unions]). + +r[patterns.struct.binding-shorthand] +The [IDENTIFIER] syntax matches any value and binds it to a variable with the same name as the given field. It is a shorthand for `fieldname: fieldname`. The `ref` and `mut` qualifiers can be included with the behavior as described in [patterns.ident.ref]. + +```rust +# struct Struct { +# a: i32, +# b: char, +# c: bool, +# } +# let struct_value = Struct{a: 10, b: 'X', c: false}; +# +let Struct { a, b, c } = struct_value; +``` + +r[patterns.struct.refutable] +A struct pattern is refutable if the [PathInExpression] resolves to a constructor of an enum with more than one variant, or one of its subpatterns is refutable. + +r[patterns.struct.namespace] +A struct pattern matches against the struct, union, or enum variant whose constructor is resolved from [PathInExpression] in the [type namespace]. See [patterns.tuple-struct.namespace] for more details. + +r[patterns.tuple-struct] +## Tuple struct patterns + +r[patterns.tuple-struct.syntax] +```grammar,patterns +TupleStructPattern -> PathInExpression `(` TupleStructItems? `)` + +TupleStructItems -> Pattern ( `,` Pattern )* `,`? +``` + +r[patterns.tuple-struct.intro] +Tuple struct patterns match tuple struct and enum values that match all criteria defined by its subpatterns. They are also used to [destructure](#destructuring) a tuple struct or enum value. + +r[patterns.tuple-struct.refutable] +A tuple struct pattern is refutable if the [PathInExpression] resolves to a constructor of an enum with more than one variant, or one of its subpatterns is refutable. + +r[patterns.tuple-struct.namespace] +A tuple struct pattern matches against the tuple struct or [tuple-like enum variant] whose constructor is resolved from [PathInExpression] in the [value namespace]. + +> [!NOTE] +> Conversely, a struct pattern for a tuple struct or [tuple-like enum variant], e.g. `S { 0: _ }`, matches against the tuple struct or variant whose constructor is resolved in the [type namespace]. +> +> ```rust,no_run +> enum E1 { V(u16) } +> enum E2 { V(u32) } +> +> // Import `E1::V` from the type namespace only. +> mod _0 { +> const V: () = (); // For namespace masking. +> pub(super) use super::E1::*; +> } +> use _0::*; +> +> // Import `E2::V` from the value namespace only. +> mod _1 { +> struct V {} // For namespace masking. +> pub(super) use super::E2::*; +> } +> use _1::*; +> +> fn f() { +> // This struct pattern matches against the tuple-like +> // enum variant whose constructor was found in the type +> // namespace. +> let V { 0: ..=u16::MAX } = (loop {}) else { loop {} }; +> // This tuple struct pattern matches against the tuple-like +> // enum variant whose constructor was found in the value +> // namespace. +> let V(..=u32::MAX) = (loop {}) else { loop {} }; +> } +> # // Required due to the odd behavior of `super` within functions. +> # fn main() {} +> ``` +> +> The Lang team has made certain decisions, such as in [PR #138458], that raise questions about the desirability of using the value namespace in this way for patterns, as described in [PR #140593]. It might be prudent to not intentionally rely on this nuance in your code. + +r[patterns.tuple] +## Tuple patterns + +r[patterns.tuple.syntax] +```grammar,patterns +TuplePattern -> `(` TuplePatternItems? `)` + +TuplePatternItems -> + Pattern `,` + | RestPattern + | Pattern (`,` Pattern)+ `,`? +``` + +r[patterns.tuple.intro] +Tuple patterns match tuple values that match all criteria defined by its subpatterns. They are also used to [destructure](#destructuring) a tuple. + +r[patterns.tuple.rest-syntax] +The form `(..)` with a single [RestPattern] is a special form that does not require a comma, and matches a tuple of any size. + +r[patterns.tuple.refutable] +The tuple pattern is refutable when one of its subpatterns is refutable. + +An example of using tuple patterns: + +```rust +let pair = (10, "ten"); +let (a, b) = pair; + +assert_eq!(a, 10); +assert_eq!(b, "ten"); +``` + +r[patterns.paren] +## Grouped patterns + +r[patterns.paren.syntax] +```grammar,patterns +GroupedPattern -> `(` Pattern `)` +``` + +r[patterns.paren.intro] +Enclosing a pattern in parentheses can be used to explicitly control the precedence of compound patterns. For example, a reference pattern next to a range pattern such as `&0..=5` is ambiguous and is not allowed, but can be expressed with parentheses. + +```rust +let int_reference = &3; +match int_reference { + &(0..=5) => (), + _ => (), +} +``` + +r[patterns.slice] +## Slice patterns + +r[patterns.slice.syntax] +```grammar,patterns +SlicePattern -> `[` SlicePatternItems? `]` + +SlicePatternItems -> Pattern (`,` Pattern)* `,`? +``` + +r[patterns.slice.intro] +Slice patterns can match both arrays of fixed size and slices of dynamic size. + +```rust +// Fixed size +let arr = [1, 2, 3]; +match arr { + [1, _, _] => "starts with one", + [a, b, c] => "starts with something else", +}; +``` +```rust +// Dynamic size +let v = vec![1, 2, 3]; +match v[..] { + [a, b] => { /* this arm will not apply because the length doesn't match */ } + [a, b, c] => { /* this arm will apply */ } + _ => { /* this wildcard is required, since the length is not known statically */ } +}; +``` + +r[patterns.slice.refutable-array] +Slice patterns are irrefutable when matching an array as long as each element is irrefutable. + +r[patterns.slice.refutable-slice] +When matching a slice, it is irrefutable only in the form with a single `..` [rest pattern][patterns.rest] or [identifier pattern](#identifier-patterns) with the `..` rest pattern as a subpattern. + +r[patterns.slice.restriction] +Within a slice, a range pattern without both lower and upper bound must be enclosed in parentheses, as in `(a..)`, to clarify it is intended to match against a single slice element. A range pattern with both lower and upper bound, like `a..=b`, is not required to be enclosed in parentheses. + +r[patterns.path] +## Path patterns + +r[patterns.path.syntax] +```grammar,patterns +PathPattern -> PathExpression +``` + +r[patterns.path.intro] +_Path patterns_ are patterns that refer either to constant values or to structs or enum variants that have no fields. + +r[patterns.path.unqualified] +Unqualified path patterns can refer to: + +* enum variants +* structs +* constants +* associated constants + +r[patterns.path.qualified] +Qualified path patterns can only refer to associated constants. + +r[patterns.path.refutable] +Path patterns are irrefutable when they refer to structs or an enum variant when the enum has only one variant or a constant whose type is irrefutable. They are refutable when they refer to refutable constants or enum variants for enums with multiple variants. + +r[patterns.const] +### Constant patterns + +r[patterns.const.partial-eq] +When a constant `C` of type `T` is used as a pattern, we first check that `T: PartialEq`. + +r[patterns.const.structural-equality] +Furthermore we require that the value of `C` *has (recursive) structural equality*, which is defined recursively as follows: + +r[patterns.const.primitive] +- Integers as well as `str`, `bool` and `char` values always have structural equality. + +r[patterns.const.builtin-aggregate] +- Tuples, arrays, and slices have structural equality if all their fields/elements have structural equality. (In particular, `()` and `[]` always have structural equality.) + +r[patterns.const.ref] +- References have structural equality if the value they point to has structural equality. + +r[patterns.const.aggregate] +- A value of `struct` or `enum` type has structural equality if its `PartialEq` instance is derived via `#[derive(PartialEq)]`, and all fields (for enums: of the active variant) have structural equality. + +r[patterns.const.pointer] +- A raw pointer has structural equality if it was defined as a constant integer (and then cast/transmuted). + +r[patterns.const.float] +- A float value has structural equality if it is not a `NaN`. + +r[patterns.const.exhaustive] +- Nothing else has structural equality. + +r[patterns.const.generic] +In particular, the value of `C` must be known at pattern-building time (which is pre-monomorphization). This means that associated consts that involve generic parameters cannot be used as patterns. + +r[patterns.const.immutable] +The value of `C` must not contain any references to mutable statics (`static mut` items or interior mutable `static` items) or `extern` statics. + +r[patterns.const.translation] +After ensuring all conditions are met, the constant value is translated into a pattern, and now behaves exactly as-if that pattern had been written directly. In particular, it fully participates in exhaustiveness checking. (For raw pointers, constants are the only way to write such patterns. Only `_` is ever considered exhaustive for these types.) + +r[patterns.or] +## Or-patterns + +_Or-patterns_ are patterns that match on one of two or more sub-patterns (for example `A | B | C`). They can nest arbitrarily. Syntactically, or-patterns are allowed in any of the places where other patterns are allowed (represented by the [Pattern] production), with the exceptions of `let`-bindings and function and closure parameters (represented by the [PatternNoTopAlt] production). + +r[patterns.constraints] +### Static semantics + +r[patterns.constraints.pattern] +1. Given a pattern `p | q` at some depth for some arbitrary patterns `p` and `q`, the pattern is considered ill-formed if: + + + the type inferred for `p` does not unify with the type inferred for `q`, or + + the same set of bindings are not introduced in `p` and `q`, or + + the type of any two bindings with the same name in `p` and `q` do not unify with respect to types or binding modes. + + Unification of types is in all instances aforementioned exact and implicit [type coercions] do not apply. + +r[patterns.constraints.match-type-check] +2. When type checking an expression `match e_s { a_1 => e_1, ... a_n => e_n }`, for each match arm `a_i` which contains a pattern of form `p_i | q_i`, the pattern `p_i | q_i` is considered ill formed if, at the depth `d` where it exists the fragment of `e_s` at depth `d`, the type of the expression fragment does not unify with `p_i | q_i`. + +r[patterns.constraints.exhaustiveness-or-pattern] +3. With respect to exhaustiveness checking, a pattern `p | q` is considered to cover `p` as well as `q`. For some constructor `c(x, ..)` the distributive law applies such that `c(p | q, ..rest)` covers the same set of value as `c(p, ..rest) | c(q, ..rest)` does. This can be applied recursively until there are no more nested patterns of form `p | q` other than those that exist at the top level. + + Note that by *"constructor"* we do not refer to tuple struct patterns, but rather we refer to a pattern for any product type. This includes enum variants, tuple structs, structs with named fields, arrays, tuples, and slices. + +r[patterns.behavior] +### Dynamic semantics + +r[patterns.behavior.nested-or-patterns] +1. The dynamic semantics of pattern matching a scrutinee expression `e_s` against a pattern `c(p | q, ..rest)` at depth `d` where `c` is some constructor, `p` and `q` are arbitrary patterns, and `rest` is optionally any remaining potential factors in `c`, is defined as being the same as that of `c(p, ..rest) | c(q, ..rest)`. + +r[patterns.precedence] +### Precedence with other undelimited patterns + +As shown elsewhere in this chapter, there are several types of patterns that are syntactically undelimited, including identifier patterns, reference patterns, and or-patterns. Or-patterns always have the lowest-precedence. This allows us to reserve syntactic space for a possible future type ascription feature and also to reduce ambiguity. For example, `x @ A(..) | B(..)` will result in an error that `x` is not bound in all patterns. `&A(x) | B(x)` will result in a type mismatch between `x` in the different subpatterns. + +[PR #138458]: https://github.com/rust-lang/rust/pull/138458 +[PR #140593]: https://github.com/rust-lang/rust/pull/140593#issuecomment-2972338457 +[`Copy`]: special-types-and-traits.md#copy +[constant]: items/constant-items.md +[enums]: items/enumerations.md +[literals]: expressions/literal-expr.md +[literal expression]: expressions/literal-expr.md +[name resolution]: names/name-resolution.md +[negating]: expressions/operator-expr.md#negation-operators +[path]: expressions/path-expr.md +[pattern matching on unions]: items/unions.md#pattern-matching-on-unions +[range expressions]: expressions/range-expr.md +[scope]: names/scopes.md +[structs]: items/structs.md +[tuples]: types/tuple.md +[scrutinee]: glossary.md#scrutinee +[tuple-like enum variant]: items.enum.tuple-expr +[type coercions]: type-coercions.md +[type namespace]: names.namespaces.kinds +[value namespace]: names.namespaces.kinds diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/procedural-macros.md b/stdlib/kvlang/reference/rust/reference-repo/src/procedural-macros.md new file mode 100644 index 00000000..18826351 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/procedural-macros.md @@ -0,0 +1,416 @@ +r[macro.proc] +# Procedural macros + +r[macro.proc.intro] +*Procedural macros* allow creating syntax extensions as execution of a function. Procedural macros come in one of three flavors: + +* [Function-like macros] - `custom!(...)` +* [Derive macros] - `#[derive(CustomDerive)]` +* [Attribute macros] - `#[CustomAttribute]` + +Procedural macros allow you to run code at compile time that operates over Rust syntax, both consuming and producing Rust syntax. You can sort of think of procedural macros as functions from an AST to another AST. + +r[macro.proc.def] +Procedural macros must be defined in the root of a crate with the [crate type] of `proc-macro`. The macros may not be used from the crate where they are defined, and can only be used when imported in another crate. + +> [!NOTE] +> When using Cargo, Procedural macro crates are defined with the `proc-macro` key in your manifest: +> +> ```toml +> [lib] +> proc-macro = true +> ``` + +r[macro.proc.result] +As functions, they must either return syntax, panic, or loop endlessly. Returned syntax either replaces or adds the syntax depending on the kind of procedural macro. Panics are caught by the compiler and are turned into a compiler error. Endless loops are not caught by the compiler which hangs the compiler. + +Procedural macros run during compilation, and thus have the same resources that the compiler has. For example, standard input, error, and output are the same that the compiler has access to. Similarly, file access is the same. Because of this, procedural macros have the same security concerns that [Cargo's build scripts] have. + +r[macro.proc.error] +Procedural macros have two ways of reporting errors. The first is to panic. The second is to emit a [`compile_error`] macro invocation. + +r[macro.proc.proc_macro-crate] +## The `proc_macro` crate + +r[macro.proc.proc_macro-crate.intro] +Procedural macro crates almost always will link to the compiler-provided [`proc_macro` crate]. The `proc_macro` crate provides types required for writing procedural macros and facilities to make it easier. + +r[macro.proc.proc_macro-crate.token-stream] +This crate primarily contains a [`TokenStream`] type. Procedural macros operate over *token streams* instead of AST nodes, which is a far more stable interface over time for both the compiler and for procedural macros to target. A *token stream* is roughly equivalent to `Vec<TokenTree>` where a `TokenTree` can roughly be thought of as lexical token. For example `foo` is an `Ident` token, `.` is a `Punct` token, and `1.2` is a `Literal` token. The `TokenStream` type, unlike `Vec<TokenTree>`, is cheap to clone. + +r[macro.proc.proc_macro-crate.span] +All tokens have an associated `Span`. A `Span` is an opaque value that cannot be modified but can be manufactured. `Span`s represent an extent of source code within a program and are primarily used for error reporting. While you cannot modify a `Span` itself, you can always change the `Span` *associated* with any token, such as through getting a `Span` from another token. + +r[macro.proc.hygiene] +## Procedural macro hygiene + +Procedural macros are *unhygienic*. This means they behave as if the output token stream was simply written inline to the code it's next to. This means that it's affected by external items and also affects external imports. + +Macro authors need to be careful to ensure their macros work in as many contexts as possible given this limitation. This often includes using absolute paths to items in libraries (for example, `::std::option::Option` instead of `Option`) or by ensuring that generated functions have names that are unlikely to clash with other functions (like `__internal_foo` instead of `foo`). + +<!-- TODO: rule name needs improvement --> +<!-- template:attributes --> +r[macro.proc.proc_macro] +## The `proc_macro` attribute + +r[macro.proc.proc_macro.intro] +The *`proc_macro` [attribute][attributes]* defines a [function-like][macro.invocation] procedural macro. + +> [!EXAMPLE] +> This macro definition ignores its input and emits a function `answer` into its scope. +> +> <!-- ignore: test doesn't support proc-macro --> +> ```rust,ignore +> # #![crate_type = "proc-macro"] +> extern crate proc_macro; +> use proc_macro::TokenStream; +> +> #[proc_macro] +> pub fn make_answer(_item: TokenStream) -> TokenStream { +> "fn answer() -> u32 { 42 }".parse().unwrap() +> } +> ``` +> +> We can use it in a binary crate to print "42" to standard output. +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> extern crate proc_macro_examples; +> use proc_macro_examples::make_answer; +> +> make_answer!(); +> +> fn main() { +> println!("{}", answer()); +> } +> ``` + +r[macro.proc.proc_macro.syntax] +The `proc_macro` attribute uses the [MetaWord] syntax. + +r[macro.proc.proc_macro.allowed-positions] +The `proc_macro` attribute may only be applied to a `pub` function of type `fn(TokenStream) -> TokenStream` where [`TokenStream`] comes from the [`proc_macro` crate]. It must have the ["Rust" ABI][items.fn.extern]. No other function qualifiers are allowed. It must be located in the root of the crate. + +r[macro.proc.proc_macro.duplicates] +The `proc_macro` attribute may only be specified once on a function. + +r[macro.proc.proc_macro.namespace] +The `proc_macro` attribute publicly defines the macro in the [macro namespace] in the root of the crate with the same name as the function. + +r[macro.proc.proc_macro.behavior] +A function-like macro invocation of a function-like procedural macro will pass what is inside the delimiters of the macro invocation as the input [`TokenStream`] argument and replace the entire macro invocation with the output [`TokenStream`] of the function. + +r[macro.proc.proc_macro.invocation] +Function-like procedural macros may be invoked in any macro invocation position, which includes: + +- [Statements] +- [Expressions] +- [Patterns] +- [Type expressions] +- [Item] positions, including items in [`extern` blocks] +- Inherent and trait [implementations] +- [Trait definitions] + +<!-- template:attributes --> +r[macro.proc.derive] +## The `proc_macro_derive` attribute + +r[macro.proc.derive.intro] +Applying the *`proc_macro_derive` [attribute]* to a function defines a *derive macro* that can be invoked by the [`derive` attribute]. These macros are given the token stream of a [struct], [enum], or [union] definition and can emit new [items] after it. They can also declare and use [derive macro helper attributes]. + +> [!EXAMPLE] +> This derive macro ignores its input and appends tokens that define a function. +> +> <!-- ignore: test doesn't support proc-macro --> +> ```rust,ignore +> # #![crate_type = "proc-macro"] +> extern crate proc_macro; +> use proc_macro::TokenStream; +> +> #[proc_macro_derive(AnswerFn)] +> pub fn derive_answer_fn(_item: TokenStream) -> TokenStream { +> "fn answer() -> u32 { 42 }".parse().unwrap() +> } +> ``` +> +> To use it, we might write: +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> extern crate proc_macro_examples; +> use proc_macro_examples::AnswerFn; +> +> #[derive(AnswerFn)] +> struct Struct; +> +> fn main() { +> assert_eq!(42, answer()); +> } +> ``` + +r[macro.proc.derive.syntax] +The syntax for the `proc_macro_derive` attribute is: + +```grammar,attributes +@root ProcMacroDeriveAttribute -> + `proc_macro_derive` `(` DeriveMacroName ( `,` DeriveMacroAttributes )? `,`? `)` + +DeriveMacroName -> IDENTIFIER + +DeriveMacroAttributes -> + `attributes` `(` ( IDENTIFIER (`,` IDENTIFIER)* `,`?)? `)` +``` + +The name of the derive macro is given by [DeriveMacroName]. The optional `attributes` argument is described in [macro.proc.derive.attributes]. + +r[macro.proc.derive.allowed-positions] +The `proc_macro_derive` attribute may only be applied to a `pub` function with the [Rust ABI][items.fn.extern] defined in the root of the crate with a type of `fn(TokenStream) -> TokenStream` where [`TokenStream`] comes from the [`proc_macro` crate]. The function may be `const` and may use `extern` to explicitly specify the Rust ABI, but it may not use any other [qualifiers][FunctionQualifiers] (e.g. it may not be `async` or `unsafe`). + +r[macro.proc.derive.duplicates] +The `proc_macro_derive` attribute may be used only once on a function. + +r[macro.proc.derive.namespace] +The `proc_macro_derive` attribute publicly defines the derive macro in the [macro namespace] in the root of the crate. + +r[macro.proc.derive.output] +The input [`TokenStream`] is the token stream of the item to which the `derive` attribute is applied. The output [`TokenStream`] must be a (possibly empty) set of items. These items are appended following the input item within the same [module] or [block]. + +r[macro.proc.derive.attributes] +### Derive macro helper attributes + +r[macro.proc.derive.attributes.intro] +Derive macros can declare *derive macro helper attributes* to be used within the scope of the [item] to which the derive macro is applied. These [attributes] are [inert]. While their purpose is to be used by the macro that declared them, they can be seen by any macro. + +r[macro.proc.derive.attributes.decl] +A helper attribute for a derive macro is declared by adding its identifier to the `attributes` list in the `proc_macro_derive` attribute. + +> [!EXAMPLE] +> This declares a helper attribute and then ignores it. +> +> <!-- ignore: test doesn't support proc-macro --> +> ```rust,ignore +> # #![crate_type="proc-macro"] +> # extern crate proc_macro; +> # use proc_macro::TokenStream; +> # +> #[proc_macro_derive(WithHelperAttr, attributes(helper))] +> pub fn derive_with_helper_attr(_item: TokenStream) -> TokenStream { +> TokenStream::new() +> } +> ``` +> +> To use it, we might write: +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> #[derive(WithHelperAttr)] +> struct Struct { +> #[helper] field: (), +> } +> ``` + +r[macro.proc.derive.attributes.scope] +When a derive macro invocation is applied to an item, the helper attributes introduced by that derive macro become in scope 1) for attributes that are applied to that item and are applied lexically after the derive macro invocation and 2) for attributes that are applied to fields and variants inside of the item. + +> [!NOTE] +> rustc currently allows derive helpers to be used before the macro that introduces them. Such derive helpers used out of order may not shadow other attribute macros. This behavior is deprecated and slated for removal. +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> #[helper] // Deprecated, hard error in the future. +> #[derive(WithHelperAttr)] +> struct Struct { +> field: (), +> } +> ``` +> +> For more details, see [Rust issue #79202](https://github.com/rust-lang/rust/issues/79202). + + +<!-- template:attributes --> +r[macro.proc.attribute] +## The `proc_macro_attribute` attribute + +r[macro.proc.attribute.intro] +The *`proc_macro_attribute` [attribute][attributes]* defines an *attribute macro* which can be used as an [outer attribute][attributes]. + +> [!EXAMPLE] +> This attribute macro takes the input stream and emits it as-is, effectively being a no-op attribute. +> +> <!-- ignore: test doesn't support proc-macro --> +> ```rust,ignore +> # #![crate_type = "proc-macro"] +> # extern crate proc_macro; +> # use proc_macro::TokenStream; +> +> #[proc_macro_attribute] +> pub fn return_as_is(_attr: TokenStream, item: TokenStream) -> TokenStream { +> item +> } +> ``` + +> [!EXAMPLE] +> This shows, in the output of the compiler, the stringified [`TokenStream`s] that attribute macros see. +> +> <!-- ignore: test doesn't support proc-macro --> +> ```rust,ignore +> // my-macro/src/lib.rs +> # extern crate proc_macro; +> # use proc_macro::TokenStream; +> #[proc_macro_attribute] +> pub fn show_streams(attr: TokenStream, item: TokenStream) -> TokenStream { +> println!("attr: \"{attr}\""); +> println!("item: \"{item}\""); +> item +> } +> ``` +> +> <!-- ignore: requires external crates --> +> ```rust,ignore +> // src/lib.rs +> extern crate my_macro; +> +> use my_macro::show_streams; +> +> // Example: Basic function. +> #[show_streams] +> fn invoke1() {} +> // out: attr: "" +> // out: item: "fn invoke1() {}" +> +> // Example: Attribute with input. +> #[show_streams(bar)] +> fn invoke2() {} +> // out: attr: "bar" +> // out: item: "fn invoke2() {}" +> +> // Example: Multiple tokens in the input. +> #[show_streams(multiple => tokens)] +> fn invoke3() {} +> // out: attr: "multiple => tokens" +> // out: item: "fn invoke3() {}" +> +> // Example: Delimiters in the input. +> #[show_streams { delimiters }] +> fn invoke4() {} +> // out: attr: "delimiters" +> // out: item: "fn invoke4() {}" +> ``` + +r[macro.proc.attribute.syntax] +The `proc_macro_attribute` attribute uses the [MetaWord] syntax. + +r[macro.proc.attribute.allowed-positions] +The `proc_macro_attribute` attribute may only be applied to a `pub` function of type `fn(TokenStream, TokenStream) -> TokenStream` where [`TokenStream`] comes from the [`proc_macro` crate]. It must have the ["Rust" ABI][items.fn.extern]. No other function qualifiers are allowed. It must be located in the root of the crate. + +r[macro.proc.attribute.duplicates] +The `proc_macro_attribute` attribute may only be specified once on a function. + +r[macro.proc.attribute.namespace] +The `proc_macro_attribute` attribute defines the attribute in the [macro namespace] in the root of the crate with the same name as the function. + +r[macro.proc.attribute.use-positions] +Attribute macros can only be used on: + +- [Items] +- Items in [`extern` blocks] +- Inherent and trait [implementations] +- [Trait definitions] + +r[macro.proc.attribute.inner] +Attribute macros cannot be used as an [inner attribute]. + +r[macro.proc.attribute.outline-mod] +For any [outline modules] present in the macro's input, only the tokens of the module declaration are passed; the file contents of the module are not loaded or included in the input. + +r[macro.proc.attribute.behavior] +The first [`TokenStream`] parameter is the delimited token tree following the attribute's name but not including the outer delimiters. If the applied attribute contains only the attribute name or the attribute name followed by empty delimiters, the [`TokenStream`] is empty. + +The second [`TokenStream`] is the rest of the [item], including other [attributes] on the [item]. + +The item to which the attribute is applied is replaced by the zero or more items in the returned [`TokenStream`]. + +r[macro.proc.token] +## Declarative macro tokens and procedural macro tokens + +r[macro.proc.token.intro] +Declarative `macro_rules` macros and procedural macros use similar, but different definitions for tokens (or rather [`TokenTree`s].) + +r[macro.proc.token.macro_rules] +Token trees in `macro_rules` (corresponding to `tt` matchers) are defined as +- Delimited groups (`(...)`, `{...}`, etc) +- All operators supported by the language, both single-character and multi-character ones (`+`, `+=`). + - Note that this set doesn't include the single quote `'`. +- Literals (`"string"`, `1`, etc) + - Note that negation (e.g. `-1`) is never a part of such literal tokens, but a separate operator token. +- Identifiers, including keywords (`ident`, `r#ident`, `fn`) +- Lifetimes (`'ident`) +- Metavariable substitutions in `macro_rules` (e.g. `$my_expr` in `macro_rules! mac { ($my_expr: expr) => { $my_expr } }` after the `mac`'s expansion, which will be considered a single token tree regardless of the passed expression) + +r[macro.proc.token.tree] +Token trees in procedural macros are defined as +- Delimited groups (`(...)`, `{...}`, etc) +- All punctuation characters used in operators supported by the language (`+`, but not `+=`), and also the single quote `'` character (typically used in lifetimes, see below for lifetime splitting and joining behavior) +- Literals (`"string"`, `1`, etc) + - Negation (e.g. `-1`) is supported as a part of integer and floating point literals. +- Identifiers, including keywords (`ident`, `r#ident`, `fn`) + +r[macro.proc.token.conversion.intro] +Mismatches between these two definitions are accounted for when token streams are passed to and from procedural macros. Note that the conversions below may happen lazily, so they might not happen if the tokens are not actually inspected. + +r[macro.proc.token.conversion.to-proc_macro] +When passed to a proc-macro +- All multi-character operators are broken into single characters. +- Lifetimes are broken into a `'` character and an identifier. +- The keyword metavariable [`$crate`] is passed as a single identifier. +- All other metavariable substitutions are represented as their underlying token streams. + - Such token streams may be wrapped into delimited groups ([`Group`]) with implicit delimiters ([`Delimiter::None`]) when it's necessary for preserving parsing priorities. + - `tt` and `ident` substitutions are never wrapped into such groups and always represented as their underlying token trees. + +r[macro.proc.token.conversion.from-proc_macro] +When emitted from a proc macro +- Punctuation characters are glued into multi-character operators when applicable. +- Single quotes `'` joined with identifiers are glued into lifetimes. +- Negative literals are converted into two tokens (the `-` and the literal) possibly wrapped into a delimited group ([`Group`]) with implicit delimiters ([`Delimiter::None`]) when it's necessary for preserving parsing priorities. + +r[macro.proc.token.doc-comment] +Note that neither declarative nor procedural macros support doc comment tokens (e.g. `/// Doc`), so they are always converted to token streams representing their equivalent `#[doc = r"str"]` attributes when passed to macros. + +[Attribute macros]: #the-proc_macro_attribute-attribute +[Cargo's build scripts]: ../cargo/reference/build-scripts.html +[Derive macros]: macro.proc.derive +[Function-like macros]: #the-proc_macro-attribute +[`$crate`]: macro.decl.hygiene.crate +[`Delimiter::None`]: proc_macro::Delimiter::None +[`Group`]: proc_macro::Group +[`TokenStream`]: proc_macro::TokenStream +[`TokenStream`s]: proc_macro::TokenStream +[`TokenTree`s]: proc_macro::TokenTree +[`derive` attribute]: attributes/derive.md +[`extern` blocks]: items/external-blocks.md +[`macro_rules`]: macros-by-example.md +[`proc_macro` crate]: proc_macro +[attribute]: attributes.md +[attributes]: attributes.md +[block]: expressions/block-expr.md +[crate type]: linkage.md +[derive macro helper attributes]: #derive-macro-helper-attributes +[enum]: items/enumerations.md +[expressions]: expressions.md +[function]: items/functions.md +[implementations]: items/implementations.md +[inert]: attributes.md#active-and-inert-attributes +[inner attribute]: attributes.inner +[item]: items.md +[items]: items.md +[macro namespace]: names/namespaces.md +[module]: items/modules.md +[outline modules]: items.mod.outlined +[patterns]: patterns.md +[public]: visibility-and-privacy.md +[statements]: statements.md +[struct]: items/structs.md +[trait definitions]: items/traits.md +[type expressions]: types.md#type-expressions +[type]: types.md +[union]: items/unions.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/runtime.md b/stdlib/kvlang/reference/rust/reference-repo/src/runtime.md new file mode 100644 index 00000000..651d7c9c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/runtime.md @@ -0,0 +1,88 @@ +r[runtime] +# The Rust runtime + +r[runtime.intro] +This section documents features that define some aspects of the Rust runtime. + +<!-- template:attributes --> +r[runtime.global_allocator] +## The `global_allocator` attribute + +r[runtime.global_allocator.intro] +The *`global_allocator` [attribute][attributes]* selects a [memory allocator][std::alloc]. + +> [!EXAMPLE] +> ```rust +> use core::alloc::{GlobalAlloc, Layout}; +> use std::alloc::System; +> +> struct MyAllocator; +> +> unsafe impl GlobalAlloc for MyAllocator { +> unsafe fn alloc(&self, layout: Layout) -> *mut u8 { +> unsafe { System.alloc(layout) } +> } +> unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { +> unsafe { System.dealloc(ptr, layout) } +> } +> } +> +> #[global_allocator] +> static GLOBAL: MyAllocator = MyAllocator; +> ``` + +r[runtime.global_allocator.syntax] +The `global_allocator` attribute uses the [MetaWord] syntax. + +r[runtime.global_allocator.allowed-positions] +The `global_allocator` attribute may only be applied to a [static item] whose type implements the [`GlobalAlloc`] trait. + +r[runtime.global_allocator.duplicates] +The `global_allocator` attribute may only be used once on an item. + +r[runtime.global_allocator.single] +The `global_allocator` attribute may only be used once in the crate graph. + +r[runtime.global_allocator.stdlib] +The `global_allocator` attribute is exported from the [standard library prelude][core::prelude::v1]. + +<!-- template:attributes --> +r[runtime.windows_subsystem] +## The `windows_subsystem` attribute + +r[runtime.windows_subsystem.intro] +The *`windows_subsystem` [attribute][attributes]* sets the [subsystem] when linking on a Windows target. + +> [!EXAMPLE] +> ```rust +> #![windows_subsystem = "windows"] +> ``` + +r[runtime.windows_subsystem.syntax] +The `windows_subsystem` attribute uses the [MetaNameValueStr] syntax. Accepted values are `"console"` and `"windows"`. + +r[runtime.windows_subsystem.allowed-positions] +The `windows_subsystem` attribute may only be applied to the crate root. + +r[runtime.windows_subsystem.duplicates] +Only the first use of `windows_subsystem` has effect. + +> [!NOTE] +> `rustc` lints against any use following the first. This may become an error in the future. + +r[runtime.windows_subsystem.ignored] +The `windows_subsystem` attribute is ignored on non-Windows targets and non-`bin` [crate types]. + +r[runtime.windows_subsystem.console] +The `"console"` subsystem is the default. If a console process is run from an existing console then it will be attached to that console; otherwise a new console window will be created. + +r[runtime.windows_subsystem.windows] +The `"windows"` subsystem will run detached from any existing console. + +> [!NOTE] +> The `"windows"` subsystem is commonly used by GUI applications that do not want to display a console window on startup. + +[`GlobalAlloc`]: alloc::alloc::GlobalAlloc +[crate types]: linkage.md +[static item]: items/static-items.md +[subsystem]: https://msdn.microsoft.com/en-us/library/fcc1zstk.aspx diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/shebang.md b/stdlib/kvlang/reference/rust/reference-repo/src/shebang.md new file mode 100644 index 00000000..dbc5ee33 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/shebang.md @@ -0,0 +1,47 @@ +r[shebang] +# Shebang + +r[shebang.intro] +A *[shebang]* is an optional line that is typically used in Unix-like systems to specify an interpreter for executing the file. + +> [!EXAMPLE] +> <!-- ignore: tests don't like shebang --> +> ```rust,ignore +> #!/usr/bin/env rustx +> +> fn main() { +> println!("Hello!"); +> } +> ``` + +r[shebang.syntax] +```grammar,lexer +@root SHEBANG -> + `#!` !((WHITESPACE | LINE_COMMENT | SHEBANG_BLOCK_COMMENT)* `[`) + ~LF* (LF | EOF) + +SHEBANG_BLOCK_COMMENT -> + `/*` !(`!` | `*` ![`*` `/`]) + ( SHEBANG_NESTED_BLOCK_COMMENT | (!(`*/` | `/*`) CHAR) )* + `*/` + +SHEBANG_NESTED_BLOCK_COMMENT -> + `/*` + ( SHEBANG_NESTED_BLOCK_COMMENT | (!(`*/` | `/*`) CHAR) )* + `*/` +``` + +r[shebang.syntax-description] +The shebang starts with the characters `#!` and extends through the first `U+000A` (LF) or through EOF if no LF is present. If the `#!` characters are followed by `[` (ignoring any intervening [whitespace] or [non-doc comments]), the line is not considered a shebang (to avoid ambiguity with an [inner attribute]). + +> [!NOTE] +> Doc comments are not ignored when determining whether `[` follows the `#!` characters. For example, `#! /*! */ [allow(unused)]` at the start of a file is a shebang, not an inner attribute, because `/*! */` is a doc comment. Likewise, text following `#!` that resembles an unterminated block comment, as in `#!/*`, does not cause an error; the line is a shebang. + +r[shebang.position] +The shebang may appear immediately at the start of the file or after the optional [byte order mark]. + +[byte order mark]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 +[inner attribute]: attributes.md +[non-doc comments]: comments.normal +[shebang]: https://en.wikipedia.org/wiki/Shebang_(Unix) +[whitespace]: whitespace.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/special-types-and-traits.md b/stdlib/kvlang/reference/rust/reference-repo/src/special-types-and-traits.md new file mode 100644 index 00000000..e508bf15 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/special-types-and-traits.md @@ -0,0 +1,227 @@ +r[lang-types] +# Special types and traits + +r[lang-types.intro] +Certain types and traits that exist in [the standard library] are known to the Rust compiler. This chapter documents the special features of these types and traits. + +r[lang-types.box] +## `Box<T>` + +r[lang-types.box.intro] +[`Box<T>`] has a few special features that Rust doesn't currently allow for user defined types. + +r[lang-types.box.deref] +* The [dereference operator] for `Box<T>` produces a place which can be [moved from]. This means that the `*` operator and the destructor of `Box<T>` are built-in to the language. + +r[lang-types.box.receiver] +* [Methods] can take `Box<Self>` as a receiver. + +r[lang-types.box.fundamental] +* A trait may be implemented for `Box<T>` in the same crate as `T`, which the [orphan rules] prevent for other generic types. + +<!-- Editor Note: This is nowhere close to an exhaustive list --> + +r[lang-types.rc] +## `Rc<T>` + +r[lang-types.rc.receiver] +[Methods] can take [`Rc<Self>`] as a receiver. + +r[lang-types.arc] +## `Arc<T>` + +r[lang-types.arc.receiver] +[Methods] can take [`Arc<Self>`] as a receiver. + +r[lang-types.pin] +## `Pin<P>` + +r[lang-types.pin.receiver] +[Methods] can take [`Pin<P>`] as a receiver. + +r[lang-types.unsafe-cell] +## `UnsafeCell<T>` + +r[lang-types.unsafe-cell.interior-mut] +[`std::cell::UnsafeCell<T>`] is used for [interior mutability]. It ensures that the compiler doesn't perform optimisations that are incorrect for such types. + +r[lang-types.unsafe-cell.read-only-alloc] +It also ensures that [`static` items] which have a type with interior mutability aren't placed in memory marked as read only. + +r[lang-types.phantom-data] +## `PhantomData<T>` + +[`std::marker::PhantomData<T>`] is a [zero-sized], minimum alignment, type that is considered to own a `T` for the purposes of [variance], [drop check], and [auto traits](#auto-traits). + +r[lang-types.va-list] +## `VaList<'_>` + +[`VaList`] is used for [C-variadic functions]. + +> [!NOTE] +> [`VaList`] is ABI compatible with the C `va_list` type; see [items.fn.c-variadic.abi-compatibility]. + +r[lang-types.ops] +## Operator traits + +The traits in [`std::ops`] and [`std::cmp`] are used to overload [operators], [indexing expressions], and [call expressions]. + +r[lang-types.deref] +## `Deref` and `DerefMut` + +As well as overloading the unary `*` operator, [`Deref`] and [`DerefMut`] are also used in [method resolution] and [deref coercions]. + +r[lang-types.drop] +## `Drop` + +The [`Drop`] trait provides a [destructor], to be run whenever a value of this type is to be destroyed. + +r[lang-types.copy] +## `Copy` + +r[lang-types.copy.intro] +The [`Copy`] trait changes the semantics of a type implementing it. + +r[lang-types.copy.behavior] +Values whose type implements `Copy` are copied rather than moved upon assignment. + +r[lang-types.copy.constraint] +`Copy` can only be implemented for types which do not implement `Drop`, and whose fields are all `Copy`. For enums, this means all fields of all variants have to be `Copy`. For unions, this means all variants have to be `Copy`. + +r[lang-types.copy.builtin-types] +`Copy` is implemented by the compiler for + +r[lang-types.copy.tuple] +* [Tuples] of `Copy` types + +r[lang-types.copy.fn-pointer] +* [Function pointers] + +r[lang-types.copy.fn-item] +* [Function items] + +r[lang-types.copy.closure] +* [Closures] that capture no values or that only capture values of `Copy` types + +r[lang-types.clone] +## `Clone` + +r[lang-types.clone.intro] +The [`Clone`] trait is a supertrait of `Copy`, so it also needs compiler generated implementations. + +r[lang-types.clone.builtin-types] +It is implemented by the compiler for the following types: + +r[lang-types.clone.builtin-copy] +* Types with a built-in `Copy` implementation (see above) + +r[lang-types.clone.tuple] +* [Tuples] of `Clone` types + +r[lang-types.clone.closure] +* [Closures] that only capture values of `Clone` types or capture no values from the environment + +r[lang-types.send] +## `Send` + +The [`Send`] trait indicates that a value of this type is safe to send from one thread to another. + +r[lang-types.sync] +## `Sync` + +r[lang-types.sync.intro] +The [`Sync`] trait indicates that a value of this type is safe to share between multiple threads. + +r[lang-types.sync.static-constraint] +This trait must be implemented for all types used in immutable [`static` items]. + +r[lang-types.termination] +## `Termination` + +The [`Termination`] trait indicates the acceptable return types for the [main function] and [test functions]. + +r[lang-types.auto-traits] +## Auto traits + +r[lang-types.auto-traits.intro] +The [`Send`], [`Sync`], [`Unpin`], [`UnwindSafe`], and [`RefUnwindSafe`] traits are _auto traits_. Auto traits have special properties. + +r[lang-types.auto-traits.auto-impl] +If no explicit implementation or negative implementation is written out for an auto trait for a given type, then the compiler implements it automatically according to the following rules: + +r[lang-types.auto-traits.builtin-composite] +* `&T`, `&mut T`, `*const T`, `*mut T`, `[T; n]`, and `[T]` implement the trait if `T` does. + +r[lang-types.auto-traits.fn-item-pointer] +* Function item types and function pointers automatically implement the trait. + +r[lang-types.auto-traits.aggregate] +* Structs, enums, unions, and tuples implement the trait if all of their fields do. + +r[lang-types.auto-traits.closure] +* Closures implement the trait if the types of all of their captures do. A closure that captures a `T` by shared reference and a `U` by value implements any auto traits that both `&T` and `U` do. + +r[lang-types.auto-traits.generic-impl] +For generic types (counting the built-in types above as generic over `T`), if a generic implementation is available, then the compiler does not automatically implement it for types that could use the implementation except that they do not meet the requisite trait bounds. For instance, the standard library implements `Send` for all `&T` where `T` is `Sync`; this means that the compiler will not implement `Send` for `&T` if `T` is `Send` but not `Sync`. + +r[lang-types.auto-traits.negative] +Auto traits can also have negative implementations, shown as `impl !AutoTrait for T` in the standard library documentation, that override the automatic implementations. For example `*mut T` has a negative implementation of `Send`, and so `*mut T` is not `Send`, even if `T` is. There is currently no stable way to specify additional negative implementations; they exist only in the standard library. + +r[lang-types.auto-traits.trait-object-marker] +Auto traits may be added as an additional bound to any [trait object], even though normally only one trait is allowed. For instance, `Box<dyn Debug + Send + UnwindSafe>` is a valid type. + +r[lang-types.sized] +## `Sized` + +r[lang-types.sized.intro] +The [`Sized`] trait indicates that the size of this type is known at compile-time; that is, it's not a [dynamically sized type]. + +r[lang-types.sized.implicit-sized] +[Type parameters] (except `Self` in traits) are `Sized` by default, as are [associated types]. + +r[lang-types.sized.implicit-impl] +`Sized` is always implemented automatically by the compiler, not by [implementation items]. + +r[lang-types.sized.relaxation] +These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound. + +[`Arc<Self>`]: std::sync::Arc +[`Deref`]: std::ops::Deref +[`DerefMut`]: std::ops::DerefMut +[`Pin<P>`]: std::pin::Pin +[`Rc<Self>`]: std::rc::Rc +[`RefUnwindSafe`]: std::panic::RefUnwindSafe +[`Termination`]: std::process::Termination +[`UnwindSafe`]: std::panic::UnwindSafe +[`Unpin`]: std::marker::Unpin + +[Arrays]: types/array.md +[associated types]: items/associated-items.md#associated-types +[call expressions]: expressions/call-expr.md +[C-variadic functions]: items.fn.c-variadic +[deref coercions]: type-coercions.md#coercion-types +[dereference operator]: expressions/operator-expr.md#the-dereference-operator +[destructor]: destructors.md +[drop check]: ../nomicon/dropck.html +[dynamically sized type]: dynamically-sized-types.md +[Function pointers]: types/function-pointer.md +[Function items]: types/function-item.md +[implementation items]: items/implementations.md +[indexing expressions]: expressions/array-expr.md#array-and-slice-indexing-expressions +[interior mutability]: interior-mutability.md +[main function]: crates-and-source-files.md#main-functions +[Methods]: items/associated-items.md#associated-functions-and-methods +[method resolution]: expressions/method-call-expr.md +[moved from]: expr.move.movable-place +[operators]: expressions/operator-expr.md +[orphan rules]: items/implementations.md#trait-implementation-coherence +[`static` items]: items/static-items.md +[test functions]: attributes/testing.md#the-test-attribute +[the standard library]: std +[trait object]: types/trait-object.md +[Tuples]: types/tuple.md +[Type parameters]: types/parameters.md +[`VaList`]: core::ffi::VaList +[variance]: subtyping.md#variance +[zero-sized]: glossary.zst +[Closures]: types/closure.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/statements-and-expressions.md b/stdlib/kvlang/reference/rust/reference-repo/src/statements-and-expressions.md new file mode 100644 index 00000000..fdd1522a --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/statements-and-expressions.md @@ -0,0 +1,6 @@ +r[stmt-expr] +# Statements and expressions + +Rust is _primarily_ an expression language. This means that most forms of value-producing or effect-causing evaluation are directed by the uniform syntax category of _expressions_. Each kind of expression can typically _nest_ within each other kind of expression, and rules for evaluation of expressions involve specifying both the value produced by the expression and the order in which its sub-expressions are themselves evaluated. + +In contrast, statements serve _mostly_ to contain and explicitly sequence expression evaluation. diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/statements.md b/stdlib/kvlang/reference/rust/reference-repo/src/statements.md new file mode 100644 index 00000000..a3e89e8d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/statements.md @@ -0,0 +1,157 @@ +r[statement] +# Statements + +r[statement.syntax] +```grammar,statements +Statement -> + `;` + | Item + | LetStatement + | ExpressionStatement + | OuterAttribute* MacroInvocationSemi +``` + +r[statement.intro] +A *statement* is a component of a [block], which is in turn a component of an outer [expression] or [function]. + +r[statement.kind] +Rust has two kinds of statement: [declaration statements](#declaration-statements) and [expression statements](#expression-statements). + +r[statement.decl] +## Declaration statements + +A *declaration statement* is one that introduces one or more *names* into the enclosing statement block. The declared names may denote new variables or new [items][item]. + +The two kinds of declaration statements are item declarations and `let` statements. + +r[statement.item] +### Item declarations + +r[statement.item.intro] +An *item declaration statement* has a syntactic form identical to an [item declaration][item] within a [module]. + +r[statement.item.scope] +Declaring an item within a statement block restricts its [scope] to the block containing the statement. The item is not given a [canonical path] nor are any sub-items it may declare. + +r[statement.item.associated-scope] +The exception to this is that associated items defined by [implementations] are still accessible in outer scopes as long as the item and, if applicable, trait are accessible. It is otherwise identical in meaning to declaring the item inside a module. + +r[statement.item.outer-generics] +There is no implicit capture of the containing function's generic parameters, parameters, and local variables. For example, `inner` may not access `outer_var`. + +```rust +fn outer() { + let outer_var = true; + + fn inner() { /* outer_var is not in scope here */ } + + inner(); +} +``` + +r[statement.let] +### `let` statements + +r[statement.let.syntax] +```grammar,statements +LetStatement -> + OuterAttribute* `let` PatternNoTopAlt ( `:` Type )? + ( + `=` Expression + | `=` Expression _except [LazyBooleanExpression] or end with a `}`_ + `else` BlockExpressionNoInnerAttributes + )? `;` +``` + +r[statement.let.intro] +A *`let` statement* introduces a new set of [variables], given by a [pattern]. The pattern is followed optionally by a type annotation and then either ends, or is followed by an initializer expression plus an optional `else` block. + +r[statement.let.inference] +When no type annotation is given, the compiler will infer the type, or signal an error if insufficient type information is available for definite inference. + +r[statement.let.scope] +Any variables introduced by a variable declaration are visible from the point of declaration until the end of the enclosing block scope, except when they are shadowed by another variable declaration. + +r[statement.let.constraint] +If an `else` block is not present, the pattern must be irrefutable. If an `else` block is present, the pattern may be refutable. + +r[statement.let.behavior] +If the pattern does not match (this requires it to be refutable), the `else` block is executed. The `else` block must always diverge (evaluate to the [never type]). + +```rust +let (mut v, w) = (vec![1, 2, 3], 42); // The bindings may be mut or const +let Some(t) = v.pop() else { // Refutable patterns require an else block + panic!(); // The else block must diverge +}; +let [u, v] = [v[0], v[1]] else { // This pattern is irrefutable, so the compiler + // will lint as the else block is redundant. + panic!(); +}; +``` + +r[statement.expr] +## Expression statements + +r[statement.expr.syntax] +```grammar,statements +ExpressionStatement -> + ExpressionWithoutBlock `;` + | ExpressionWithBlock `;`? +``` + +r[statement.expr.intro] +An *expression statement* is one that evaluates an [expression] and ignores its result. As a rule, an expression statement's purpose is to trigger the effects of evaluating its expression. + +r[statement.expr.restriction-semicolon] +An expression that consists of only a [block expression][block] or control flow expression, if used in a context where a statement is permitted, can omit the trailing semicolon. This can cause an ambiguity between it being parsed as a standalone statement and as a part of another expression; in this case, it is parsed as a statement. + +r[statement.expr.constraint-block] +The type of [ExpressionWithBlock] expressions when used as statements must be the unit type. + +```rust +# let mut v = vec![1, 2, 3]; +v.pop(); // Ignore the element returned from pop +if v.is_empty() { + v.push(5); +} else { + v.remove(0); +} // Semicolon can be omitted. +[1]; // Separate expression statement, not an indexing expression. +``` + +When the trailing semicolon is omitted, the result must be type `()`. + +```rust +// bad: the block's type is i32, not () +// Error: expected `()` because of default return type +// if true { +// 1 +// } + +// good: the block's type is i32 +if true { + 1 +} else { + 2 +}; +``` + +r[statement.attribute] +## Attributes on statements + +Statements accept [outer attributes]. The attributes that have meaning on a statement are [`cfg`], and [the lint check attributes]. + +[block]: expressions/block-expr.md +[expression]: expressions.md +[function]: items/functions.md +[item]: items.md +[module]: items/modules.md +[never type]: types/never.md +[canonical path]: paths.md#canonical-paths +[implementations]: items/implementations.md +[variables]: variables.md +[outer attributes]: attributes.md +[`cfg`]: conditional-compilation.md +[the lint check attributes]: attributes/diagnostics.md#lint-check-attributes +[pattern]: patterns.md +[scope]: names/scopes.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/subtyping.md b/stdlib/kvlang/reference/rust/reference-repo/src/subtyping.md new file mode 100644 index 00000000..1e9d6c15 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/subtyping.md @@ -0,0 +1,113 @@ +r[subtype] +# Subtyping and variance + +r[subtype.intro] +Subtyping is implicit and can occur at any stage in type checking or inference. + +r[subtype.kinds] +Subtyping is restricted to two cases: variance with respect to lifetimes and between types with higher ranked lifetimes. If we were to erase lifetimes from types, then the only subtyping would be due to type equality. + +Consider the following example: string literals always have `'static` lifetime. Nevertheless, we can assign `s` to `t`: + +```rust +fn bar<'a>() { + let s: &'static str = "hi"; + let t: &'a str = s; +} +``` + +Since `'static` outlives the lifetime parameter `'a`, `&'static str` is a subtype of `&'a str`. + +r[subtype.higher-ranked] +[Higher-ranked] [function pointers] and [trait objects] have another subtype relation. They are subtypes of types that are given by substitutions of the higher-ranked lifetimes. Some examples: + +```rust +// Here 'a is substituted for 'static +let subtype: &(for<'a> fn(&'a i32) -> &'a i32) = &((|x| x) as fn(&_) -> &_); +let supertype: &(fn(&'static i32) -> &'static i32) = subtype; + +// This works similarly for trait objects +let subtype: &(dyn for<'a> Fn(&'a i32) -> &'a i32) = &|x| x; +let supertype: &(dyn Fn(&'static i32) -> &'static i32) = subtype; + +// We can also substitute one higher-ranked lifetime for another +let subtype: &(for<'a, 'b> fn(&'a i32, &'b i32)) = &((|x, y| {}) as fn(&_, &_)); +let supertype: &for<'c> fn(&'c i32, &'c i32) = subtype; +``` + +r[subtyping.variance] +## Variance + +r[subtyping.variance.intro] +Variance is a property that generic types have with respect to their arguments. A generic type's *variance* in a parameter is how the subtyping of the parameter affects the subtyping of the type. + +r[subtyping.variance.covariant] +* `F<T>` is *covariant* over `T` if `T` being a subtype of `U` implies that `F<T>` is a subtype of `F<U>` (subtyping "passes through") + +r[subtyping.variance.contravariant] +* `F<T>` is *contravariant* over `T` if `T` being a subtype of `U` implies that `F<U>` is a subtype of `F<T>` + +r[subtyping.variance.invariant] +* `F<T>` is *invariant* over `T` otherwise (no subtyping relation can be derived) + +r[subtyping.variance.builtin-types] +Variance of types is automatically determined as follows + +| Type | Variance in `'a` | Variance in `T` | +|-------------------------------|-------------------|-------------------| +| `&'a T` | covariant | covariant | +| `&'a mut T` | covariant | invariant | +| `*const T` | | covariant | +| `*mut T` | | invariant | +| `[T]` and `[T; n]` | | covariant | +| `fn() -> T` | | covariant | +| `fn(T) -> ()` | | contravariant | +| `std::cell::UnsafeCell<T>` | | invariant | +| `std::marker::PhantomData<T>` | | covariant | +| `dyn Trait<T> + 'a` | covariant | invariant | + +r[subtyping.variance.user-composite-types] +The variance of other `struct`, `enum`, and `union` types is decided by looking at the variance of the types of their fields. If the parameter is used in positions with different variances then the parameter is invariant. For example the following struct is covariant in `'a` and `T` and invariant in `'b`, `'c`, and `U`. + +```rust +use std::cell::UnsafeCell; +struct Variance<'a, 'b, 'c, T, U: 'a> { + x: &'a U, // This makes `Variance` covariant in 'a, and would + // make it covariant in U, but U is used later + y: *const T, // Covariant in T + z: UnsafeCell<&'b f64>, // Invariant in 'b + w: *mut U, // Invariant in U, makes the whole struct invariant + + f: fn(&'c ()) -> &'c () // Both co- and contravariant, makes 'c invariant + // in the struct. +} +``` + +r[subtyping.variance.builtin-composite-types] +When used outside of an `struct`, `enum`, or `union`, the variance for parameters is checked at each location separately. + +```rust +# use std::cell::UnsafeCell; +fn generic_tuple<'short, 'long: 'short>( + // 'long is used inside of a tuple in both a co- and invariant position. + x: (&'long u32, UnsafeCell<&'long u32>), +) { + // As the variance at these positions is computed separately, + // we can freely shrink 'long in the covariant position. + let _: (&'short u32, UnsafeCell<&'long u32>) = x; +} + +fn takes_fn_ptr<'short, 'middle: 'short>( + // 'middle is used in both a co- and contravariant position. + f: fn(&'middle ()) -> &'middle (), +) { + // As the variance at these positions is computed separately, + // we can freely shrink 'middle in the covariant position + // and extend it in the contravariant position. + let _: fn(&'static ()) -> &'short () = f; +} +``` + +[function pointers]: types/function-pointer.md +[Higher-ranked]: ../nomicon/hrtb.html +[trait objects]: types/trait-object.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/syntax-index.md b/stdlib/kvlang/reference/rust/reference-repo/src/syntax-index.md new file mode 100644 index 00000000..ea7d0584 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/syntax-index.md @@ -0,0 +1,456 @@ +# Syntax index + +This appendix provides an index of tokens and common forms with links to where those elements are defined. + +## Keywords + +| Keyword | Use | +|---------------|-----| +| `_` | [wildcard pattern], [inferred const], [inferred type], [placeholder lifetime], [constant items], [extern crate], [use declarations], [destructuring assignment] | +| `abstract` | [reserved keyword] | +| `as` | [extern crate][items.extern-crate.as], [use declarations][items.use.forms-as], [type cast expressions], [qualified paths] | +| `async` | [async functions], [async blocks], [async closures] | +| `await` | [await expressions] | +| `become` | [reserved keyword] | +| `box` | [reserved keyword] | +| `break` | [break expressions] | +| `const` | [const functions], [const items], [const generics], [const blocks], [raw borrow operator], [raw pointer type], [const assembly operands] | +| `continue` | [continue expressions] | +| `crate` | [extern crate], [visibility], [paths] | +| `do` | [reserved keyword] | +| `dyn` | [trait objects] | +| `else` | [let statements], [if expressions] | +| `enum` | [enumerations] | +| `extern` | [extern crate], [extern function qualifier], [external blocks], [extern function pointer types] | +| `false` | [boolean type], [boolean expressions], [configuration predicates] | +| `final` | [reserved keyword] | +| `fn` | [functions], [function pointer types] | +| `for` | [trait implementations], [iterator loops], [higher-ranked trait bounds] | +| `gen` | [reserved keyword] | +| `if` | [if expressions], [match guards] | +| `impl` | [inherent impls], [trait impls], [impl trait types], [anonymous type parameters] | +| `in` | [visibility], [iterator loops], [assembly operands] | +| `let` | [let statements], [`if let` patterns] | +| `loop` | [infinite loops] | +| `macro_rules` | [macros by example] | +| `macro` | [reserved keyword] | +| `match` | [match expressions] | +| `mod` | [modules] | +| `move` | [closure expressions], [async blocks] | +| `mut` | [borrow expressions], [identifier patterns], [reference patterns], [struct patterns], [reference types], [raw pointer types], [self parameters], [static items] | +| `override` | [reserved keyword] | +| `priv` | [reserved keyword] | +| `pub` | [visibility] | +| `raw` | [borrow expressions], [raw assembly] | +| `ref` | [identifier patterns], [struct patterns] | +| `return` | [return expressions] | +| `safe` | [external block functions], [external block statics] | +| `self` | [extern crate][items.extern-crate.self], [self parameters], [visibility], [`self` paths] | +| `Self` | [`Self` type paths], [use bounds] | +| `static` | [static items], [`'static` lifetimes] | +| `struct` | [structs] | +| `super` | [super paths], [visibility] | +| `trait` | [trait items] | +| `true` | [boolean type], [boolean expressions], [configuration predicates] | +| `try` | [reserved keyword] | +| `type` | [type aliases] | +| `typeof` | [reserved keyword] | +| `union` | [union items] | +| `unsafe` | [unsafe blocks], [unsafe attributes], [unsafe modules], [unsafe functions], [unsafe external blocks], [unsafe external functions], [unsafe external statics], [unsafe traits], [unsafe trait implementations] | +| `unsized` | [reserved keyword] | +| `use` | [use items], [use bounds] | +| `virtual` | [reserved keyword] | +| `where` | [where clauses] | +| `while` | [predicate loops] | +| `yield` | [reserved keyword] | + +## Operators and punctuation + +| Symbol | Name | Use | +|--------|-------------|-----| +| `+` | Plus | [addition][arith], [trait bounds], [macro Kleene matcher] | +| `-` | Minus | [subtraction][arith], [negation] | +| `*` | Star | [multiplication][arith], [dereference], [raw pointers], [macro Kleene matcher], [glob imports] | +| `/` | Slash | [division][arith] | +| `%` | Percent | [remainder][arith] | +| `^` | Caret | [bitwise and logical XOR][arith] | +| `!` | Not | [bitwise and logical NOT][negation], [macro calls], [inner attributes][attributes], [never type], [negative impls] | +| `&` | And | [bitwise and logical AND][arith], [borrow], [references], [reference patterns] | +| `\|` | Or | [bitwise and logical OR][arith], [closures], [or patterns], [if let], [while let] | +| `&&` | AndAnd | [lazy AND][lazy-bool], [borrow], [references], [reference patterns] | +| `\|\|` | OrOr | [lazy OR][lazy-bool], [closures] | +| `<<` | Shl | [shift left][arith], [nested generics][generics] | +| `>>` | Shr | [shift right][arith], [nested generics][generics] | +| `+=` | PlusEq | [addition assignment][compound] | +| `-=` | MinusEq | [subtraction assignment][compound] | +| `*=` | StarEq | [multiplication assignment][compound] | +| `/=` | SlashEq | [division assignment][compound] | +| `%=` | PercentEq | [remainder assignment][compound] | +| `^=` | CaretEq | [bitwise XOR assignment][compound] | +| `&=` | AndEq | [bitwise AND assignment][compound] | +| `\|=` | OrEq | [bitwise OR assignment][compound] | +| `<<=` | ShlEq | [shift left assignment][compound] | +| `>>=` | ShrEq | [shift right assignment][compound], [nested generics][generics] | +| `=` | Eq | [assignment], [let statements], [attributes], various type definitions | +| `==` | EqEq | [equal][comparison] | +| `!=` | Ne | [not equal][comparison] | +| `>` | Gt | [greater than][comparison], [generics], [paths], [use bounds] | +| `<` | Lt | [less than][comparison], [generics], [paths], [use bounds] | +| `>=` | Ge | [greater than or equal to][comparison], [generics] | +| `<=` | Le | [less than or equal to][comparison] | +| `@` | At | [subpattern binding] | +| `.` | Dot | [field access][field], [tuple index], [method calls], [await expressions] | +| `..` | DotDot | [range expressions][expr.range], [struct expressions], [rest pattern], [range patterns], [struct patterns] | +| `...` | DotDotDot | [variadic functions], [range patterns] | +| `..=` | DotDotEq | [inclusive range expressions][expr.range], [range patterns] | +| `,` | Comma | various separators | +| `;` | Semi | terminator for various items and statements, [array expressions], [array types] | +| `:` | Colon | various separators | +| `::` | PathSep | [path separator][paths] | +| `->` | RArrow | [functions], [closures], [function pointer type] | +| `=>` | FatArrow | [match arms][match], [macros] | +| `<-` | LArrow | The left arrow symbol has been unused since before Rust 1.0, but it is still treated as a single token. | +| `#` | Pound | [attributes], [raw string literals], [raw byte string literals], [raw C string literals] | +| `$` | Dollar | [macros] | +| `?` | Question | [try propagation expressions][question], [relaxed trait bounds], [macro Kleene matcher] | +| `~` | Tilde | The tilde operator has been unused since before Rust 1.0, but its token may still be used. | + +## Comments + +| Comment | Use | +|----------|-----| +| `//` | [line comment][comments] | +| `//!` | [inner line comment][comments] | +| `///` | [outer line doc comment][comments] | +| `/*…*/` | [block comment][comments] | +| `/*!…*/` | [inner block doc comment][comments] | +| `/**…*/` | [outer block doc comment][comments] | + +## Other tokens + +| Token | Use | +|--------------|-----| +| `ident` | [identifiers] | +| `r#ident` | [raw identifiers] | +| `'ident` | [lifetimes and loop labels] | +| `'r#ident` | [raw lifetimes and loop labels] | +| `…u8`, `…i32`, `…f64`, `…usize`, … | [number literals] | +| `"…"` | [string literals] | +| `r"…"`, `r#"…"#`, `r##"…"##`, … | [raw string literals] | +| `b"…"` | [byte string literals] | +| `br"…"`, `br#"…"#`, `br##"…"##`, … | [raw byte string literals] | +| `'…'` | [character literals] | +| `b'…'` | [byte literals] | +| `c"…"` | [C string literals] | +| `cr"…"`, `cr#"…"#`, `cr##"…"##`, … | [raw C string literals] | + +## Macros + +| Syntax | Use | +|--------------------------------------------|-----| +| `ident!(…)`<br>`ident! {…}`<br>`ident![…]` | [macro invocations] | +| `$ident` | [macro metavariable] | +| `$ident:kind` | [macro matcher fragment specifier] | +| `$(…)…` | [macro repetition] | + +## Attributes + +| Syntax | Use | +|------------|-----| +| `#[meta]` | [outer attribute] | +| `#![meta]` | [inner attribute] | + +## Expressions + +| Expression | Use | +|---------------------------|-----| +| `\|…\| expr`<br>`\|…\| -> Type { … }` | [closures] | +| `ident::…` | [paths] | +| `::crate_name::…` | [explicit crate paths] | +| `crate::…` | [crate-relative paths] | +| `self::…` | [module-relative paths] | +| `super::…` | [parent module paths] | +| `Type::…`<br>`<Type as Trait>::ident` | [associated items] | +| `<Type>::…` | [qualified paths] which can be used for types without names such as `<&T>::…`, `<[T]>::…`, etc. | +| `Trait::method(…)`<br>`Type::method(…)`<br>`<Type as Trait>::method(…)` | [disambiguated method calls] | +| `method::<…>(…)`<br>`path::<…>` | [generic arguments], aka turbofish | +| `()` | [unit] | +| `(expr)` | [parenthesized expressions] | +| `(expr,)` | [single-element tuple expressions] | +| `(expr, …)` | [tuple expressions] | +| `expr(expr, …)` | [call expressions] | +| `expr.0`, `expr.1`, … | [tuple indexing expressions] | +| `expr.ident` | [field access expressions] | +| `{…}` | [block expressions] | +| `Type {…}` | [struct expressions] | +| `Type(…)` | [tuple struct constructors] | +| `[…]` | [array expressions] | +| `[expr; len]` | [repeat array expressions] | +| `expr[..]`, `expr[a..]`, `expr[..b]`, `expr[a..b]`, `expr[a..=b]`, `expr[..=b]` | [array and slice indexing expressions] | +| `if expr {…} else {…}` | [if expressions] | +| `match expr { pattern => {…} }` | [match expressions] | +| `loop {…}` | [infinite loop expressions] | +| `while expr {…}` | [predicate loop expressions] | +| `for pattern in expr {…}` | [iterator loops] | +| `&expr`<br>`&mut expr` | [borrow expressions] | +| `&raw const expr`<br>`&raw mut expr` | [raw borrow expressions] | +| `*expr` | [dereference expressions] | +| `expr?` | [try propagation expressions] | +| `-expr` | [negation expressions] | +| `!expr` | [bitwise and logical NOT expressions] | +| `expr as Type` | [type cast expressions] | + +## Items + +[Items] are the components of a crate. + +| Item | Use | +|-------------------------------|-----| +| `mod ident;`<br>`mod ident {…}` | [modules] | +| `use path;` | [use declarations] | +| `fn ident(…) {…}` | [functions] | +| `type Type = Type;` | [type aliases] | +| `struct ident {…}` | [structs] | +| `enum ident {…}` | [enumerations] | +| `union ident {…}` | [unions] | +| `trait ident {…}` | [traits] | +| `impl Type {…}`<br>`impl Type for Trait {…}` | [implementations] | +| `const ident = expr;` | [constant items] | +| `static ident = expr;` | [static items] | +| `extern "C" {…}` | [external blocks] | +| `fn ident<…>(…) …`<br>`struct ident<…> {…}`<br>`enum ident<…> {…}`<br>`impl<…> Type<…> {…}` | [generic definitions] | + +## Type expressions + +[Type expressions] are used to refer to types. + +| Type | Use | +|---------------------------------------|-----| +| `bool`, `u8`, `f64`, `str`, … | [primitive types] | +| `for<…>` | [higher-ranked trait bounds] | +| `T: TraitA + TraitB` | [trait bounds] | +| `T: 'a + 'b` | [lifetime bounds] | +| `T: TraitA + 'a` | [trait and lifetime bounds] | +| `T: ?Sized` | [relaxed trait bounds] | +| `[Type; len]` | [array types] | +| `(Type, …)` | [tuple types] | +| `[Type]` | [slice types] | +| `(Type)` | [parenthesized types] | +| `impl Trait` | [impl trait types], [anonymous type parameters] | +| `dyn Trait` | [trait object types] | +| `ident`<br>`ident::…` | [type paths] (can refer to [structs], [enumerations], [unions], [type aliases], [traits], [generics], etc.) | +| `Type<…>`<br>`Trait<…>` | [generic arguments] (e.g. `Vec<u8>`) | +| `Trait<ident = Type>` | [associated type bindings] (e.g. `Iterator<Item = T>`) | +| `Trait<ident: …>` | [associated type bounds] (e.g. `Iterator<Item: Send>`) | +| `&Type`<br>`&mut Type` | [reference types] | +| `*mut Type`<br>`*const Type` | [raw pointer types] | +| `fn(…) -> Type` | [function pointer types] | +| `_` | [inferred type], [inferred const] | +| `'_` | [placeholder lifetime] | +| `!` | [never type] | + +## Patterns + +[Patterns] are used to match values. + +| Pattern | Use | +|-----------------------------------|-----| +| `"foo"`, `'a'`, `123`, `2.4`, … | [literal patterns] | +| `ident` | [identifier patterns] | +| `_` | [wildcard pattern] | +| `..` | [rest pattern] | +| `a..`, `..b`, `a..b`, `a..=b`, `..=b` | [range patterns] | +| `&pattern`<br>`&mut pattern` | [reference patterns] | +| `path {…}` | [struct patterns] | +| `path(…)` | [tuple struct patterns] | +| `(pattern, …)` | [tuple patterns] | +| `(pattern)` | [grouped patterns] | +| `[pattern, …]` | [slice patterns] | +| `CONST`, `Enum::Variant`, … | [path patterns] | + +[`'static` lifetimes]: bound +[`if let` patterns]: expr.if.let +[`self` paths]: paths.qualifiers.mod-self +[`Self` type paths]: paths.qualifiers.type-self +[anonymous type parameters]: type.impl-trait.param +[arith]: expr.arith-logic +[array and slice indexing expressions]: expr.array.index +[array expressions]: expr.array +[array types]: type.array +[assembly operands]: asm.operand-type.supported-operands-in +[assignment]: expr.assign +[associated items]: items.associated +[associated type bindings]: paths.expr +[associated type bounds]: paths.expr +[async blocks]: expr.block.async +[async closures]: expr.closure.async +[async functions]: items.fn.async +[await expressions]: expr.await +[bitwise and logical NOT expressions]: expr.negate +[block expressions]: expr.block +[boolean expressions]: expr.literal +[boolean type]: type.bool +[borrow expressions]: expr.operator.borrow +[borrow]: expr.operator.borrow +[break expressions]: expr.loop.break +[byte literals]: lex.token.byte +[byte string literals]: lex.token.str-byte +[C string literals]: lex.token.str-c +[call expressions]: expr.call +[character literals]: lex.token.literal.char +[closure expressions]: expr.closure +[closures]: expr.closure +[comparison]: expr.cmp +[compound]: expr.compound-assign +[configuration predicates]: cfg +[const assembly operands]: asm.operand-type.supported-operands-const +[const blocks]: expr.block.const +[const functions]: const-eval.const-fn +[const generics]: items.generics.const +[const items]: items.const +[constant items]: items.const +[continue expressions]: expr.loop.continue +[crate-relative paths]: paths.qualifiers.crate +[dereference expressions]: expr.deref +[dereference]: expr.deref +[destructuring assignment]: expr.placeholder +[disambiguated method calls]: expr.call.desugar +[enumerations]: items.enum +[explicit crate paths]: paths.qualifiers.global-root +[extern crate]: items.extern-crate +[extern function pointer types]: type.fn-pointer.qualifiers +[extern function qualifier]: items.fn.extern +[external block functions]: items.extern.fn +[external block statics]: items.extern.static +[external blocks]: items.extern +[field access expressions]: expr.field +[field]: expr.field +[function pointer type]: type.fn-pointer +[function pointer types]: type.fn-pointer +[functions]: items.fn +[generic arguments]: items.generics +[generic definitions]: items.generics +[generics]: items.generics +[glob imports]: items.use.glob +[grouped patterns]: patterns.paren +[higher-ranked trait bounds]: bound.higher-ranked +[identifier patterns]: patterns.ident +[identifiers]: ident +[if expressions]: expr.if +[if let]: expr.if.let +[impl trait types]: type.impl-trait.return +[implementations]: items.impl +[inferred const]: items.generics.const.inferred +[inferred type]: type.inferred +[infinite loop expressions]: expr.loop.infinite +[infinite loops]: expr.loop.infinite +[inherent impls]: items.impl.inherent +[inner attribute]: attributes.inner +[iterator loops]: expr.loop.for +[lazy-bool]: expr.bool-logic +[let statements]: statement.let +[lifetime bounds]: bound.lifetime +[lifetimes and loop labels]: lex.token.life +[literal patterns]: patterns.literal +[macro calls]: macro.invocation +[macro invocations]: macro.invocation +[macro Kleene matcher]: macro.decl.repetition +[macro matcher fragment specifier]: macro.decl.meta.specifier +[macro metavariable]: macro.decl.meta +[macro repetition]: macro.decl.repetition +[macros by example]: macro.decl +[macros]: macro.decl +[match expressions]: expr.match +[match guards]: expr.match.guard +[match]: expr.match +[method calls]: expr.method +[module-relative paths]: paths.qualifiers.mod-self +[modules]: items.mod +[negation expressions]: expr.negate +[negation]: expr.negate +[negative impls]: items.impl +[never type]: type.never +[number literals]: lex.token.literal.num +[or patterns]: patterns.or +[outer attribute]: attributes.outer +[parent module paths]: paths.qualifiers.super +[parenthesized expressions]: expr.paren +[parenthesized types]: type.name.parenthesized +[path patterns]: patterns.path +[placeholder lifetime]: lifetime-elision.function.explicit-placeholder +[predicate loop expressions]: expr.loop.while +[predicate loops]: expr.loop.while +[primitive types]: type.kinds +[qualified paths]: paths.qualified +[question]: expr.try +[range patterns]: patterns.range +[raw assembly]: asm.options.supported-options-raw +[raw borrow expressions]: expr.borrow.raw +[raw borrow operator]: expr.borrow.raw +[raw byte string literals]: lex.token.str-byte-raw +[raw C string literals]: lex.token.str-c-raw +[raw identifiers]: ident.raw +[raw lifetimes and loop labels]: lex.token.life +[raw pointer type]: type.pointer.raw +[raw pointer types]: type.pointer.raw +[raw pointers]: type.pointer.raw +[raw string literals]: lex.token.literal.str-raw +[reference patterns]: patterns.ref +[reference types]: type.pointer.reference +[references]: type.pointer.reference +[relaxed trait bounds]: bound.sized +[repeat array expressions]: expr.array +[reserved keyword]: lex.keywords.reserved +[rest pattern]: patterns.rest +[return expressions]: expr.return +[self parameters]: items.fn.params.self-pat +[single-element tuple expressions]: expr.tuple +[slice patterns]: patterns.slice +[slice types]: type.slice +[static items]: items.static +[string literals]: lex.token.literal.str +[struct expressions]: expr.struct +[struct patterns]: patterns.struct +[structs]: items.struct +[subpattern binding]: patterns.ident.scrutinized +[super paths]: paths.qualifiers.super +[trait and lifetime bounds]: bound +[trait bounds]: bound +[trait implementations]: items.impl.trait +[trait impls]: items.impl.trait +[trait items]: items.traits +[trait object types]: type.trait-object +[trait objects]: type.trait-object +[traits]: items.traits +[try propagation expressions]: expr.try +[tuple expressions]: expr.tuple +[tuple index]: expr.tuple-index +[tuple indexing expressions]: expr.tuple-index +[tuple patterns]: patterns.tuple +[tuple struct constructors]: items.struct.tuple +[tuple struct patterns]: patterns.tuple-struct +[tuple types]: type.tuple +[type aliases]: items.type +[type cast expressions]: expr.as +[Type expressions]: type.name +[type paths]: type.name.path +[union items]: items.union +[unions]: items.union +[unit]: type.tuple.unit +[unsafe attributes]: attributes.safety +[unsafe blocks]: expr.block.unsafe +[unsafe external blocks]: unsafe.extern +[unsafe external functions]: items.extern.fn.safety +[unsafe external statics]: items.extern.static.safety +[unsafe functions]: unsafe.fn +[unsafe modules]: items.mod.unsafe +[unsafe trait implementations]: items.impl.trait.safety +[unsafe traits]: items.traits.safety +[use bounds]: bound.use +[use declarations]: items.use +[use items]: items.use +[variadic functions]: items.extern.variadic +[visibility]: vis +[where clauses]: items.generics.where +[while let]: expr.loop.while.let +[wildcard pattern]: patterns.wildcard diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/test-summary.md b/stdlib/kvlang/reference/rust/reference-repo/src/test-summary.md new file mode 100644 index 00000000..e4e3e749 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/test-summary.md @@ -0,0 +1,5 @@ +# Test summary + +The following is a summary of the total tests that are linked to individual rule identifiers within the reference. + +{{summary-table}} diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/tokens.md b/stdlib/kvlang/reference/rust/reference-repo/src/tokens.md new file mode 100644 index 00000000..bcd91103 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/tokens.md @@ -0,0 +1,868 @@ +r[lex.token] +# Tokens + +r[lex.token.syntax] +```grammar,lexer +Token -> + RESERVED_TOKEN + | RAW_IDENTIFIER + | CHAR_LITERAL + | STRING_LITERAL + | RAW_STRING_LITERAL + | BYTE_LITERAL + | BYTE_STRING_LITERAL + | RAW_BYTE_STRING_LITERAL + | C_STRING_LITERAL + | RAW_C_STRING_LITERAL + | FLOAT_LITERAL + | INTEGER_LITERAL + | LIFETIME_TOKEN + | PUNCTUATION + | IDENTIFIER_OR_KEYWORD +``` + +r[lex.token.intro] +Tokens are primitive productions in the grammar defined by regular (non-recursive) languages. Rust source input can be broken down into the following kinds of tokens: + +* [Keywords] +* [Identifiers][identifier] +* [Literals](#literals) +* [Lifetimes](#lifetimes-and-loop-labels) +* [Punctuation](#punctuation) +* [Delimiters](#delimiters) + +Within this documentation's grammar, "simple" tokens are given in [string table production] form, and appear in `monospace` font. + +[string table production]: notation.md#string-table-productions + +r[lex.token.literal] +## Literals + +r[lex.token.literal.intro] +Literals are tokens used in [literal expressions]. + +### Examples + +#### Characters and strings + +| | Example | `#` sets[^nsets] | Characters | Escapes | +|----------------------------------------------|-----------------|------------|-------------|---------------------| +| [Character](#character-literals) | `'H'` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) | +| [String](#string-literals) | `"hello"` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) | +| [Raw string](#raw-string-literals) | `r#"hello"#` | <256 | All Unicode | `N/A` | +| [Byte](#byte-literals) | `b'H'` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) | +| [Byte string](#byte-string-literals) | `b"hello"` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) | +| [Raw byte string](#raw-byte-string-literals) | `br#"hello"#` | <256 | All ASCII | `N/A` | +| [C string](#c-string-literals) | `c"hello"` | 0 | All Unicode | [Quote](#quote-escapes) & [Byte](#byte-escapes) & [Unicode](#unicode-escapes) | +| [Raw C string](#raw-c-string-literals) | `cr#"hello"#` | <256 | All Unicode | `N/A` | + +[^nsets]: The number of `#`s on each side of the same literal must be equivalent. + + +#### ASCII escapes + +| | Name | +|---|------| +| `\x41` | 7-bit character code (exactly 2 hex digits, up to 0x7F) | +| `\n` | Newline | +| `\r` | Carriage return | +| `\t` | Tab | +| `\\` | Backslash | +| `\0` | Null | + +#### Byte escapes + +| | Name | +|---|------| +| `\x7F` | 8-bit character code (exactly 2 hex digits) | +| `\n` | Newline | +| `\r` | Carriage return | +| `\t` | Tab | +| `\\` | Backslash | +| `\0` | Null | + +#### Unicode escapes + +| | Name | +|---|------| +| `\u{7FFF}` | 24-bit Unicode character code (up to 6 hex digits) | + +#### Quote escapes + +| | Name | +|---|------| +| `\'` | Single quote | +| `\"` | Double quote | + +#### Numbers + +| [Number literals](#number-literals)[^nl] | Example | Exponentiation | +|----------------------------------------|---------|----------------| +| Decimal integer | `98_222` | `N/A` | +| Hex integer | `0xff` | `N/A` | +| Octal integer | `0o77` | `N/A` | +| Binary integer | `0b1111_0000` | `N/A` | +| Floating-point | `123.0E+77` | `Optional` | + +[^nl]: All number literals allow `_` as a visual separator: `1_234.0E+18f64` + +r[lex.token.literal.suffix] +#### Suffixes + +r[lex.token.literal.literal.suffix.intro] +A suffix is a sequence of characters following (without intervening whitespace) the primary part of a literal of the same form as a non-raw identifier or keyword. + +r[lex.token.literal.suffix.syntax] +```grammar,lexer +SUFFIX -> + `_` ^ XID_Continue+ + | XID_Start XID_Continue* +``` + +r[lex.token.literal.suffix.validity] +Any kind of literal (string, integer, etc.) with any suffix is valid as a token. + +A literal token with any suffix can be passed to a macro without producing an error. The macro itself will decide how to interpret such a token and whether to produce an error or not. In particular, the `literal` fragment specifier for by-example macros matches literal tokens with arbitrary suffixes. + +```rust +macro_rules! blackhole { ($tt:tt) => () } +macro_rules! blackhole_lit { ($l:literal) => () } + +blackhole!("string"suffix); // OK +blackhole_lit!(1suffix); // OK +``` + +r[lex.token.literal.suffix.parse] +However, suffixes on literal tokens which are interpreted as literal expressions or patterns are restricted. Any suffixes are rejected on non-numeric literal tokens, and numeric literal tokens are accepted only with suffixes from the list below. + +| Integer | Floating-point | +|---------|----------------| +| `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, `isize` | `f32`, `f64` | + +### Character and string literals + +r[lex.token.literal.char] +#### Character literals + +r[lex.token.literal.char.syntax] +```grammar,lexer +CHAR_LITERAL -> + `'` + ( ~[`'` `\` LF CR TAB] | QUOTE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE ) + `'` SUFFIX? + +QUOTE_ESCAPE -> `\'` | `\"` + +ASCII_ESCAPE -> + `\x` OCT_DIGIT HEX_DIGIT + | `\n` | `\r` | `\t` | `\\` | `\0` + +UNICODE_ESCAPE -> + `\u{` ( HEX_DIGIT `_`* ){1..=6} _valid hex char value_ `}`[^valid-hex-char] +``` + +[^valid-hex-char]: See [lex.token.literal.char-escape.unicode]. + +r[lex.token.literal.char.intro] +A _character literal_ is a single Unicode character enclosed within two `U+0027` (single-quote) characters, with the exception of `U+0027` itself, which must be _escaped_ by a preceding `U+005C` character (`\`). + +r[lex.token.literal.str] +#### String literals + +r[lex.token.literal.str.syntax] +```grammar,lexer +STRING_LITERAL -> + `"` ( + ~[`"` `\` CR] + | QUOTE_ESCAPE + | ASCII_ESCAPE + | UNICODE_ESCAPE + | STRING_CONTINUE + )* `"` SUFFIX? + +STRING_CONTINUE -> `\` LF [TAB LF CR SP]* +``` + +r[lex.token.literal.str.intro] +A _string literal_ is a sequence of any Unicode characters enclosed within two `U+0022` (double-quote) characters, with the exception of `U+0022` itself, which must be _escaped_ by a preceding `U+005C` character (`\`). + +r[lex.token.literal.str.linefeed] +Line-breaks, represented by the character `U+000A` (LF), are allowed in string literals. The character `U+000D` (CR) may not appear in a string literal. When an unescaped `U+005C` character (`\`) occurs immediately before a line break, the line break does not appear in the string represented by the token. See [String continuation escapes] for details. + +r[lex.token.literal.char-escape] +#### Character escapes + +r[lex.token.literal.char-escape.intro] +Some additional _escapes_ are available in either character or non-raw string literals. An escape starts with a `U+005C` (`\`) and continues with one of the following forms: + +r[lex.token.literal.char-escape.ascii] +* A _7-bit code point escape_ starts with `U+0078` (`x`) and is followed by exactly two _hex digits_ with value up to `0x7F`. It denotes the ASCII character with value equal to the provided hex value. Higher values are not permitted because it is ambiguous whether they mean Unicode code points or byte values. + +r[lex.token.literal.char-escape.unicode] +* A _24-bit code point escape_ starts with `U+0075` (`u`) and is followed by up to six _hex digits_ surrounded by braces `U+007B` (`{`) and `U+007D` (`}`). It denotes the Unicode code point equal to the provided hex value. The value must be a valid Unicode scalar value. + +r[lex.token.literal.char-escape.whitespace] +* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072` (`r`), or `U+0074` (`t`), denoting the Unicode values `U+000A` (LF), `U+000D` (CR) or `U+0009` (HT) respectively. + +r[lex.token.literal.char-escape.null] +* The _null escape_ is the character `U+0030` (`0`) and denotes the Unicode value `U+0000` (NUL). + +r[lex.token.literal.char-escape.slash] +* The _backslash escape_ is the character `U+005C` (`\`) which must be escaped in order to denote itself. + +r[lex.token.literal.str-raw] +#### Raw string literals + +r[lex.token.literal.str-raw.syntax] +```grammar,lexer +RAW_STRING_LITERAL -> + `r` `"` ^ RAW_STRING_CONTENT `"` SUFFIX? + | `r` `#`{n:1..=255} ^ `"` RAW_STRING_CONTENT_HASHED `"` `#`{n} SUFFIX? + +RAW_STRING_CONTENT -> (!`"` ~CR )* + +RAW_STRING_CONTENT_HASHED -> (!(`"` `#`{n}) ~CR )* +``` + +r[lex.token.literal.str-raw.intro] +Raw string literals do not process any escapes. They start with the character `U+0072` (`r`), followed by fewer than 256 of the character `U+0023` (`#`) and a `U+0022` (double-quote) character. + +r[lex.token.literal.str-raw.body] +The _raw string body_ can contain any sequence of Unicode characters other than `U+000D` (CR). It is terminated only by another `U+0022` (double-quote) character, followed by the same number of `U+0023` (`#`) characters that preceded the opening `U+0022` (double-quote) character. + +r[lex.token.literal.str-raw.content] +All Unicode characters contained in the raw string body represent themselves, the characters `U+0022` (double-quote) (except when followed by at least as many `U+0023` (`#`) characters as were used to start the raw string literal) or `U+005C` (`\`) do not have any special meaning. + +Examples for string literals: + +```rust +"foo"; r"foo"; // foo +"\"foo\""; r#""foo""#; // "foo" + +"foo #\"# bar"; +r##"foo #"# bar"##; // foo #"# bar + +"\x52"; "R"; r"R"; // R +"\\x52"; r"\x52"; // \x52 +``` + +### Byte and byte string literals + +r[lex.token.byte] +#### Byte literals + +r[lex.token.byte.syntax] +```grammar,lexer +BYTE_LITERAL -> + `b'` ^ ( ASCII_FOR_CHAR | BYTE_ESCAPE ) `'` SUFFIX? + +ASCII_FOR_CHAR -> ![`'` `\` LF CR TAB] ASCII + +BYTE_ESCAPE -> + `\x` HEX_DIGIT HEX_DIGIT + | `\n` | `\r` | `\t` | `\\` | `\0` | `\'` | `\"` +``` + +r[lex.token.byte.intro] +A _byte literal_ is a single ASCII character (in the `U+0000` to `U+007F` range) or a single _escape_ preceded by the characters `U+0062` (`b`) and `U+0027` (single-quote), and followed by the character `U+0027`. If the character `U+0027` is present within the literal, it must be _escaped_ by a preceding `U+005C` (`\`) character. It is equivalent to a `u8` unsigned 8-bit integer _number literal_. + +r[lex.token.str-byte] +#### Byte string literals + +r[lex.token.str-byte.syntax] +```grammar,lexer +BYTE_STRING_LITERAL -> + `b"` ^ ( ASCII_FOR_STRING | BYTE_ESCAPE | STRING_CONTINUE )* `"` SUFFIX? + +ASCII_FOR_STRING -> ![`"` `\` CR] ASCII +``` + +r[lex.token.str-byte.intro] +A non-raw _byte string literal_ is a sequence of ASCII characters and _escapes_, preceded by the characters `U+0062` (`b`) and `U+0022` (double-quote), and followed by the character `U+0022`. If the character `U+0022` is present within the literal, it must be _escaped_ by a preceding `U+005C` (`\`) character. Alternatively, a byte string literal can be a _raw byte string literal_, defined below. + +r[lex.token.str-byte.linefeed] +Line-breaks, represented by the character `U+000A` (LF), are allowed in byte string literals. The character `U+000D` (CR) may not appear in a byte string literal. When an unescaped `U+005C` character (`\`) occurs immediately before a line break, the line break does not appear in the string represented by the token. See [String continuation escapes] for details. + +r[lex.token.str-byte.escape] +Some additional _escapes_ are available in either byte or non-raw byte string literals. An escape starts with a `U+005C` (`\`) and continues with one of the following forms: + +r[lex.token.str-byte.escape-byte] +* A _byte escape_ escape starts with `U+0078` (`x`) and is followed by exactly two _hex digits_. It denotes the byte equal to the provided hex value. + +r[lex.token.str-byte.escape-whitespace] +* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072` (`r`), or `U+0074` (`t`), denoting the bytes values `0x0A` (ASCII LF), `0x0D` (ASCII CR) or `0x09` (ASCII HT) respectively. + +r[lex.token.str-byte.escape-null] +* The _null escape_ is the character `U+0030` (`0`) and denotes the byte value `0x00` (ASCII NUL). + +r[lex.token.str-byte.escape-slash] +* The _backslash escape_ is the character `U+005C` (`\`) which must be escaped in order to denote its ASCII encoding `0x5C`. + +r[lex.token.str-byte-raw] +#### Raw byte string literals + +r[lex.token.str-byte-raw.syntax] +```grammar,lexer +RAW_BYTE_STRING_LITERAL -> + `br` `"` ^ RAW_BYTE_STRING_CONTENT `"` SUFFIX? + | `br` `#`{n:1..=255} ^ `"` RAW_BYTE_STRING_CONTENT_HASHED `"` `#`{n} SUFFIX? + +RAW_BYTE_STRING_CONTENT -> (!`"` ASCII_FOR_RAW )* + +RAW_BYTE_STRING_CONTENT_HASHED -> (!(`"` `#`{n}) ASCII_FOR_RAW )* + +ASCII_FOR_RAW -> !CR ASCII +``` + +r[lex.token.str-byte-raw.intro] +Raw byte string literals do not process any escapes. They start with the character `U+0062` (`b`), followed by `U+0072` (`r`), followed by fewer than 256 of the character `U+0023` (`#`), and a `U+0022` (double-quote) character. + +r[lex.token.str-byte-raw.body] +The _raw string body_ can contain any sequence of ASCII characters other than `U+000D` (CR). It is terminated only by another `U+0022` (double-quote) character, followed by the same number of `U+0023` (`#`) characters that preceded the opening `U+0022` (double-quote) character. A raw byte string literal can not contain any non-ASCII byte. + +r[lex.token.literal.str-byte-raw.content] +All characters contained in the raw string body represent their ASCII encoding, the characters `U+0022` (double-quote) (except when followed by at least as many `U+0023` (`#`) characters as were used to start the raw string literal) or `U+005C` (`\`) do not have any special meaning. + +Examples for byte string literals: + +```rust +b"foo"; br"foo"; // foo +b"\"foo\""; br#""foo""#; // "foo" + +b"foo #\"# bar"; +br##"foo #"# bar"##; // foo #"# bar + +b"\x52"; b"R"; br"R"; // R +b"\\x52"; br"\x52"; // \x52 +``` + +### C string and raw C string literals + +r[lex.token.str-c] +#### C string literals + +r[lex.token.str-c.syntax] +```grammar,lexer +C_STRING_LITERAL -> + `c"` ^ ( + ~[`"` `\` CR NUL] + | !(`\0` | `\x00`) BYTE_ESCAPE + | !(`\u{` (`0` `_`*){1..=6} `}`) UNICODE_ESCAPE + | STRING_CONTINUE + )* `"` SUFFIX? +``` + +r[lex.token.str-c.intro] +A _C string literal_ is a sequence of Unicode characters and _escapes_, preceded by the characters `U+0063` (`c`) and `U+0022` (double-quote), and followed by the character `U+0022`. If the character `U+0022` is present within the literal, it must be _escaped_ by a preceding `U+005C` (`\`) character. Alternatively, a C string literal can be a _raw C string literal_, defined below. + +[CStr]: core::ffi::CStr + +r[lex.token.str-c.null] +C strings are implicitly terminated by byte `0x00`, so the C string literal `c""` is equivalent to manually constructing a `&CStr` from the byte string literal `b"\x00"`. Other than the implicit terminator, byte `0x00` is not permitted within a C string. + +r[lex.token.str-c.linefeed] +Line-breaks, represented by the character `U+000A` (LF), are allowed in C string literals. The character `U+000D` (CR) may not appear in a C string literal. When an unescaped `U+005C` character (`\`) occurs immediately before a line break, the line break does not appear in the string represented by the token. See [String continuation escapes] for details. + +r[lex.token.str-c.escape] +Some additional _escapes_ are available in non-raw C string literals. An escape starts with a `U+005C` (`\`) and continues with one of the following forms: + +r[lex.token.str-c.escape-byte] +* A _byte escape_ escape starts with `U+0078` (`x`) and is followed by exactly two _hex digits_. It denotes the byte equal to the provided hex value. + +r[lex.token.str-c.escape-unicode] +* A _24-bit code point escape_ starts with `U+0075` (`u`) and is followed by up to six _hex digits_ surrounded by braces `U+007B` (`{`) and `U+007D` (`}`). It denotes the Unicode code point equal to the provided hex value, encoded as UTF-8. + +r[lex.token.str-c.escape-whitespace] +* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072` (`r`), or `U+0074` (`t`), denoting the bytes values `0x0A` (ASCII LF), `0x0D` (ASCII CR) or `0x09` (ASCII HT) respectively. + +r[lex.token.str-c.escape-slash] +* The _backslash escape_ is the character `U+005C` (`\`) which must be escaped in order to denote its ASCII encoding `0x5C`. + +r[lex.token.str-c.char-unicode] +A C string represents bytes with no defined encoding, but a C string literal may contain Unicode characters above `U+007F`. Such characters will be replaced with the bytes of that character's UTF-8 representation. + +The following C string literals are equivalent: + +```rust +c"æ"; // LATIN SMALL LETTER AE (U+00E6) +c"\u{00E6}"; +c"\xC3\xA6"; +``` + +r[lex.token.str-c.edition2021] +> [!EDITION-2021] +> C string literals are accepted in the 2021 edition or later. In earlier editions the token `c""` is lexed as `c ""`. + +r[lex.token.str-c-raw] +#### Raw C string literals + +r[lex.token.str-c-raw.syntax] +```grammar,lexer +RAW_C_STRING_LITERAL -> + `cr` `"` ^ RAW_C_STRING_CONTENT `"` SUFFIX? + | `cr` `#`{n:1..=255} ^ `"` RAW_C_STRING_CONTENT_HASHED `"` `#`{n} SUFFIX? + +RAW_C_STRING_CONTENT -> (!`"` ~[CR NUL] )* + +RAW_C_STRING_CONTENT_HASHED -> (!(`"` `#`{n}) ~[CR NUL] )* +``` + +r[lex.token.str-c-raw.intro] +Raw C string literals do not process any escapes. They start with the character `U+0063` (`c`), followed by `U+0072` (`r`), followed by fewer than 256 of the character `U+0023` (`#`), and a `U+0022` (double-quote) character. + +r[lex.token.str-c-raw.body] +The _raw C string body_ can contain any sequence of Unicode characters other than `U+0000` (NUL) and `U+000D` (CR). It is terminated only by another `U+0022` (double-quote) character, followed by the same number of `U+0023` (`#`) characters that preceded the opening `U+0022` (double-quote) character. + +r[lex.token.str-c-raw.content] +All characters contained in the raw C string body represent themselves in UTF-8 encoding. The characters `U+0022` (double-quote) (except when followed by at least as many `U+0023` (`#`) characters as were used to start the raw C string literal) or `U+005C` (`\`) do not have any special meaning. + +r[lex.token.str-c-raw.edition2021] +> [!EDITION-2021] +> Raw C string literals are accepted in the 2021 edition or later. In earlier editions the token `cr""` is lexed as `cr ""`, and `cr#""#` is lexed as `cr #""#` (which is non-grammatical). + +#### Examples for C string and raw C string literals + +```rust +c"foo"; cr"foo"; // foo +c"\"foo\""; cr#""foo""#; // "foo" + +c"foo #\"# bar"; +cr##"foo #"# bar"##; // foo #"# bar + +c"\x52"; c"R"; cr"R"; // R +c"\\x52"; cr"\x52"; // \x52 +``` + +r[lex.token.literal.num] +### Number literals + +A _number literal_ is either an _integer literal_ or a _floating-point literal_. The grammar for recognizing the two kinds of literals is mixed. + +r[lex.token.literal.int] +#### Integer literals + +r[lex.token.literal.int.syntax] +```grammar,lexer +INTEGER_LITERAL -> + ( BIN_LITERAL | OCT_LITERAL | HEX_LITERAL | DEC_LITERAL ) + ^ !RESERVED_FLOAT SUFFIX? + +DEC_LITERAL -> DEC_DIGIT (DEC_DIGIT|`_`)* + +BIN_LITERAL -> `0b` ^ `_`* BIN_DIGIT (BIN_DIGIT|`_`)* ![`e` `E` `2`-`9`] + +OCT_LITERAL -> `0o` ^ `_`* OCT_DIGIT (OCT_DIGIT|`_`)* ![`e` `E` `8`-`9`] + +HEX_LITERAL -> `0x` ^ `_`* HEX_DIGIT (HEX_DIGIT|`_`)* + +BIN_DIGIT -> [`0`-`1`] + +OCT_DIGIT -> [`0`-`7`] + +DEC_DIGIT -> [`0`-`9`] + +HEX_DIGIT -> [`0`-`9` `a`-`f` `A`-`F`] + +RESERVED_FLOAT -> `.` !(`.` | `_` | XID_Start) +``` + +r[lex.token.literal.int.kind] +An _integer literal_ has one of four forms: + +r[lex.token.literal.int.kind-dec] +* A _decimal literal_ starts with a *decimal digit* and continues with any mixture of *decimal digits* and _underscores_. + +r[lex.token.literal.int.kind-hex] +* A _hex literal_ starts with the character sequence `U+0030` `U+0078` (`0x`) and continues as any mixture (with at least one digit) of hex digits and underscores. + +r[lex.token.literal.int.kind-oct] +* An _octal literal_ starts with the character sequence `U+0030` `U+006F` (`0o`) and continues as any mixture (with at least one digit) of octal digits and underscores. + +r[lex.token.literal.int.kind-bin] +* A _binary literal_ starts with the character sequence `U+0030` `U+0062` (`0b`) and continues as any mixture (with at least one digit) of binary digits and underscores. + +r[lex.token.literal.int.suffix] +Like any literal, an integer literal may be followed (immediately, without any spaces) by a suffix as described above. The suffix may not begin with `e` or `E`, as that would be interpreted as the exponent of a floating-point literal. See [Integer literal expressions] for the effect of these suffixes. + +Examples of integer literals which are accepted as literal expressions: + +```rust +# #![allow(overflowing_literals)] +123; +123i32; +123u32; +123_u32; + +0xff; +0xff_u8; +0x01_f32; // integer 7986, not floating-point 1.0 +0x01_e3; // integer 483, not floating-point 1000.0 + +0o70; +0o70_i16; + +0b1111_1111_1001_0000; +0b1111_1111_1001_0000i64; +0b________1; + +0usize; + +// These are too big for their type, but are accepted as literal expressions. +128_i8; +256_u8; + +// This is an integer literal, accepted as a floating-point literal expression. +5f32; +``` + +Note that `-1i8`, for example, is analyzed as two tokens: `-` followed by `1i8`. + +Examples of integer literals which are not accepted as literal expressions: + +```rust +# #[cfg(false)] { +0invalidSuffix; +123AFB43; +0b010a; +0xAB_CD_EF_GH; +0b1111_f32; +# } +``` + +r[lex.token.literal.int.invalid] +##### Invalid integer literals + +r[lex.token.literal.int.invalid.intro] +Certain integer literal forms are invalid. To avoid ambiguity, the tokenizer rejects them rather than splitting them into separate tokens. + +```rust,compile_fail +0b0102; // This is not `0b010` followed by `2`. +0o1279; // This is not `0o127` followed by `9`. +0x80.0; // This is not `0x80` followed by `.` and `0`. +0b101e; // This is not a suffixed literal or `0b101` followed by `e`. +0b; // This is not an integer literal or `0` followed by `b`. +0b_; // This is not an integer literal or `0` followed by `b_`. +2em; // This is not a suffixed literal or `2` followed by `em`. +2.0em; // This is not a suffixed literal or `2.0` followed by `em`. +``` + +r[lex.token.literal.int.out-of-range] +It is an error to have an unsuffixed binary or octal literal followed without intervening whitespace by a decimal digit outside the range for its radix. + +r[lex.token.literal.int.period] +It is an error to have an unsuffixed binary, octal, or hexadecimal literal followed without intervening whitespace by a period character (subject to the same restrictions on what may follow the period as in floating-point literals). + +r[lex.token.literal.int.exp] +It is an error to have an unsuffixed binary or octal literal followed without intervening whitespace by the character `e` or `E`. + +r[lex.token.literal.int.empty-with-radix] +It is an error for a radix prefix to not be followed, after any optional leading underscores, by at least one valid digit for its radix. + +r[lex.token.literal.int.tuple-field] +#### Tuple index + +r[lex.token.literal.int.tuple-field.syntax] +```grammar,lexer +TUPLE_INDEX -> DEC_LITERAL | BIN_LITERAL | OCT_LITERAL | HEX_LITERAL +``` + +r[lex.token.literal.int.tuple-field.intro] +A tuple index is used to refer to the fields of [tuples], [tuple structs], and [tuple enum variants]. + +r[lex.token.literal.int.tuple-field.eq] +Tuple indices are compared with the literal token directly. Tuple indices start with `0` and each successive index increments the value by `1` as a decimal value. Thus, only decimal values will match, and the value must not have any extra `0` prefix characters. + +Tuple indices may not include any suffixes (such as `usize`). + +```rust,compile_fail +let example = ("dog", "cat", "horse"); +let dog = example.0; +let cat = example.1; +// The following examples are invalid. +let cat = example.01; // ERROR no field named `01` +let horse = example.0b10; // ERROR no field named `0b10` +let unicorn = example.0usize; // ERROR suffixes on a tuple index are invalid +let underscore = example.0_0; // ERROR no field `0_0` on type `(&str, &str, &str)` +``` + +r[lex.token.literal.float] +#### Floating-point literals + +r[lex.token.literal.float.syntax] +```grammar,lexer +FLOAT_LITERAL -> + DEC_LITERAL (`.` DEC_LITERAL)? FLOAT_EXPONENT SUFFIX? + | DEC_LITERAL `.` DEC_LITERAL SUFFIX? + | DEC_LITERAL `.` !(`.` | `_` | XID_Start) + +FLOAT_EXPONENT -> + (`e`|`E`) ^ (`+`|`-`)? `_`* DEC_DIGIT (DEC_DIGIT|`_`)* +``` + +r[lex.token.literal.float.form] +A _floating-point literal_ has one of two forms: + +* A _decimal literal_ followed by a period character `U+002E` (`.`). This is optionally followed by another decimal literal, with an optional _exponent_. +* A single _decimal literal_ followed by an _exponent_. + +r[lex.token.literal.float.suffix] +Like integer literals, a floating-point literal may be followed by a suffix, so long as the pre-suffix part does not end with `U+002E` (`.`). The suffix may not begin with `e` or `E` if the literal does not include an exponent. See [Floating-point literal expressions] for the effect of these suffixes. + +Examples of floating-point literals which are accepted as literal expressions: + +```rust +123.0f64; +0.1f64; +0.1f32; +12E+99_f64; +let x: f64 = 2.; +``` + +This last example is different because it is not possible to use the suffix syntax with a floating point literal ending in a period. `2.f64` would attempt to call a method named `f64` on `2`. + +Note that `-1.0`, for example, is analyzed as two tokens: `-` followed by `1.0`. + +Examples of floating-point literals which are not accepted as literal expressions: + +```rust +# #[cfg(false)] { +2.0f80; +2e5f80; +2e5e6; +2.0e5e6; +1.3e10u64; +# } +``` + +r[lex.token.literal.float.invalid-exponent] +It is an error for a floating-point literal to have an exponent with no digits. + +```rust,compile_fail +2e; // This is not a floating-point literal or `2` followed by `e`. +2.0e; // This is not a floating-point literal or `2.0` followed by `e`. +``` + +r[lex.token.life] +## Lifetimes and loop labels + +r[lex.token.life.syntax] +```grammar,lexer +LIFETIME_TOKEN -> + RAW_LIFETIME + | `'` IDENTIFIER_OR_KEYWORD !`'` + +LIFETIME_OR_LABEL -> + RAW_LIFETIME + | `'` NON_KEYWORD_IDENTIFIER !`'` + +RAW_LIFETIME -> + `'r#` ^ IDENTIFIER_OR_KEYWORD !`'` + +RESERVED_RAW_LIFETIME -> `'r#` (`_` | `crate` | `self` | `Self` | `super`) !(`'` | XID_Continue) +``` + +r[lex.token.life.intro] +Lifetime parameters and [loop labels] use LIFETIME_OR_LABEL tokens. Any LIFETIME_TOKEN will be accepted by the lexer, and for example, can be used in macros. + +r[lex.token.life.raw.intro] +A raw lifetime is like a normal lifetime, but its identifier is prefixed by `r#`. (Note that the `r#` prefix is not included as part of the actual lifetime.) + +r[lex.token.life.raw.allowed] +Unlike a normal lifetime, a raw lifetime may be any strict or reserved keyword except the ones listed above for `RAW_LIFETIME`. + +r[lex.token.life.raw.reserved] +It is an error to use the [RESERVED_RAW_LIFETIME] token. + +r[lex.token.life.raw.edition2021] +> [!EDITION-2021] +> Raw lifetimes are accepted in the 2021 edition or later. In earlier editions the token `'r#lt` is lexed as `'r # lt`. + +r[lex.token.punct] +## Punctuation + +r[lex.token.punct.intro] +Punctuation tokens are used as operators, separators, and other parts of the grammar. + +r[lex.token.punct.syntax] +```grammar,lexer +PUNCTUATION -> + `...` + | `..=` + | `<<=` + | `>>=` + | `!=` + | `%=` + | `&&` + | `&=` + | `*=` + | `+=` + | `-=` + | `->` + | `..` + | `/=` + | `::` + | `<-` + | `<<` + | `<=` + | `==` + | `=>` + | `>=` + | `>>` + | `^=` + | `|=` + | `||` + | `!` + | `#` + | `$` + | `%` + | `&` + | `(` + | `)` + | `*` + | `+` + | `,` + | `-` + | `.` + | `/` + | `:` + | `;` + | `<` + | `=` + | `>` + | `?` + | `@` + | `[` + | `]` + | `^` + | `{` + | `|` + | `}` + | `~` +``` + +> [!NOTE] +> See the [syntax index] for links to how punctuation characters are used. + +r[lex.token.delim] +## Delimiters + +Bracket punctuation is used in various parts of the grammar. An open bracket must always be paired with a close bracket. Brackets and the tokens within them are referred to as "token trees" in [macros]. The three types of brackets are: + +| Bracket | Type | +|---------|-----------------| +| `{` `}` | Curly braces | +| `[` `]` | Square brackets | +| `(` `)` | Parentheses | + +r[lex.token.reserved] +## Reserved tokens + +r[lex.token.reserved.intro] +Several token forms are reserved for future use or to avoid confusion. It is an error for the source input to match one of these forms. + +r[lex.token.reserved.syntax] +```grammar,lexer +RESERVED_TOKEN -> + RESERVED_GUARDED_STRING_LITERAL + | RESERVED_POUNDS + | RESERVED_RAW_IDENTIFIER + | RESERVED_RAW_LIFETIME + | RESERVED_TOKEN_DOUBLE_QUOTE + | RESERVED_TOKEN_LIFETIME + | RESERVED_TOKEN_POUND + | RESERVED_TOKEN_SINGLE_QUOTE +``` + +r[lex.token.reserved-prefix] +## Reserved prefixes + +r[lex.token.reserved-prefix.syntax] +```grammar,lexer +RESERVED_TOKEN_DOUBLE_QUOTE -> + IDENTIFIER_OR_KEYWORD _except `b` or `c` or `r` or `br` or `cr`_ `"` + +RESERVED_TOKEN_SINGLE_QUOTE -> + IDENTIFIER_OR_KEYWORD _except `b`_ `'` + +RESERVED_TOKEN_POUND -> + IDENTIFIER_OR_KEYWORD _except `r` or `br` or `cr`_ `#` + +RESERVED_TOKEN_LIFETIME -> + `'` IDENTIFIER_OR_KEYWORD _except `r`_ `#` +``` + +r[lex.token.reserved-prefix.intro] +Some lexical forms known as _reserved prefixes_ are reserved for future use. + +r[lex.token.reserved-prefix.id] +Source input which would otherwise be lexically interpreted as a non-raw identifier (or a keyword) which is immediately followed by a `#`, `'`, or `"` character (without intervening whitespace) is identified as a reserved prefix. + +r[lex.token.reserved-prefix.raw-token] +Note that raw identifiers, raw string literals, and raw byte string literals may contain a `#` character but are not interpreted as containing a reserved prefix. + +r[lex.token.reserved-prefix.strings] +Similarly the `r`, `b`, `br`, `c`, and `cr` prefixes used in raw string literals, byte literals, byte string literals, raw byte string literals, C string literals, and raw C string literals are not interpreted as reserved prefixes. + +r[lex.token.reserved-prefix.life] +Source input which would otherwise be lexically interpreted as a non-raw lifetime (or a keyword) which is immediately followed by a `#` character (without intervening whitespace) is identified as a reserved lifetime prefix. + +r[lex.token.reserved-prefix.edition2021] +> [!EDITION-2021] +> Starting with the 2021 edition, reserved prefixes are reported as an error by the lexer (in particular, they cannot be passed to macros). +> +> Before the 2021 edition, reserved prefixes are accepted by the lexer and interpreted as multiple tokens (for example, one token for the identifier or keyword, followed by a `#` token). +> +> Examples accepted in all editions: +> ```rust +> macro_rules! lexes {($($_:tt)*) => {}} +> lexes!{a #foo} +> lexes!{continue 'foo} +> lexes!{match "..." {}} +> lexes!{r#let#foo} // three tokens: r#let # foo +> lexes!{'prefix #lt} +> ``` +> +> Examples accepted before the 2021 edition but rejected later: +> ```rust,edition2018 +> macro_rules! lexes {($($_:tt)*) => {}} +> lexes!{a#foo} +> lexes!{continue'foo} +> lexes!{match"..." {}} +> lexes!{'prefix#lt} +> ``` + +r[lex.token.reserved-guards] +## Reserved guards + +r[lex.token.reserved-guards.syntax] +```grammar,lexer +RESERVED_GUARDED_STRING_LITERAL -> `#`+ STRING_LITERAL + +RESERVED_POUNDS -> `#`{2..} +``` + +r[lex.token.reserved-guards.intro] +The reserved guards are syntax reserved for future use, and will generate a compile error if used. + +r[lex.token.reserved-guards.string-literal] +The *reserved guarded string literal* is a token of one or more `U+0023` (`#`) immediately followed by a [STRING_LITERAL]. + +r[lex.token.reserved-guards.pounds] +The *reserved pounds* is a token of two or more `U+0023` (`#`). + +r[lex.token.reserved-guards.edition2024] +> [!EDITION-2024] +> Before the 2024 edition, reserved guards are accepted by the lexer and interpreted as multiple tokens. For example, the `#"foo"#` form is interpreted as three tokens. `##` is interpreted as two tokens. + +[Floating-point literal expressions]: expressions/literal-expr.md#floating-point-literal-expressions +[identifier]: identifiers.md +[Integer literal expressions]: expressions/literal-expr.md#integer-literal-expressions +[keywords]: keywords.md +[literal expressions]: expressions/literal-expr.md +[loop labels]: expressions/loop-expr.md#loop-labels +[macros]: macros-by-example.md +[String continuation escapes]: expressions/literal-expr.md#string-continuation-escapes +[syntax index]: syntax-index.md#operators-and-punctuation +[tuple structs]: items/structs.md +[tuple enum variants]: items/enumerations.md +[tuples]: types/tuple.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/trait-bounds.md b/stdlib/kvlang/reference/rust/reference-repo/src/trait-bounds.md new file mode 100644 index 00000000..6a5b870c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/trait-bounds.md @@ -0,0 +1,254 @@ +r[bound] +# Trait and lifetime bounds + +r[bound.syntax] +```grammar,miscellaneous +Bounds -> Bound ( `+` Bound )* `+`? + +Bound -> Lifetime | TraitBound | UseBound + +TraitBound -> + ( `?` | ForLifetimes )? TypePath + | `(` ( `?` | ForLifetimes )? TypePath `)` + +LifetimeBounds -> ( Lifetime `+` )* Lifetime? + +Lifetime -> + LIFETIME_OR_LABEL + | `'static` + | `'_` + +UseBound -> `use` UseBoundGenericArgs + +UseBoundGenericArgs -> + `<` `>` + | `<` ( UseBoundGenericArg `,`)* UseBoundGenericArg `,`? `>` + +UseBoundGenericArg -> + Lifetime + | IDENTIFIER + | `Self` +``` + +r[bound.intro] +[Trait] and lifetime bounds provide a way for [generic items][generic] to restrict which types and lifetimes are used as their parameters. Bounds can be provided on any type in a [where clause]. There are also shorter forms for certain common cases: + +* Bounds written after declaring a [generic parameter][generic]: `fn f<A: Copy>() {}` is the same as `fn f<A>() where A: Copy {}`. +* In trait declarations as [supertraits]: `trait Circle : Shape {}` is equivalent to `trait Circle where Self : Shape {}`. +* In trait declarations as bounds on [associated types]: `trait A { type B: Copy; }` is equivalent to `trait A where Self::B: Copy { type B; }`. + +r[bound.satisfaction] +Bounds on an item must be satisfied when using the item. When type checking and borrow checking a generic item, the bounds can be used to determine that a trait is implemented for a type. For example, given `Ty: Trait` + +* In the body of a generic function, methods from `Trait` can be called on `Ty` values. Likewise associated constants on the `Trait` can be used. +* Associated types from `Trait` can be used. +* Generic functions and types with a `T: Trait` bounds can be used with `Ty` being used for `T`. + +```rust +# type Surface = i32; +trait Shape { + fn draw(&self, surface: Surface); + fn name() -> &'static str; +} + +fn draw_twice<T: Shape>(surface: Surface, sh: T) { + sh.draw(surface); // Can call method because T: Shape + sh.draw(surface); +} + +fn copy_and_draw_twice<T: Copy>(surface: Surface, sh: T) where T: Shape { + let shape_copy = sh; // doesn't move sh because T: Copy + draw_twice(surface, sh); // Can use generic function because T: Shape +} + +struct Figure<S: Shape>(S, S); + +fn name_figure<U: Shape>( + figure: Figure<U>, // Type Figure<U> is well-formed because U: Shape +) { + println!( + "Figure of two {}", + U::name(), // Can use associated function + ); +} +``` + +r[bound.trivial] +Bounds that don't use the item's parameters or [higher-ranked lifetimes] are checked when the item is defined. It is an error for such a bound to be false. + +r[bound.special] +[`Copy`], [`Clone`], and [`Sized`] bounds are also checked for certain generic types when using the item, even if the use does not provide a concrete type. It is an error to have `Copy` or `Clone` as a bound on a mutable reference, [trait object], or [slice]. It is an error to have `Sized` as a bound on a trait object or slice. + +```rust,compile_fail +struct A<'a, T> +where + i32: Default, // Allowed, but not useful + i32: Iterator, // Error: `i32` is not an iterator + &'a mut T: Copy, // (at use) Error: the trait bound is not satisfied + [T]: Sized, // (at use) Error: size cannot be known at compilation +{ + f: &'a T, +} +struct UsesA<'a, T>(A<'a, T>); +``` + +r[bound.trait-object] +Trait and lifetime bounds are also used to name [trait objects]. + +r[bound.sized] +## `?Sized` + +`?` is only used to relax the implicit [`Sized`] trait bound for [type parameters] or [associated types]. `?Sized` may not be used as a bound for other types. + +r[bound.lifetime] +## Lifetime bounds + +r[bound.lifetime.intro] +Lifetime bounds can be applied to types or to other lifetimes. + +r[bound.lifetime.outlive-lifetime] +The bound `'a: 'b` is usually read as `'a` *outlives* `'b`. `'a: 'b` means that `'a` lasts at least as long as `'b`, so a reference `&'a ()` is valid whenever `&'b ()` is valid. + +```rust +fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) where 'a: 'b { + y = x; // &'a i32 is a subtype of &'b i32 because 'a: 'b + let r: &'b &'a i32 = &&0; // &'b &'a i32 is well formed because 'a: 'b +} +``` + +r[bound.lifetime.outlive-type] +`T: 'a` means that all lifetime parameters of `T` outlive `'a`. For example, if `'a` is an unconstrained lifetime parameter, then `i32: 'static` and `&'static str: 'a` are satisfied, but `Vec<&'a ()>: 'static` is not. + +r[bound.higher-ranked] +## Higher-ranked trait bounds + +r[bound.higher-ranked.syntax] +```grammar,miscellaneous +ForLifetimes -> `for` GenericParams +``` + +r[bound.higher-ranked.intro] +Trait bounds may be *higher ranked* over lifetimes. These bounds specify a bound that is true *for all* lifetimes. For example, a bound such as `for<'a> &'a T: PartialEq<i32>` would require an implementation like + +```rust +# struct T; +impl<'a> PartialEq<i32> for &'a T { + // ... +# fn eq(&self, other: &i32) -> bool {true} +} +``` + +and could then be used to compare a `&'a T` with any lifetime to an `i32`. + +Only a higher-ranked bound can be used here, because the lifetime of the reference is shorter than any possible lifetime parameter on the function: + +```rust +fn call_on_ref_zero<F>(f: F) where for<'a> F: Fn(&'a i32) { + let zero = 0; + f(&zero); +} +``` + +r[bound.higher-ranked.trait] +Higher-ranked lifetimes may also be specified just before the trait: the only difference is the [scope][hrtb-scopes] of the lifetime parameter, which extends only to the end of the following trait instead of the whole bound. This function is equivalent to the last one. + +```rust +fn call_on_ref_zero<F>(f: F) where F: for<'a> Fn(&'a i32) { + let zero = 0; + f(&zero); +} +``` + +r[bound.implied] +## Implied bounds + +r[bound.implied.intro] +Lifetime bounds required for types to be well-formed are sometimes inferred. + +```rust +fn requires_t_outlives_a<'a, T>(x: &'a T) {} +``` + +The type parameter `T` is required to outlive `'a` for the type `&'a T` to be well-formed. This is inferred because the function signature contains the type `&'a T` which is only valid if `T: 'a` holds. + +r[bound.implied.context] +Implied bounds are added for all parameters and outputs of functions. Inside of `requires_t_outlives_a` you can assume `T: 'a` to hold even if you don't explicitly specify this: + +```rust +fn requires_t_outlives_a_not_implied<'a, T: 'a>() {} + +fn requires_t_outlives_a<'a, T>(x: &'a T) { + // This compiles, because `T: 'a` is implied by + // the reference type `&'a T`. + requires_t_outlives_a_not_implied::<'a, T>(); +} +``` + +```rust,compile_fail,E0309 +# fn requires_t_outlives_a_not_implied<'a, T: 'a>() {} +fn not_implied<'a, T>() { + // This errors, because `T: 'a` is not implied by + // the function signature. + requires_t_outlives_a_not_implied::<'a, T>(); +} +``` + +r[bound.implied.trait] +Only lifetime bounds are implied, trait bounds still have to be explicitly added. The following example therefore causes an error: + +```rust,compile_fail,E0277 +use std::fmt::Debug; +struct IsDebug<T: Debug>(T); +// error[E0277]: `T` doesn't implement `Debug` +fn doesnt_specify_t_debug<T>(x: IsDebug<T>) {} +``` + +r[bound.implied.def] +Lifetime bounds are also inferred for type definitions and impl blocks for any type: + +```rust +struct Struct<'a, T> { + // This requires `T: 'a` to be well-formed + // which is inferred by the compiler. + field: &'a T, +} + +enum Enum<'a, T> { + // This requires `T: 'a` to be well-formed, + // which is inferred by the compiler. + // + // Note that `T: 'a` is required even when only + // using `Enum::OtherVariant`. + SomeVariant(&'a T), + OtherVariant, +} + +trait Trait<'a, T: 'a> {} + +// This would error because `T: 'a` is not implied by any type +// in the impl header. +// impl<'a, T> Trait<'a, T> for () {} + +// This compiles as `T: 'a` is implied by the self type `&'a T`. +impl<'a, T> Trait<'a, T> for &'a T {} +``` + +r[bound.use] +## Use bounds + +Certain bounds lists may include a `use<..>` bound to control which generic parameters are captured by the `impl Trait` [abstract return type]. See [precise capturing] for more details. + +[abstract return type]: types/impl-trait.md#abstract-return-types +[arrays]: types/array.md +[associated types]: items/associated-items.md#associated-types +[hrtb-scopes]: names/scopes.md#higher-ranked-trait-bound-scopes +[supertraits]: items/traits.md#supertraits +[generic]: items/generics.md +[higher-ranked lifetimes]: #higher-ranked-trait-bounds +[precise capturing]: types/impl-trait.md#precise-capturing +[slice]: types/slice.md +[Trait]: items/traits.md#trait-bounds +[trait object]: types/trait-object.md +[trait objects]: types/trait-object.md +[type parameters]: types/parameters.md +[where clause]: items/generics.md#where-clauses diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/type-coercions.md b/stdlib/kvlang/reference/rust/reference-repo/src/type-coercions.md new file mode 100644 index 00000000..76b994d6 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/type-coercions.md @@ -0,0 +1,303 @@ +r[coerce] +# Type coercions + +r[coerce.intro] +**Type coercions** are implicit operations that change the type of a value. They happen automatically at specific locations and are highly restricted in what types actually coerce. + +r[coerce.as] +Any conversions allowed by coercion can also be explicitly performed by the [type cast operator], `as`. + +Coercions are originally defined in [RFC 401] and expanded upon in [RFC 1558]. + +r[coerce.site] +## Coercion sites + +r[coerce.site.intro] +A coercion can only occur at certain coercion sites in a program; these are typically places where the desired type is explicit or can be derived by propagation from explicit types (without type inference). Possible coercion sites are: + +r[coerce.site.let] +* `let` statements where an explicit type is given. + + For example, `&mut 42` is coerced to have type `&i8` in the following: + + ```rust + let _: &i8 = &mut 42; + ``` + +r[coerce.site.value] +* `static` and `const` item declarations (similar to `let` statements). + +r[coerce.site.argument] +* Arguments for function calls + + The value being coerced is the actual parameter, and it is coerced to the type of the formal parameter. + + For example, `&mut 42` is coerced to have type `&i8` in the following: + + ```rust + fn bar(_: &i8) { } + + fn main() { + bar(&mut 42); + } + ``` + + For method calls, the receiver (`self` parameter) type is coerced differently, see the documentation on [method-call expressions] for details. + +r[coerce.site.constructor] +* Instantiations of struct, union, or enum variant fields + + For example, `&mut 42` is coerced to have type `&i8` in the following: + + ```rust + struct Foo<'a> { x: &'a i8 } + + fn main() { + Foo { x: &mut 42 }; + } + ``` + +r[coerce.site.return] +* Function results—either the final line of a block if it is not semicolon-terminated or any expression in a `return` statement + + For example, `x` is coerced to have type `&dyn Display` in the following: + + ```rust + use std::fmt::Display; + fn foo(x: &u32) -> &dyn Display { + x + } + ``` + +r[coerce.site.assignment] +* Assigned value operands in assignment expressions + + For example, `y` is coerced to have type `&i8` in the following: + ```rust + let mut x = &0i8; + let y = &mut 42i8; + x = y; + ``` + +r[coerce.site.subexpr] +If the expression in one of these coercion sites is a coercion-propagating expression, then the relevant sub-expressions in that expression are also coercion sites. Propagation recurses from these new coercion sites. Propagating expressions and their relevant sub-expressions are: + +r[coerce.site.array] +* Array literals, where the array has type `[U; n]`. Each sub-expression in the array literal is a coercion site for coercion to type `U`. + +r[coerce.site.repeat] +* Array literals with repeating syntax, where the array has type `[U; n]`. The repeated sub-expression is a coercion site for coercion to type `U`. + +r[coerce.site.tuple] +* Tuples, where a tuple is a coercion site to type `(U_0, U_1, ..., U_n)`. Each sub-expression is a coercion site to the respective type, e.g. the zeroth sub-expression is a coercion site to type `U_0`. + +r[coerce.site.parenthesis] +* Parenthesized sub-expressions (`(e)`): if the expression has type `U`, then the sub-expression is a coercion site to `U`. + +r[coerce.site.block] +* Blocks: if a block has type `U`, then the last expression in the block (if it is not semicolon-terminated) is a coercion site to `U`. This includes blocks which are part of control flow statements, such as `if`/`else`, if the block has a known type. + +r[coerce.types] +## Coercion types + +r[coerce.types.intro] +Coercion is allowed between the following types: + +r[coerce.types.reflexive] +* `T` to `U` if `T` is a [subtype] of `U` (*reflexive case*) + +r[coerce.types.transitive] +* `T_1` to `T_3` where `T_1` coerces to `T_2` and `T_2` coerces to `T_3` (*transitive case*) + + Note that this is not fully supported yet. + +r[coerce.types.mut-reborrow] +* `&mut T` to `&T` + +r[coerce.types.mut-pointer] +* `*mut T` to `*const T` + +r[coerce.types.ref-to-pointer] +* `&T` to `*const T` + +r[coerce.types.mut-to-pointer] +* `&mut T` to `*mut T` + +r[coerce.types.deref] +* `&T` or `&mut T` to `&U` if `T` implements `Deref<Target = U>`. For example: + + ```rust + use std::ops::Deref; + + struct CharContainer { + value: char, + } + + impl Deref for CharContainer { + type Target = char; + + fn deref<'a>(&'a self) -> &'a char { + &self.value + } + } + + fn foo(arg: &char) {} + + fn main() { + let x = &mut CharContainer { value: 'y' }; + foo(x); //&mut CharContainer is coerced to &char. + } + ``` + +r[coerce.types.deref-mut] +* `&mut T` to `&mut U` if `T` implements `DerefMut<Target = U>`. + +r[coerce.types.unsize] +* TyCtor(`T`) to TyCtor(`U`), where TyCtor(`T`) is one of + - `&T` + - `&mut T` + - `*const T` + - `*mut T` + - `Box<T>` + + and where `U` can be obtained from `T` by [unsized coercion](#unsized-coercions). + + <!--In the future, coerce_inner will be recursively extended to tuples and + structs. In addition, coercions from subtraits to supertraits will be + added. See [RFC 401] for more details.--> + +r[coerce.types.fn] +* Function item types to `fn` pointers + +r[coerce.types.closure] +* Non capturing closures to `fn` pointers + +r[coerce.types.never] +* `!` to any `T` + +r[coerce.unsize] +### Unsized coercions + +r[coerce.unsize.intro] +The following coercions are called `unsized coercions`, since they relate to converting types to unsized types, and are permitted in a few cases where other coercions are not, as described above. They can still happen anywhere else a coercion can occur. + +r[coerce.unsize.trait] +Two traits, [`Unsize`] and [`CoerceUnsized`], are used to assist in this process and expose it for library use. The following coercions are built-ins and, if `T` can be coerced to `U` with one of them, then an implementation of `Unsize<U>` for `T` will be provided: + +r[coerce.unsize.slice] +* `[T; n]` to `[T]`. + +r[coerce.unsize.trait-object] +* `T` to `dyn U`, when `T` implements `U + Sized`, and `U` is [dyn compatible]. + +r[coerce.unsize.trait-upcast] +* `dyn T` to `dyn U`, when `U` is one of `T`'s [supertraits]. + * This allows dropping auto traits, i.e. `dyn T + Auto` to `dyn U` is allowed. + * This allows adding auto traits if the principal trait has the auto trait as a super trait, i.e. given `trait T: U + Send {}`, `dyn T` to `dyn T + Send` or to `dyn U + Send` coercions are allowed. + +r[coerce.unsized.composite] +* `Foo<..., T, ...>` to `Foo<..., U, ...>`, when: + * `Foo` is a struct. + * `T` implements `Unsize<U>`. + * The last field of `Foo` has a type involving `T`. + * If that field has type `Bar<T>`, then `Bar<T>` implements `Unsize<Bar<U>>`. + * T is not part of the type of any other fields. + +r[coerce.unsized.pointer] +Additionally, a type `Foo<T>` can implement `CoerceUnsized<Foo<U>>` when `T` implements `Unsize<U>` or `CoerceUnsized<Foo<U>>`. This allows it to provide an unsized coercion to `Foo<U>`. + +> [!NOTE] +> While the definition of the unsized coercions and their implementation has been stabilized, the traits themselves are not yet stable and therefore can't be used directly in stable Rust. + +r[coerce.least-upper-bound] +## Least upper bound coercions + +r[coerce.least-upper-bound.intro] +In some contexts, the compiler must coerce together multiple types to try and find the most general type. This is called a "Least Upper Bound" coercion. LUB coercion is used and only used in the following situations: + ++ To find the common type for a series of if branches. ++ To find the common type for a series of match arms. ++ To find the common type for array elements. ++ To find the common type for a [labeled block expression] among the break operands and the final block operand. ++ To find the common type for an [`loop` expression with break expressions] among the break operands. ++ To find the type for the return type of a closure with multiple return statements. ++ To check the type for the return type of a function with multiple return statements. + +r[coerce.least-upper-bound.target] +In each such case, there are a set of types `T0..Tn` to be mutually coerced to some target type `T_t`, which is unknown to start. + +r[coerce.least-upper-bound.computation] +Computing the LUB coercion is done iteratively. The target type `T_t` begins as the type `T0`. For each new type `Ti`, we consider whether + +r[coerce.least-upper-bound.computation-identity] ++ If `Ti` can be coerced to the current target type `T_t`, then no change is made. + +r[coerce.least-upper-bound.computation-replace] ++ Otherwise, check whether `T_t` can be coerced to `Ti`; if so, the `T_t` is changed to `Ti`. (This check is also conditioned on whether all of the source expressions considered thus far have implicit coercions.) + +r[coerce.least-upper-bound.computation-unify] ++ If not, try to compute a mutual supertype of `T_t` and `Ti`, which will become the new target type. + +### Examples: + +```rust +# let (a, b, c) = (0, 1, 2); +// For if branches +let bar = if true { + a +} else if false { + b +} else { + c +}; + +// For match arms +let baw = match 42 { + 0 => a, + 1 => b, + _ => c, +}; + +// For array elements +let bax = [a, b, c]; + +// For closure with multiple return statements +let clo = || { + if true { + a + } else if false { + b + } else { + c + } +}; +let baz = clo(); + +// For type checking of function with multiple return statements +fn foo() -> i32 { + let (a, b, c) = (0, 1, 2); + match 42 { + 0 => a, + 1 => b, + _ => c, + } +} +``` + +In these examples, types of the `ba*` are found by LUB coercion. And the compiler checks whether LUB coercion result of `a`, `b`, `c` is `i32` in the processing of the function `foo`. + +### Caveat + +This description is obviously informal. Making it more precise is expected to proceed as part of a general effort to specify the Rust type checker more precisely. + +[RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md +[RFC 1558]: https://github.com/rust-lang/rfcs/blob/master/text/1558-closure-to-fn-coercion.md +[subtype]: subtyping.md +[dyn compatible]: items/traits.md#dyn-compatibility +[type cast operator]: expressions/operator-expr.md#type-cast-expressions +[`Unsize`]: std::marker::Unsize +[`CoerceUnsized`]: std::ops::CoerceUnsized +[labeled block expression]: expr.loop.block-labels +[`loop` expression with break expressions]: expr.loop.break-value +[method-call expressions]: expressions/method-call-expr.md +[supertraits]: items/traits.md#supertraits diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/type-layout.md b/stdlib/kvlang/reference/rust/reference-repo/src/type-layout.md new file mode 100644 index 00000000..daec57f9 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/type-layout.md @@ -0,0 +1,726 @@ +r[layout] +# Type layout + +r[layout.intro] +The layout of a type is its size, alignment, and the relative offsets of its fields. For enums, how the discriminant is laid out and interpreted is also part of type layout. + +r[layout.guarantees] +Type layout can be changed with each compilation. Instead of trying to document exactly what is done, we only document what is guaranteed today. + +Note that even types with the same layout can still differ in how they are passed across function boundaries. For function call ABI compatibility of types, see [here][fn-abi-compatibility]. + +r[layout.properties] +## Size and alignment + +r[layout.properties.intro] +All values have an alignment and size. + +r[layout.properties.align] +The *alignment* of a value specifies what addresses are valid to store the value at. A value of alignment `n` must only be stored at an address that is a multiple of n. For example, a value with an alignment of 2 must be stored at an even address, while a value with an alignment of 1 can be stored at any address. Alignment is measured in bytes, and must be at least 1, and always a power of 2. The alignment of a value can be checked with the [`align_of_val`] function. + +r[layout.properties.size] +The *size* of a value is the offset in bytes between successive elements in an array with that item type including alignment padding. The size of a value is always a multiple of its alignment. Note that some types are [zero-sized]; 0 is considered a multiple of any alignment (for example, on some platforms, the type `[u16; 0]` has size 0 and alignment 2). The size of a value can be checked with the [`size_of_val`] function. + +r[layout.properties.sized] +Types where all values have the same size and alignment, and both are known at compile time, implement the [`Sized`] trait and can be checked with the [`size_of`] and [`align_of`] functions. Types that are not [`Sized`] are known as [dynamically sized types]. Since all values of a `Sized` type share the same size and alignment, we refer to those shared values as the size of the type and the alignment of the type respectively. + +r[layout.primitive] +## Primitive data layout + +r[layout.primitive.size] +The size of most primitives is given in this table. + +| Type | `size_of::<Type>()`| +|-- |-- | +| `bool` | 1 | +| `u8` / `i8` | 1 | +| `u16` / `i16` | 2 | +| `u32` / `i32` | 4 | +| `u64` / `i64` | 8 | +| `u128` / `i128` | 16 | +| `usize` / `isize` | See below | +| `f32` | 4 | +| `f64` | 8 | +| `char` | 4 | + +r[layout.primitive.size-minimum] +`usize` and `isize` have a size big enough to contain every address on the target platform. For example, on a 32 bit target, this is 4 bytes, and on a 64 bit target, this is 8 bytes. + +r[layout.primitive.size-align] +`usize` and `isize` have the same size and alignment. + +r[layout.primitive.platform-specific-alignment] +The alignment of primitives is platform-specific. In most cases, their alignment is equal to their size, but it may be less. In particular, `i128` and `u128` are often aligned to 4 or 8 bytes even though their size is 16, and on many 32-bit platforms, `i64`, `u64`, and `f64` are only aligned to 4 bytes, not 8. + +r[layout.primitive.integer-alignment] +Alignment is guaranteed to be the same for fixed-width signed and unsigned integer variants of the same indicated size --- that is, for a given size `N`, `align_of::<uN>() == align_of::<iN>()`. + +r[layout.pointer] +## Pointers and references layout + +r[layout.pointer.intro] +Pointers and references have the same layout. Mutability of the pointer or reference does not change the layout. + +r[layout.pointer.thin] +Pointers to sized types have the same size and alignment as `usize`. + +r[layout.pointer.unsized] +Pointers to unsized types are sized. The size and alignment of a pointer to an unsized type are each guaranteed to be greater than or equal to those of a pointer to a sized type. + +> [!NOTE] +> Though you should not rely on this, all pointers to <abbr title="Dynamically Sized Types">DSTs</abbr> are currently twice the size of the size of `usize` and have the same alignment. + +r[layout.array] +## Array layout + +An array of `[T; N]` has a size of `size_of::<T>() * N` and the same alignment of `T`. Arrays are laid out so that the zero-based `nth` element of the array is offset from the start of the array by `n * size_of::<T>()` bytes. + +r[layout.slice] +## Slice layout + +Slices have the same layout as the section of the array they slice. + +> [!NOTE] +> This is about the raw `[T]` type, not pointers (`&[T]`, `Box<[T]>`, etc.) to slices. + +r[layout.str] +## `str` Layout + +String slices are a UTF-8 representation of characters that have the same layout as slices of type `[u8]`. A reference `&str` has the same layout as a reference `&[u8]`. + +r[layout.tuple] +## Tuple layout + +r[layout.tuple.def] +Tuples are laid out according to the [`Rust` representation][`Rust`]. + +r[layout.tuple.unit] +The exception to this is the unit tuple (`()`), which is guaranteed as a [zero-sized type] to have a size of 0 and an alignment of 1. + +r[layout.trait-object] +## Trait object layout + +Trait objects have the same layout as the value the trait object is of. + +> [!NOTE] +> This is about the raw trait object types, not pointers (`&dyn Trait`, `Box<dyn Trait>`, etc.) to trait objects. + +r[layout.closure] +## Closure layout + +Closures have no layout guarantees. + +r[layout.repr] +## Representations + +r[layout.repr.intro] +All user-defined composite types (`struct`s, `enum`s, and `union`s) have a *representation* that specifies what the layout is for the type. + +r[layout.repr.kinds] +The possible representations for a type are: + +- [`Rust`] (default) +- [`C`] +- The [primitive representations] +- [`transparent`] + +r[layout.repr.attribute] +The representation of a type can be changed by applying the `repr` attribute to it. The following example shows a struct with a `C` representation. + +```rust +#[repr(C)] +struct ThreeInts { + first: i16, + second: i8, + third: i32 +} +``` + +r[layout.repr.align-packed] +The alignment may be raised or lowered with the `align` and `packed` modifiers respectively. They alter the representation specified in the attribute. If no representation is specified, the default one is altered. + +```rust +// Default representation, alignment lowered to 2. +#[repr(packed(2))] +struct PackedStruct { + first: i16, + second: i8, + third: i32 +} + +// C representation, alignment raised to 8 +#[repr(C, align(8))] +struct AlignedStruct { + first: i16, + second: i8, + third: i32 +} +``` + +> [!NOTE] +> As a consequence of the representation being an attribute on the item, the representation does not depend on generic parameters. Any two types with the same name have the same representation. For example, `Foo<Bar>` and `Foo<Baz>` both have the same representation. + +r[layout.repr.inter-field] +The representation of a type can change the padding between fields, but does not change the layout of the fields themselves. For example, a struct with a `C` representation that contains a struct `Inner` with the `Rust` representation will not change the layout of `Inner`. + +<a id="the-default-representation"></a> +r[layout.repr.rust] +### The `Rust` representation + +r[layout.repr.rust.intro] +The `Rust` representation is the default representation for nominal types without a `repr` attribute. Using this representation explicitly through a `repr` attribute is guaranteed to be the same as omitting the attribute entirely. + +r[layout.repr.rust.layout] +The only data layout guarantees made by this representation are those required for soundness. These are: + + 1. The offset of a field is divisible by that field's alignment. + 2. The alignment of the type is at least the maximum alignment of its fields. + +r[layout.repr.rust.struct] +For [structs], it is further guaranteed that the fields do not overlap. That is, the fields can be ordered such that the offset plus the size of any field is less than or equal to the offset of the next field in the ordering. The ordering does not have to be the same as the order in which the fields are specified in the declaration of the type. + +Be aware that this guarantee does not imply that the fields have distinct addresses: [zero-sized types] may have the same address as other fields in the same struct. + +r[layout.repr.rust.struct-zst] +For [structs] with no fields or where all fields are [zero sized], it is further guaranteed that the structs are themselves [zero sized]. + +r[layout.repr.rust.enum-empty-zst] +[Enums] (without a [primitive representation] specified) with no variants are [zero sized]. + +> [!NOTE] +> Such enums are [uninhabited]. + +r[layout.repr.rust.enum-struct-like-zst] +For [enums] (without a [primitive representation] specified) with a single [field-struct-like variant], a single [unit-struct-like variant], or a single [tuple-struct-like variant] and where the struct-like thing has no fields or where all of the fields are [zero sized], the enums themselves are [zero sized]. + +```rust +# use core::mem::size_of; +enum E1 { + V {}, +} + +enum E2 { + V { f: () }, +} + +enum E3 { + V, +} + +enum E4 { + V(), +} + +enum E5 { + V(()), +} + +assert_eq!(size_of::<E1>(), 0); +assert_eq!(size_of::<E2>(), 0); +assert_eq!(size_of::<E3>(), 0); +assert_eq!(size_of::<E4>(), 0); +assert_eq!(size_of::<E5>(), 0); +``` + +r[layout.repr.rust.unspecified] +There are no other guarantees of data layout made by this representation. + +r[layout.repr.c] +### The `C` representation + +r[layout.repr.c.intro] +The `C` representation is designed for dual purposes. One purpose is for creating types that are interoperable with the C Language. The second purpose is to create types that you can soundly perform operations on that rely on data layout such as reinterpreting values as a different type. + +Because of this dual purpose, it is possible to create types that are not useful for interfacing with the C programming language. + +r[layout.repr.c.constraint] +This representation can be applied to structs, unions, and enums. The exception is [zero-variant enums] for which the `C` representation is an error. + +r[layout.repr.c.struct] +#### `#[repr(C)]` Structs + +r[layout.repr.c.struct.align] +The alignment of the struct is the alignment of the most-aligned field in it, or one if there are no fields. + +r[layout.repr.c.struct.size-field-offset] +The size and offset of fields is determined by the following algorithm. + +Start with a current offset of 0 bytes. + +For each field in declaration order in the struct, first determine the size and alignment of the field. If the current offset is not a multiple of the field's alignment, then add padding bytes to the current offset until it is a multiple of the field's alignment. The offset for the field is what the current offset is now. Then increase the current offset by the size of the field. + +Finally, the size of the struct is the current offset rounded up to the nearest multiple of the struct's alignment. + +Here is the algorithm: + +```rust +# /// A field of a struct. +# #[derive(Debug)] +struct Field { + alignment: usize, + size: usize, +} +# /// Layout of user-defined structs. +# #[derive(Debug)] +struct MockLayout { +# /// Fields stored in declaration order. + fields: Vec<Field>, +# /// Offset of each field from the start of the struct. + field_offsets: Vec<usize>, +# /// Overall alignment. + alignment: usize, +# /// Overall size. + size: usize, +} + +impl MockLayout { + /// Returns the amount of padding needed after `offset` to ensure that the + /// following address will be aligned to `alignment`. + fn padding_needed_for(offset: usize, alignment: usize) -> usize { + let misalignment = offset % alignment; + if misalignment > 0 { + // Round up to next multiple of `alignment`. + alignment - misalignment + } else { + // Already a multiple of `alignment`. + 0 + } + } + + /// Fields must be in declaration order. By this point, they have already + /// had their alignments and sizes calculated. + pub fn from_fields(fields: Vec<Field>) -> Self { + // "The alignment of the struct is the alignment of the most-aligned + // field in it, or one if there are no fields." + let alignment = fields + .iter() + .map(|field| field.alignment) + .max() + .unwrap_or(1); + + // "Start with a current offset of 0 bytes." + let mut current_offset = 0; + + let mut field_offsets = vec![]; + for field in &fields { + // "If the current offset is not a multiple of the field's + // alignment, then add padding bytes to the current offset until it + // is a multiple of the field's alignment." + current_offset += Self::padding_needed_for( + current_offset, + field.alignment + ); + + // "The offset for the field is what the current offset is now." + field_offsets.push(current_offset); + + // "Then increase the current offset by the size of the field." + current_offset += field.size; + } + + // "Finally, the size of the struct is the current offset rounded up to + // the nearest multiple of the struct's alignment." + let size = current_offset + Self::padding_needed_for( + current_offset, + alignment + ); + + MockLayout { fields, field_offsets, alignment, size } + } +} +# +# #[repr(C)] +# struct Demo { +# first: u8, +# second: u32, +# third: u64, +# } +# macro_rules! fields { +# ( $( $t:ty ),+ ) => { +# vec![ +# $( Field { +# alignment: std::mem::align_of::<$t>(), +# size: std::mem::size_of::<$t>(), +# }),+ +# ] +# } +# } +# let fields = fields![u8, u32, u64]; +# let demo_layout = MockLayout::from_fields(fields); +# assert_eq!(std::mem::align_of::<Demo>(), demo_layout.alignment); +# assert_eq!(std::mem::size_of::<Demo>(), demo_layout.size); +``` + +> [!WARNING] +> This mock implementation uses a naive algorithm that ignores overflow issues for the sake of clarity. To perform memory layout computations in actual code, use [`Layout`]. + +> [!NOTE] +> This algorithm can produce [zero-sized] structs. In C, an empty struct declaration like `struct Foo { }` is illegal. However, both gcc and clang support options to enable such structs, and assign them size zero. C++, in contrast, gives empty structs a size of 1, unless they are inherited from or they are fields that have the `[[no_unique_address]]` attribute, in which case they do not increase the overall size of the struct. + +r[layout.repr.c.union] +#### `#[repr(C)]` Unions + +r[layout.repr.c.union.intro] +A union declared with `#[repr(C)]` will have the same size and alignment as an equivalent C union declaration in the C language for the target platform. + +r[layout.repr.c.union.size-align] +The union will have a size of the maximum size of all of its fields rounded to its alignment, and an alignment of the maximum alignment of all of its fields. These maximums may come from different fields. Each field lives at byte offset 0 from the beginning of the union. + +```rust +#[repr(C)] +union Union { + f1: u16, + f2: [u8; 4], +} + +assert_eq!(std::mem::size_of::<Union>(), 4); // From f2 +assert_eq!(std::mem::align_of::<Union>(), 2); // From f1 + +assert_eq!(std::mem::offset_of!(Union, f1), 0); +assert_eq!(std::mem::offset_of!(Union, f2), 0); + +#[repr(C)] +union SizeRoundedUp { + a: u32, + b: [u16; 3], +} + +assert_eq!(std::mem::size_of::<SizeRoundedUp>(), 8); // Size of 6 from b, + // rounded up to 8 from + // alignment of a. +assert_eq!(std::mem::align_of::<SizeRoundedUp>(), 4); // From a + +assert_eq!(std::mem::offset_of!(SizeRoundedUp, a), 0); +assert_eq!(std::mem::offset_of!(SizeRoundedUp, b), 0); +``` + +r[layout.repr.c.enum] +#### `#[repr(C)]` Field-less Enums + +r[layout.repr.c.enum.discriminant] +For a [field-less enum] with the `C` representation, the discriminant values must either all be representable by the `int` type in the target platform's C ABI or all be representable by its `unsigned int` type. + +> [!NOTE] +> `repr(C)` enums without a primitive representation have discriminant values of type `isize`. See [items.enum.discriminant.type]. The size and alignment are determined from the discriminant values (according to the rule below) *after* they have been cast to `isize`. + +> [!NOTE] +> `rustc` accepts enums whose discriminant values do not meet this requirement but lints against them. This will become an error in the future. + +r[layout.repr.c.enum.size-align] +A [field-less enum] with the `C` representation has the same size and alignment as a C enum with the same discriminant values and no fixed underlying type. + +```rust +# use core::ffi::c_int; +# use core::mem::{align_of, size_of}; +#[repr(C)] +enum E { + V1, + V2, +} + +#[cfg(target_arch = "x86_64")] +{ + assert_eq!(size_of::<E>(), size_of::<c_int>()); + assert_eq!(align_of::<E>(), align_of::<c_int>()); +} +``` + +> [!NOTE] +> The enum representation in C is implementation defined, so this is really a "best guess". In particular, this may be incorrect when the C code of interest is compiled with certain flags. +> +> For maximum portability, prefer setting the size and alignment explicitly using a [primitive representation] on the Rust side and a fixed underlying type (introduced in C23) on the C side. + +> [!WARNING] +> There are crucial differences between an `enum` in the C language and Rust's [field-less enums] with this representation. An `enum` in C is mostly a `typedef` plus some named constants; in other words, an object of an `enum` type can hold any integer value. For example, this is often used for bitflags in `C`. In contrast, Rust’s [field-less enums] can only legally hold the discriminant values, everything else is [undefined behavior]. Therefore, using a field-less enum in FFI to model a C `enum` is often wrong. + +r[layout.repr.c.adt] +#### `#[repr(C)]` Enums With Fields + +r[layout.repr.c.adt.intro] +The representation of a `repr(C)` enum with fields is a `repr(C)` struct with two fields, also called a "tagged union" in C: + +r[layout.repr.c.adt.tag] +- a `repr(C)` version of the enum with all fields removed ("the tag") + +r[layout.repr.c.adt.fields] +- a `repr(C)` union of `repr(C)` structs for the fields of each variant that had them ("the payload") + +> [!NOTE] +> Due to the representation of `repr(C)` structs and unions, if a variant has a single field there is no difference between putting that field directly in the union or wrapping it in a struct; any system which wishes to manipulate such an `enum`'s representation may therefore use whichever form is more convenient or consistent for them. + +```rust +// This Enum has the same representation as ... +#[repr(C)] +enum MyEnum { + A(u32), + B(f32, u64), + C { x: u32, y: u8 }, + D, + } + +// ... this struct. +#[repr(C)] +struct MyEnumRepr { + tag: MyEnumDiscriminant, + payload: MyEnumFields, +} + +// This is the discriminant enum. +#[repr(C)] +enum MyEnumDiscriminant { A, B, C, D } + +// This is the variant union. +#[repr(C)] +union MyEnumFields { + A: MyAFields, + B: MyBFields, + C: MyCFields, + D: MyDFields, +} + +#[repr(C)] +#[derive(Copy, Clone)] +struct MyAFields(u32); + +#[repr(C)] +#[derive(Copy, Clone)] +struct MyBFields(f32, u64); + +#[repr(C)] +#[derive(Copy, Clone)] +struct MyCFields { x: u32, y: u8 } + +// This struct could be omitted (it is a zero-sized type), and it must be in +// C/C++ headers. +#[repr(C)] +#[derive(Copy, Clone)] +struct MyDFields; +``` + +r[layout.repr.primitive] +### Primitive representations + +r[layout.repr.primitive.intro] +The *primitive representations* are the representations with the same names as the primitive integer types. That is: `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, and `isize`. + +r[layout.repr.primitive.constraint] +Primitive representations can only be applied to enumerations and have different behavior whether the enum has fields or no fields. It is an error for [zero-variant enums] to have a primitive representation. Combining two primitive representations together is an error. + +r[layout.repr.primitive.enum] +#### Primitive representation of field-less enums + +A [field-less enum] with a primitive representation has the same size and alignment as the primitive type of the same name. + +> [!NOTE] +> Enums with a primitive representation have discriminant values of the type named by the representation. See [items.enum.discriminant.type-primitive]. + +r[layout.repr.primitive.adt] +#### Primitive representation of enums with fields + +The representation of a primitive representation enum is a `repr(C)` union of `repr(C)` structs for each variant with a field. The first field of each struct in the union is the primitive representation version of the enum with all fields removed ("the tag") and the remaining fields are the fields of that variant. + +> [!NOTE] +> This representation is unchanged if the tag is given its own member in the union, should that make manipulation more clear for you (although to follow the C++ standard the tag member should be wrapped in a `struct`). + +> [!NOTE] +> This representation is quite different from `repr(C)` for enums with fields. + +```rust +// This enum has the same representation as ... +#[repr(u8)] +enum MyEnum { + A(u32), + B(f32, u64), + C { x: u32, y: u8 }, + D, + } + +// ... this union. +#[repr(C)] +union MyEnumRepr { + A: MyVariantA, + B: MyVariantB, + C: MyVariantC, + D: MyVariantD, +} + +// This is the discriminant enum. +#[repr(u8)] +#[derive(Copy, Clone)] +enum MyEnumDiscriminant { A, B, C, D } + +#[repr(C)] +#[derive(Clone, Copy)] +struct MyVariantA(MyEnumDiscriminant, u32); + +#[repr(C)] +#[derive(Clone, Copy)] +struct MyVariantB(MyEnumDiscriminant, f32, u64); + +#[repr(C)] +#[derive(Clone, Copy)] +struct MyVariantC { tag: MyEnumDiscriminant, x: u32, y: u8 } + +#[repr(C)] +#[derive(Clone, Copy)] +struct MyVariantD(MyEnumDiscriminant); +``` + +r[layout.repr.primitive-c] +#### Combining primitive representations of enums with fields and `#[repr(C)]` + +For enums with fields, it is also possible to combine `repr(C)` and a primitive representation (e.g., `repr(C, u8)`). This modifies the [`repr(C)`] by changing the representation of the discriminant enum to the chosen primitive instead. So, if you chose the `u8` representation, then the discriminant enum would have a size and alignment of 1 byte. + +> [!NOTE] +> This means `repr(C, u8)` is quite different from `repr(u8)`! +> The former is a struct with two fields (tag and a union of variants), the latter is a union where each field starts with the tag. + +The discriminant enum from the example [earlier][`repr(C)`] then becomes: + +```rust +#[repr(C, u8)] // `u8` was added +enum MyEnum { + A(u32), + B(f32, u64), + C { x: u32, y: u8 }, + D, + } + +// ... + +#[repr(u8)] // So `u8` is used here instead of `C` +enum MyEnumDiscriminant { A, B, C, D } + +// ... +``` + +For example, with a `repr(C, u8)` enum it is not possible to have 257 unique discriminants ("tags") whereas the same enum with only a `repr(C)` attribute will compile without any problems. + +Using a primitive representation in addition to `repr(C)` can change the size of an enum from the `repr(C)` form: + +```rust +#[repr(C)] +enum EnumC { + Variant0(u8), + Variant1, +} + +#[repr(C, u8)] +enum Enum8 { + Variant0(u8), + Variant1, +} + +#[repr(C, u16)] +enum Enum16 { + Variant0(u8), + Variant1, +} + +// The size of the C representation is platform dependent +assert_eq!(std::mem::size_of::<EnumC>(), 8); +// One byte for the discriminant and one byte for the value in Enum8::Variant0 +assert_eq!(std::mem::size_of::<Enum8>(), 2); +// Two bytes for the discriminant and one byte for the value in Enum16::Variant0 +// plus one byte of padding. +assert_eq!(std::mem::size_of::<Enum16>(), 4); +``` + +[`repr(C)`]: #reprc-enums-with-fields + +r[layout.repr.alignment] +### The alignment modifiers + +r[layout.repr.alignment.intro] +The `align` and `packed` modifiers can be used to respectively raise or lower the alignment of `struct`s and `union`s. `packed` may also alter the padding between fields (although it will not alter the padding inside of any field). On their own, `align` and `packed` do not provide guarantees about the order of fields in the layout of a struct or the layout of an enum variant, although they may be combined with representations (such as `C`) which do provide such guarantees. + +r[layout.repr.alignment.constraint-alignment] +The alignment is specified as an integer parameter in the form of `#[repr(align(x))]` or `#[repr(packed(x))]`. The alignment value must be a power of two from 1 up to 2<sup>29</sup>. For `packed`, if no value is given, as in `#[repr(packed)]`, then the value is 1. + +r[layout.repr.alignment.align] +For `align`, if the specified alignment is less than the alignment of the type without the `align` modifier, then the alignment is unaffected. + +r[layout.repr.alignment.packed] +For `packed`, if the specified alignment is greater than the type's alignment without the `packed` modifier, then the alignment and layout is unaffected. + +r[layout.repr.alignment.packed-fields] +The alignments of each field, for the purpose of positioning fields, is the smaller of the specified alignment and the alignment of the field's type. + +r[layout.repr.alignment.packed-padding] +Inter-field padding is guaranteed to be the minimum required in order to satisfy each field's (possibly altered) alignment (although note that, on its own, `packed` does not provide any guarantee about field ordering). An important consequence of these rules is that a type with `#[repr(packed(1))]` (or `#[repr(packed)]`) will have no inter-field padding. + +r[layout.repr.alignment.constraint-exclusive] +The `align` and `packed` modifiers cannot be applied on the same type and a `packed` type cannot transitively contain another `align`ed type. `align` and `packed` may only be applied to the [`Rust`] and [`C`] representations. + +r[layout.repr.alignment.enum] +The `align` modifier can also be applied on an `enum`. When it is, the effect on the `enum`'s alignment is the same as if the `enum` was wrapped in a newtype `struct` with the same `align` modifier. + +> [!NOTE] +> References to unaligned fields are not allowed because it is [undefined behavior]. When fields are unaligned due to an alignment modifier, consider the following options for using references and dereferences: +> +> ```rust +> #[repr(packed)] +> struct Packed { +> f1: u8, +> f2: u16, +> } +> let mut e = Packed { f1: 1, f2: 2 }; +> // Instead of creating a reference to a field, copy the value to a local variable. +> let x = e.f2; +> // Or in situations like `println!` which creates a reference, use braces +> // to change it to a copy of the value. +> println!("{}", {e.f2}); +> // Or if you need a pointer, use the unaligned methods for reading and writing +> // instead of dereferencing the pointer directly. +> let ptr: *const u16 = &raw const e.f2; +> let value = unsafe { ptr.read_unaligned() }; +> let mut_ptr: *mut u16 = &raw mut e.f2; +> unsafe { mut_ptr.write_unaligned(3) } +> ``` + +r[layout.repr.transparent] +### The `transparent` representation + +r[layout.repr.transparent.constraint-field] +The `transparent` representation can only be used on a [`struct`][structs] or an [`enum`][enumerations] with a single variant that has: +- any number of fields with size 0 and alignment 1 (e.g. [`PhantomData<T>`]), and +- at most one other field. + +r[layout.repr.transparent.layout-abi] +Structs and enums with this representation have the same layout and ABI as the only non-size 0 non-alignment 1 field, if present, or unit otherwise. + +This is different than the `C` representation because a struct with the `C` representation will always have the ABI of a `C` `struct` while, for example, a struct with the `transparent` representation with a primitive field will have the ABI of the primitive field. + +r[layout.repr.transparent.constraint-exclusive] +Because this representation delegates type layout to another type, it cannot be used with any other representation. + +[`align_of_val`]: std::mem::align_of_val +[`size_of_val`]: std::mem::size_of_val +[`align_of`]: std::mem::align_of +[`size_of`]: std::mem::size_of +[`Sized`]: std::marker::Sized +[`Copy`]: std::marker::Copy +[dynamically sized types]: dynamically-sized-types.md +[enums]: items/enumerations.md +[field-less enum]: items.enum.fieldless +[field-less enums]: items/enumerations.md#field-less-enum +[field-struct-like variant]: EnumVariantStruct +[fn-abi-compatibility]: ../core/primitive.fn.md#abi-compatibility +[enumerations]: items/enumerations.md +[zero-variant enums]: items/enumerations.md#zero-variant-enums +[undefined behavior]: behavior-considered-undefined.md +[zero sized]: glossary.zst +[zero-sized]: glossary.zst +[zero-sized type]: glossary.zst +[zero-sized types]: glossary.zst +[`PhantomData<T>`]: special-types-and-traits.md#phantomdatat +[`Rust`]: #the-rust-representation +[`C`]: #the-c-representation +[primitive representation]: #primitive-representations +[primitive representations]: #primitive-representations +[structs]: items/structs.md +[`transparent`]: #the-transparent-representation +[tuple-struct-like variant]: EnumVariantTuple +[unit-struct-like variant]: EnumVariant +[`Layout`]: std::alloc::Layout +[uninhabited]: glossary.uninhabited diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/type-system.md b/stdlib/kvlang/reference/rust/reference-repo/src/type-system.md new file mode 100644 index 00000000..bed7f128 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/type-system.md @@ -0,0 +1 @@ +# Type system diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types.md b/stdlib/kvlang/reference/rust/reference-repo/src/types.md new file mode 100644 index 00000000..8ee8ab00 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types.md @@ -0,0 +1,176 @@ +r[type] +# Types + +r[type.intro] +Every variable, item, and value in a Rust program has a type. The _type_ of a *value* defines the interpretation of the memory holding it and the operations that may be performed on the value. + +r[type.builtin] +Built-in types are tightly integrated into the language, in nontrivial ways that are not possible to emulate in user-defined types. + +r[type.user-defined] +User-defined types have limited capabilities. + +r[type.kinds] +The list of types is: + +* Primitive types: + * [Boolean] --- `bool` + * [Numeric] --- integer and float + * [`char`] + * [`str`] + * [Never] --- `!` --- a type with no values +* Sequence types: + * [Tuple] + * [Array] + * [Slice] +* User-defined types: + * [Struct] + * [Enum] + * [Union] +* Function types: + * [Functions] + * [Closures] +* Pointer types: + * [References] + * [Raw pointers] + * [Function pointers] +* Trait types: + * [Trait objects] + * [Impl trait] + +r[type.name] +## Type expressions + +r[type.name.syntax] +```grammar,types +Type -> + TypeNoBounds + | ImplTraitType + | TraitObjectType + +TypeNoBounds -> + ParenthesizedType + | ImplTraitTypeOneBound + | TraitObjectTypeOneBound + | TypePath + | TupleType + | NeverType + | RawPointerType + | ReferenceType + | ArrayType + | SliceType + | InferredType + | QualifiedPathInType + | BareFunctionType + | MacroInvocation +``` + +r[type.name.intro] +A _type expression_ as defined in the [Type] grammar rule above is the syntax for referring to a type. It may refer to: + +r[type.name.sequence] +* Sequence types ([tuple], [array], [slice]). + +r[type.name.path] +* [Type paths] which can reference: + * Primitive types ([boolean], [numeric], [`char`], [`str`]). + * Paths to an [item] ([struct], [enum], [union], [type alias], [trait]). + * [`Self` path] where `Self` is the implementing type. + * Generic [type parameters]. + +r[type.name.pointer] +* Pointer types ([reference], [raw pointer], [function pointer]). + +r[type.name.inference] +* The [inferred type] which asks the compiler to determine the type. + +r[type.name.grouped] +* [Parentheses] which are used for disambiguation. + +r[type.name.trait] +* Trait types: [Trait objects] and [impl trait]. + +r[type.name.never] +* The [never] type. + +r[type.name.macro-expansion] +* [Macros] which expand to a type expression. + +r[type.name.parenthesized] +### Parenthesized types + +r[type.name.parenthesized.syntax] +```grammar,types +ParenthesizedType -> `(` Type `)` +``` + +r[type.name.parenthesized.intro] +In some situations the combination of types may be ambiguous. Use parentheses around a type to avoid ambiguity. For example, the `+` operator for [type boundaries] within a [reference type] is unclear where the boundary applies, so the use of parentheses is required. Grammar rules that require this disambiguation use the [TypeNoBounds] rule instead of [Type][grammar-Type]. + +```rust +# use std::any::Any; +type T<'a> = &'a (dyn Any + Send); +``` + +r[type.recursive] +## Recursive types + +r[type.recursive.intro] +Nominal types — [structs], [enumerations], and [unions] — may be recursive. That is, each `enum` variant or `struct` or `union` field may refer, directly or indirectly, to the enclosing `enum` or `struct` type itself. + +r[type.recursive.constraint] +Such recursion has restrictions: + +* Recursive types must include a nominal type in the recursion (not mere [type aliases], or other structural types such as [arrays] or [tuples]). So `type Rec = &'static [Rec]` is not allowed. +* The size of a recursive type must be finite; in other words the recursive fields of the type must be [pointer types]. + +An example of a *recursive* type and its use: + +```rust +enum List<T> { + Nil, + Cons(T, Box<List<T>>) +} + +let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); +``` + +[`char`]: types/char.md +[`str`]: types/str.md +[Array]: types/array.md +[Boolean]: types/boolean.md +[Closures]: types/closure.md +[Enum]: types/enum.md +[Function pointers]: types/function-pointer.md +[Functions]: types/function-item.md +[Impl trait]: types/impl-trait.md +[Macros]: macros.md +[Numeric]: types/numeric.md +[Parentheses]: #parenthesized-types +[Raw pointers]: types/pointer.md#raw-pointers-const-and-mut +[References]: types/pointer.md#shared-references- +[Slice]: types/slice.md +[Struct]: types/struct.md +[Trait objects]: types/trait-object.md +[Tuple]: types/tuple.md +[Type paths]: paths.md#paths-in-types +[Union]: types/union.md +[`Self` path]: paths.md#self-1 +[arrays]: types/array.md +[enumerations]: types/enum.md +[function pointer]: types/function-pointer.md +[inferred type]: types/inferred.md +[item]: items.md +[never]: types/never.md +[pointer types]: types/pointer.md +[raw pointer]: types/pointer.md#raw-pointers-const-and-mut +[reference type]: types/pointer.md#shared-references- +[reference]: types/pointer.md#shared-references- +[structs]: types/struct.md +[trait]: types/trait-object.md +[tuples]: types/tuple.md +[type alias]: items/type-aliases.md +[type aliases]: items/type-aliases.md +[type boundaries]: trait-bounds.md +[type parameters]: types/parameters.md +[unions]: types/union.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/array.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/array.md new file mode 100644 index 00000000..8df7cb71 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/array.md @@ -0,0 +1,32 @@ +r[type.array] +# Array types + +r[type.array.syntax] +```grammar,types +ArrayType -> `[` Type `;` Expression `]` +``` + +r[type.array.intro] +An array is a fixed-size sequence of `N` elements of type `T`. The array type is written as `[T; N]`. + +r[type.array.constraint] +The size is a [constant expression] that evaluates to a [`usize`]. + +Examples: + +```rust +// A stack-allocated array +let array: [i32; 3] = [1, 2, 3]; + +// A heap-allocated array, coerced to a slice +let boxed_array: Box<[i32]> = Box::new([1, 2, 3]); +``` + +r[type.array.index] +All elements of arrays are always initialized, and access to an array is always bounds-checked in safe methods and operators. + +> [!NOTE] +> The [`Vec<T>`] standard library type provides a heap-allocated resizable array type. + +[`usize`]: numeric.md#machine-dependent-integer-types +[constant expression]: ../const_eval.md#constant-expressions diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/boolean.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/boolean.md new file mode 100644 index 00000000..7da7f30e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/boolean.md @@ -0,0 +1,143 @@ +r[type.bool] +# Boolean type + +r[type.bool.intro] +```rust +let b: bool = true; +``` + +The *boolean type* or *bool* is a primitive data type that can take on one of two values, called *true* and *false*. + +r[type.bool.literal] +Values of this type may be created using a [literal expression] using the keywords `true` and `false` corresponding to the value of the same name. + +r[type.bool.namespace] +This type is a part of the [language prelude] with the [name] `bool`. + +r[type.bool.layout] +An object with the boolean type has a [size and alignment] of 1 each. + +r[type.bool.repr] +The value false has the bit pattern `0x00` and the value true has the bit pattern `0x01`. It is [undefined behavior] for an object with the boolean type to have any other bit pattern. + +r[type.bool.use] +The boolean type is the type of many operands in various [expressions]: + +r[type.bool.use-in-condition] +* The condition operand in [if expressions] and [while expressions] + +r[type.bool.use-in-lazy-operator] +* The operands in [lazy boolean operator expressions][lazy] + +> [!NOTE] +> The boolean type acts similarly to but is not an [enumerated type]. In practice, this mostly means that constructors are not associated to the type (e.g. `bool::true`). + +r[type.bool.traits] +Like all primitives, the boolean type [implements][p-impl] the [traits][p-traits] [`Clone`][p-clone], [`Copy`][p-copy], [`Sized`][p-sized], [`Send`][p-send], and [`Sync`][p-sync]. + +> [!NOTE] +> See the [standard library docs](bool) for library operations. + +r[type.bool.expr] +## Operations on boolean values + +r[type.bool.expr.intro] +When using certain operator expressions with a boolean type for its operands, they evaluate using the rules of [boolean logic]. + +r[type.bool.expr.not] +### Logical not + +| `b` | [`!b`][op-not] | +|- | - | +| `true` | `false` | +| `false` | `true` | + +r[type.bool.expr.or] +### Logical or + +| `a` | `b` | [`a \| b`][op-or] | +|- | - | - | +| `true` | `true` | `true` | +| `true` | `false` | `true` | +| `false` | `true` | `true` | +| `false` | `false` | `false` | + +r[type.bool.expr.and] +### Logical and + +| `a` | `b` | [`a & b`][op-and] | +|- | - | - | +| `true` | `true` | `true` | +| `true` | `false` | `false` | +| `false` | `true` | `false` | +| `false` | `false` | `false` | + +r[type.bool.expr.xor] +### Logical xor + +| `a` | `b` | [`a ^ b`][op-xor] | +|- | - | - | +| `true` | `true` | `false` | +| `true` | `false` | `true` | +| `false` | `true` | `true` | +| `false` | `false` | `false` | + +r[type.bool.expr.cmp] +### Comparisons + +r[type.bool.expr.cmp.eq] +| `a` | `b` | [`a == b`][op-compare] | +|- | - | - | +| `true` | `true` | `true` | +| `true` | `false` | `false` | +| `false` | `true` | `false` | +| `false` | `false` | `true` | + +r[type.bool.expr.cmp.greater] +| `a` | `b` | [`a > b`][op-compare] | +|- | - | - | +| `true` | `true` | `false` | +| `true` | `false` | `true` | +| `false` | `true` | `false` | +| `false` | `false` | `false` | + +r[type.bool.expr.cmp.not-eq] +* `a != b` is the same as `!(a == b)` + +r[type.bool.expr.cmp.greater-eq] +* `a >= b` is the same as `a == b | a > b` + +r[type.bool.expr.cmp.less] +* `a < b` is the same as `!(a >= b)` + +r[type.bool.expr.cmp.less-eq] +* `a <= b` is the same as `a == b | a < b` + +r[type.bool.validity] +## Bit validity + +The single byte of a `bool` is guaranteed to be initialized (in other words, `transmute::<bool, u8>(...)` is always sound -- but since some bit patterns are invalid `bool`s, the inverse is not always sound). + +[boolean logic]: https://en.wikipedia.org/wiki/Boolean_algebra +[enumerated type]: enum.md +[expressions]: ../expressions.md +[if expressions]: ../expressions/if-expr.md#if-expressions +[language prelude]: ../names/preludes.md#language-prelude +[lazy]: ../expressions/operator-expr.md#lazy-boolean-operators +[literal expression]: ../expressions/literal-expr.md +[name]: ../names.md +[op-and]: ../expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[op-compare]: ../expressions/operator-expr.md#comparison-operators +[op-not]: ../expressions/operator-expr.md#negation-operators +[op-or]: ../expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[op-xor]: ../expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[p-clone]: ../special-types-and-traits.md#clone +[p-copy]: ../special-types-and-traits.md#copy +[p-impl]: ../items/implementations.md +[p-send]: ../special-types-and-traits.md#send +[p-sized]: ../special-types-and-traits.md#sized +[p-sync]: ../special-types-and-traits.md#sync +[p-traits]: ../items/traits.md +[size and alignment]: ../type-layout.md#size-and-alignment +[undefined behavior]: ../behavior-considered-undefined.md +[while expressions]: ../expressions/loop-expr.md#predicate-loops diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/char.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/char.md new file mode 100644 index 00000000..c242c14e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/char.md @@ -0,0 +1,27 @@ +r[type.char] +# Character type + +r[type.char.intro] +The `char` type represents a single [Unicode scalar value] (i.e., a code point that is not a surrogate). + +> [!EXAMPLE] +> ```rust +> let c: char = 'a'; +> let emoji: char = '😀'; +> let unicode: char = '\u{1F600}'; +> ``` + +> [!NOTE] +> See [the standard library docs][`char`] for information on the impls of the `char` type. + +r[type.char.value] +A value of type `char` is represented as a 32-bit unsigned word in the 0x0000 to 0xD7FF or 0xE000 to 0x10FFFF range. It is immediate [undefined behavior] to create a `char` that falls outside this range. + +r[type.char.layout] +`char` is guaranteed to have the same size and alignment as `u32` on all platforms. + +r[type.char.validity] +Every byte of a `char` is guaranteed to be initialized. In other words, `transmute::<char, [u8; size_of::<char>()]>(...)` is always sound -- but since some bit patterns are invalid `char`s, the inverse is not always sound. + +[Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value +[undefined behavior]: ../behavior-considered-undefined.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/closure.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/closure.md new file mode 100644 index 00000000..85f5908e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/closure.md @@ -0,0 +1,840 @@ +r[type.closure] +# Closure types + +r[type.closure.intro] +A [closure expression] produces a closure value with a unique, anonymous type that cannot be written out. A closure type is approximately equivalent to a struct which contains the captured values. For instance, the following closure: + +```rust +#[derive(Debug)] +struct Point { x: i32, y: i32 } +struct Rectangle { left_top: Point, right_bottom: Point } + +fn f<F : FnOnce() -> String> (g: F) { + println!("{}", g()); +} + +let mut rect = Rectangle { + left_top: Point { x: 1, y: 1 }, + right_bottom: Point { x: 0, y: 0 } +}; + +let c = || { + rect.left_top.x += 1; + rect.right_bottom.x += 1; + format!("{:?}", rect.left_top) +}; +f(c); // Prints "Point { x: 2, y: 1 }". +``` + +generates a closure type roughly like the following: + +<!-- ignore: simplified --> +```rust,ignore +// Note: This is not exactly how it is translated, this is only for +// illustration. + +struct Closure<'a> { + left_top : &'a mut Point, + right_bottom_x : &'a mut i32, +} + +impl<'a> FnOnce<()> for Closure<'a> { + type Output = String; + extern "rust-call" fn call_once(self, args: ()) -> String { + self.left_top.x += 1; + *self.right_bottom_x += 1; + format!("{:?}", self.left_top) + } +} +``` + +so that the call to `f` works as if it were: + +<!-- ignore: continuation of above --> +```rust,ignore +f(Closure{ left_top: &mut rect.left_top, right_bottom_x: &mut rect.right_bottom.x }); +``` + +r[type.closure.capture] +## Capture modes + +r[type.closure.capture.intro] +A *capture mode* determines how a [place expression] from the environment is borrowed or moved into the closure. The capture modes are: + +1. Immutable borrow (`ImmBorrow`) --- The place expression is captured as a [shared reference]. +2. Unique immutable borrow (`UniqueImmBorrow`) --- This is similar to an immutable borrow, but must be unique as described [below](#unique-immutable-borrows-in-captures). +3. Mutable borrow (`MutBorrow`) --- The place expression is captured as a [mutable reference]. +4. Move (`ByValue`) --- The place expression is captured by [moving the value] into the closure. + +r[type.closure.capture.precedence] +Place expressions from the environment are captured from the first mode that is compatible with how the captured value is used inside the closure body. The mode is not affected by the code surrounding the closure, such as the lifetimes of involved variables or fields, or of the closure itself. + +[moving the value]: ../expressions.md#moved-and-copied-types +[mutable reference]: pointer.md#mutable-references-mut +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[shared reference]: pointer.md#references--and-mut + +r[type.closure.capture.copy] +### `Copy` values + +Values that implement [`Copy`] that are moved into the closure are captured with the `ImmBorrow` mode. + +```rust +let x = [0; 1024]; +let c = || { + let y = x; // x captured by ImmBorrow +}; +``` + +r[type.closure.async.input] +### Async input capture + +Async closures always capture all input arguments, regardless of whether or not they are used within the body. + +## Capture precision + +r[type.closure.capture.precision.capture-path] +A *capture path* is a sequence starting with a variable from the environment followed by zero or more place projections from that variable. + +r[type.closure.capture.precision.place-projection] +A *place projection* is a [field access], [tuple index], [dereference] (and automatic dereferences), [array or slice index] expression, or [pattern destructuring] applied to a variable. + +> [!NOTE] +> In `rustc`, pattern destructuring desugars into a series of dereferences and field or element accesses. + +r[type.closure.capture.precision.intro] +The closure borrows or moves the capture path, which may be truncated based on the rules described below. + +For example: + +```rust +struct SomeStruct { + f1: (i32, i32), +} +let s = SomeStruct { f1: (1, 2) }; + +let c = || { + let x = s.f1.1; // s.f1.1 captured by ImmBorrow +}; +c(); +``` + +Here the capture path is the local variable `s`, followed by a field access `.f1`, and then a tuple index `.1`. This closure captures an immutable borrow of `s.f1.1`. + +[field access]: ../expressions/field-expr.md +[pattern destructuring]: patterns.destructure +[tuple index]: ../expressions/tuple-expr.md#tuple-indexing-expressions +[dereference]: ../expressions/operator-expr.md#the-dereference-operator +[array or slice index]: ../expressions/array-expr.md#array-and-slice-indexing-expressions + +r[type.closure.capture.precision.shared-prefix] +### Shared prefix + +In the case where a capture path and one of the ancestors of that path are both captured by a closure, the ancestor path is captured with the highest capture mode among the two captures, `CaptureMode = max(AncestorCaptureMode, DescendantCaptureMode)`, using the strict weak ordering: + +`ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue` + +Note that this might need to be applied recursively. + +```rust +// In this example, there are three different capture paths with a shared ancestor: +# fn move_value<T>(_: T){} +let s = String::from("S"); +let t = (s, String::from("T")); +let mut u = (t, String::from("U")); + +let c = || { + println!("{:?}", u); // u captured by ImmBorrow + u.1.truncate(0); // u.1 captured by MutBorrow + move_value(u.0.0); // u.0.0 captured by ByValue +}; +c(); +``` + +Overall this closure will capture `u` by `ByValue`. + +r[type.closure.capture.precision.dereference-shared] +### Rightmost shared reference truncation + +The capture path is truncated at the rightmost dereference in the capture path if the dereference is applied to a shared reference. + +This truncation is allowed because fields that are read through a shared reference will always be read via a shared reference or a copy. This helps reduce the size of the capture when the extra precision does not yield any benefit from a borrow checking perspective. + +The reason it is the *rightmost* dereference is to help avoid a shorter lifetime than is necessary. Consider the following example: + +```rust +struct Int(i32); +struct B<'a>(&'a i32); + +struct MyStruct<'a> { + a: &'static Int, + b: B<'a>, +} + +fn foo<'a, 'b>(m: &'a MyStruct<'b>) -> impl FnMut() + 'static { + let c = || drop(&m.a.0); + c +} +``` + +If this were to capture `m`, then the closure would no longer outlive `'static`, since `m` is constrained to `'a`. Instead, it captures `(*(*m).a)` by `ImmBorrow`. + +r[type.closure.capture.precision.wildcard] +### Wildcard pattern bindings + +r[type.closure.capture.precision.wildcard.reads] +Closures only capture data that needs to be read. Binding a value with a [wildcard pattern] does not read the value, so the place is not captured. + +```rust,no_run +struct S; // A non-`Copy` type. +let x = S; +let c = || { + let _ = x; // Does not capture `x`. +}; +let c = || match x { + _ => (), // Does not capture `x`. +}; +x; // OK: `x` can be moved here. +c(); +``` + +r[type.closure.capture.precision.wildcard.destructuring] +Destructuring tuples, structs, and single-variant enums does not, by itself, cause a read or the place to be captured. + +> [!NOTE] +> Enums marked with [`#[non_exhaustive]`][attributes.type-system.non_exhaustive] are always treated as having multiple variants. See *[type.closure.capture.precision.discriminants.non_exhaustive]*. + +```rust,no_run +struct S; // A non-`Copy` type. + +// Destructuring tuples does not cause a read or capture. +let x = (S,); +let c = || { + let (..) = x; // Does not capture `x`. +}; +x; // OK: `x` can be moved here. +c(); + +// Destructuring unit structs does not cause a read or capture. +let x = S; +let c = || { + let S = x; // Does not capture `x`. +}; +x; // OK: `x` can be moved here. +c(); + +// Destructuring structs does not cause a read or capture. +struct W<T>(T); +let x = W(S); +let c = || { + let W(..) = x; // Does not capture `x`. +}; +x; // OK: `x` can be moved here. +c(); + +// Destructuring single-variant enums does not cause a read +// or capture. +enum E<T> { V(T) } +let x = E::V(S); +let c = || { + let E::V(..) = x; // Does not capture `x`. +}; +x; // OK: `x` can be moved here. +c(); +``` + +r[type.closure.capture.precision.wildcard.fields] +Fields matched against [RestPattern] (`..`) or [StructPatternEtCetera] (also `..`) are not read, and those fields are not captured. + +```rust,no_run +struct S; // A non-`Copy` type. +let x = (S, S); +let c = || { + let (x0, ..) = x; // Captures `x.0` by `ByValue`. +}; +// Only the first tuple field was captured by the closure. +x.1; // OK: `x.1` can be moved here. +c(); +``` + +r[type.closure.capture.precision.wildcard.array-slice] +Partial captures of arrays and slices are not supported; the entire slice or array is always captured even if used with wildcard pattern matching, indexing, or sub-slicing. + +```rust,compile_fail,E0382 +struct S; // A non-`Copy` type. +let mut x = [S, S]; +let c = || { + let [x0, _] = x; // Captures all of `x` by `ByValue`. +}; +let _ = &mut x[1]; // ERROR: Borrow of moved value. +``` + +r[type.closure.capture.precision.wildcard.initialized] +Values that are matched with wildcards must still be initialized. + +```rust,compile_fail,E0381 +let x: u8; +let c = || { + let _ = x; // ERROR: Binding `x` isn't initialized. +}; +``` + +[wildcard pattern]: ../patterns.md#wildcard-pattern + +r[type.closure.capture.precision.discriminants] +### Capturing for discriminant reads + +r[type.closure.capture.precision.discriminants.reads] +If pattern matching reads a discriminant, the place containing that discriminant is captured by `ImmBorrow`. + +r[type.closure.capture.precision.discriminants.multiple-variant] +Matching against a variant of an enum that has more than one variant reads the discriminant, capturing the place by `ImmBorrow`. + +```rust,compile_fail,E0502 +struct S; // A non-`Copy` type. +let mut x = (Some(S), S); +let c = || match x { + (None, _) => (), +// ^^^^ +// This pattern requires reading the discriminant, which +// causes `x.0` to be captured by `ImmBorrow`. + _ => (), +}; +let _ = &mut x.0; // ERROR: Cannot borrow `x.0` as mutable. +// ^^^ +// The closure is still live, so `x.0` is still immutably +// borrowed here. +c(); +``` + +```rust,no_run +# struct S; // A non-`Copy` type. +# let x = (Some(S), S); +let c = || match x { // Captures `x.0` by `ImmBorrow`. + (None, _) => (), + _ => (), +}; +// Though `x.0` is captured due to the discriminant read, +// `x.1` is not captured. +x.1; // OK: `x.1` can be moved here. +c(); +``` + +r[type.closure.capture.precision.discriminants.single-variant] +Matching against the only variant of a single-variant enum does not read the discriminant and does not capture the place. + +```rust,no_run +enum E<T> { V(T) } // A single-variant enum. +let x = E::V(()); +let c = || { + let E::V(_) = x; // Does not capture `x`. +}; +x; // OK: `x` can be moved here. +c(); +``` + +r[type.closure.capture.precision.discriminants.non_exhaustive] +If [`#[non_exhaustive]`][attributes.type-system.non_exhaustive] is applied to an enum, the enum is treated as having multiple variants for the purpose of deciding whether a read occurs, even if it actually has only one variant. + +r[type.closure.capture.precision.discriminants.uninhabited-variants] +Even if all variants but the one being matched against are uninhabited, making the pattern [irrefutable][patterns.refutable], the discriminant is still read if it otherwise would be. + +```rust,compile_fail,E0502 +let mut x = Ok::<_, !>(42); +let c = || { + let Ok(_) = x; // Captures `x` by `ImmBorrow`. +}; +let _ = &mut x; // ERROR: Cannot borrow `x` as mutable. +c(); +``` + + +r[type.closure.capture.precision.range-patterns] +### Capturing and range patterns + +r[type.closure.capture.precision.range-patterns.reads] +Matching against a [range pattern][patterns.range] reads the place being matched, even if the range includes all possible values of the type, and captures the place by `ImmBorrow`. + +```rust,compile_fail,E0502 +let mut x = 0u8; +let c = || { + let 0..=u8::MAX = x; // Captures `x` by `ImmBorrow`. +}; +let _ = &mut x; // ERROR: Cannot borrow `x` as mutable. +c(); +``` + +r[type.closure.capture.precision.slice-patterns] +### Capturing and slice patterns + +r[type.closure.capture.precision.slice-patterns.slices] +Matching a slice against a [slice pattern][patterns.slice] other than one with only a single [rest pattern][patterns.rest] (i.e. `[..]`) is treated as a read of the length from the slice and captures the slice by `ImmBorrow`. + +```rust,compile_fail,E0502 +let x: &mut [u8] = &mut []; +let c = || match x { // Captures `*x` by `ImmBorrow`. + &mut [] => (), +// ^^ +// This matches a slice of exactly zero elements. To know whether the +// scrutinee matches, the length must be read, causing the slice to +// be captured. + _ => (), +}; +let _ = &mut *x; // ERROR: Cannot borrow `*x` as mutable. +c(); +``` + +```rust,no_run +let x: &mut [u8] = &mut []; +let c = || match x { // Does not capture `*x`. + [..] => (), +// ^^ Rest pattern. +}; +let _ = &mut *x; // OK +c(); +``` + +> [!NOTE] +> Perhaps surprisingly, even though the length is contained in the (wide) *pointer* to the slice, it is the place of the *pointee* (the slice) that is treated as read and is captured. +> +> ```rust,no_run +> fn f<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l { +> // The closure outlives `'l` because it captures `**x`. If +> // instead it captured `*x`, it would not live long enough +> // to satisfy the `impl Fn() + 'l` bound. +> || match *x { // Captures `**x` by `ImmBorrow`. +> &[] => (), +> _ => (), +> } +> } +> ``` +> +> In this way, the behavior is consistent with dereferencing to the slice in the scrutinee. +> +> ```rust,no_run +> fn f<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l { +> || match **x { // Captures `**x` by `ImmBorrow`. +> [] => (), +> _ => (), +> } +> } +> ``` +> +> For details, see [Rust PR #138961](https://github.com/rust-lang/rust/pull/138961). + +r[type.closure.capture.precision.slice-patterns.arrays] +As the length of an array is fixed by its type, matching an array against a slice pattern does not by itself capture the place. + +```rust,no_run +let x: [u8; 1] = [0]; +let c = || match x { // Does not capture `x`. + [_] => (), // Length is fixed. +}; +x; // OK: `x` can be moved here. +c(); +``` + +r[type.closure.capture.precision.move-dereference] +### Capturing references in move contexts + +Because it is not allowed to move fields out of a reference, `move` closures will only capture the prefix of a capture path that runs up to, but not including, the first dereference of a reference. The reference itself will be moved into the closure. + +```rust +struct T(String, String); + +let mut t = T(String::from("foo"), String::from("bar")); +let t_mut_ref = &mut t; +let mut c = move || { + t_mut_ref.0.push_str("123"); // captures `t_mut_ref` ByValue +}; +c(); +``` + +r[type.closure.capture.precision.raw-pointer-dereference] +### Raw pointer dereference + +Because it is `unsafe` to dereference a raw pointer, closures will only capture the prefix of a capture path that runs up to, but not including, the first dereference of a raw pointer. + +```rust +struct T(String, String); + +let t = T(String::from("foo"), String::from("bar")); +let t_ptr = &t as *const T; + +let c = || unsafe { + println!("{}", (*t_ptr).0); // captures `t_ptr` by ImmBorrow +}; +c(); +``` + +r[type.closure.capture.precision.union] +### Union fields + +Because it is `unsafe` to access a union field, closures will only capture the prefix of a capture path that runs up to the union itself. + +```rust +union U { + a: (i32, i32), + b: bool, +} +let u = U { a: (123, 456) }; + +let c = || { + let x = unsafe { u.a.0 }; // captures `u` ByValue +}; +c(); + +// This also includes writing to fields. +let mut u = U { a: (123, 456) }; + +let mut c = || { + u.b = true; // captures `u` with MutBorrow +}; +c(); +``` + +r[type.closure.capture.precision.unaligned] +### Reference into unaligned `struct`s + +Because it is [undefined behavior] to create references to unaligned fields in a structure, closures will only capture the prefix of the capture path that runs up to, but not including, the first field access into a structure that uses [the `packed` representation]. This includes all fields, even those that are aligned, to protect against compatibility concerns should any of the fields in the structure change in the future. + +```rust +#[repr(packed)] +struct T(i32, i32); + +let t = T(2, 5); +let c = || { + let a = t.0; // captures `t` with ImmBorrow +}; +// Copies out of `t` are ok. +let (a, b) = (t.0, t.1); +c(); +``` + +Similarly, taking the address of an unaligned field also captures the entire struct: + +```rust,compile_fail,E0505 +#[repr(packed)] +struct T(String, String); + +let mut t = T(String::new(), String::new()); +let c = || { + let a = std::ptr::addr_of!(t.1); // captures `t` with ImmBorrow +}; +let a = t.0; // ERROR: cannot move out of `t.0` because it is borrowed +c(); +``` + +but the above works if it is not packed since it captures the field precisely: + +```rust +struct T(String, String); + +let mut t = T(String::new(), String::new()); +let c = || { + let a = std::ptr::addr_of!(t.1); // captures `t.1` with ImmBorrow +}; +// The move here is allowed. +let a = t.0; +c(); +``` + +[undefined behavior]: ../behavior-considered-undefined.md +[the `packed` representation]: ../type-layout.md#the-alignment-modifiers + +r[type.closure.capture.precision.box-deref] +### `Box` vs other `Deref` implementations + +The implementation of the [`Deref`] trait for [`Box`] is treated differently from other `Deref` implementations, as it is considered a special entity. + +For example, let us look at examples involving `Rc` and `Box`. The `*rc` is desugared to a call to the trait method `deref` defined on `Rc`, but since `*box` is treated differently, it is possible to do a precise capture of the contents of the `Box`. + +[`Box`]: ../special-types-and-traits.md#boxt +[`Deref`]: ../special-types-and-traits.md#deref-and-derefmut + +r[type.closure.capture.precision.box-non-move.not-moved] +#### `Box` with non-`move` closure + +In a non-`move` closure, if the contents of the `Box` are not moved into the closure body, the contents of the `Box` are precisely captured. + +```rust +struct S(String); + +let b = Box::new(S(String::new())); +let c_box = || { + let x = &(*b).0; // captures `(*b).0` by ImmBorrow +}; +c_box(); + +// Contrast `Box` with another type that implements Deref: +let r = std::rc::Rc::new(S(String::new())); +let c_rc = || { + let x = &(*r).0; // captures `r` by ImmBorrow +}; +c_rc(); +``` + +r[type.closure.capture.precision.box-non-move.moved] +However, if the contents of the `Box` are moved into the closure, then the box is entirely captured. This is done so the amount of data that needs to be moved into the closure is minimized. + +```rust +// This is the same as the example above except the closure +// moves the value instead of taking a reference to it. + +struct S(String); + +let b = Box::new(S(String::new())); +let c_box = || { + let x = (*b).0; // captures `b` with ByValue +}; +c_box(); +``` + +r[type.closure.capture.precision.box-move.read] +#### `Box` with move closure + +Similarly to moving contents of a `Box` in a non-`move` closure, reading the contents of a `Box` in a `move` closure will capture the `Box` entirely. + +```rust +struct S(i32); + +let b = Box::new(S(10)); +let c_box = move || { + let x = (*b).0; // captures `b` with ByValue +}; +``` + +r[type.closure.unique-immutable] +## Unique immutable borrows in captures + +Captures can occur by a special kind of borrow called a _unique immutable borrow_, which cannot be used anywhere else in the language and cannot be written out explicitly. It occurs when modifying the referent of a mutable reference, as in the following example: + +```rust +let mut b = false; +let x = &mut b; +let mut c = || { + // An ImmBorrow and a MutBorrow of `x`. + let a = &x; + *x = true; // `x` captured by UniqueImmBorrow +}; +// The following line is an error: +// let y = &x; +c(); +// However, the following is OK. +let z = &x; +``` + +In this case, borrowing `x` mutably is not possible, because `x` is not `mut`. But at the same time, borrowing `x` immutably would make the assignment illegal, because a `& &mut` reference might not be unique, so it cannot safely be used to modify a value. So a unique immutable borrow is used: it borrows `x` immutably, but like a mutable borrow, it must be unique. + +In the above example, uncommenting the declaration of `y` will produce an error because it would violate the uniqueness of the closure's borrow of `x`; the declaration of z is valid because the closure's lifetime has expired at the end of the block, releasing the borrow. + +r[type.closure.call] +## Call traits and coercions + +r[type.closure.call.intro] +Closure types all implement [`FnOnce`], indicating that they can be called once by consuming ownership of the closure. Additionally, some closures implement more specific call traits: + +r[type.closure.call.fn-mut] +* A closure which does not move out of any captured variables implements [`FnMut`], indicating that it can be called by mutable reference. + +r[type.closure.call.fn] +* A closure which does not mutate or move out of any captured variables implements [`Fn`], indicating that it can be called by shared reference. + +> [!NOTE] +> `move` closures may still implement [`Fn`] or [`FnMut`], even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them. + +r[type.closure.non-capturing] +*Non-capturing closures* are closures that don't capture anything from their environment. Non-async, non-capturing closures can be coerced to function pointers (e.g., `fn()`) with the matching signature. + +```rust +let add = |x, y| x + y; + +let mut x = add(5,7); + +type Binop = fn(i32, i32) -> i32; +let bo: Binop = add; +x = bo(5,7); +``` + +r[type.closure.async.traits] +### Async closure traits + +r[type.closure.async.traits.fn-family] +Async closures have a further restriction of whether or not they implement [`FnMut`] or [`Fn`]. + +The [`Future`] returned by the async closure has similar capturing characteristics as a closure. It captures place expressions from the async closure based on how they are used. The async closure is said to be *lending* to its [`Future`] if it has either of the following properties: + +- The `Future` includes a mutable capture. +- The async closure captures by value, except when the value is accessed with a dereference projection. + +If the async closure is lending to its `Future`, then [`FnMut`] and [`Fn`] are *not* implemented. [`FnOnce`] is always implemented. + +> **Example**: The first clause for a mutable capture can be illustrated with the following: +> +> ```rust,compile_fail +> fn takes_callback<Fut: Future>(c: impl FnMut() -> Fut) {} +> +> fn f() { +> let mut x = 1i32; +> let c = async || { +> x = 2; // x captured with MutBorrow +> }; +> takes_callback(c); // ERROR: async closure does not implement `FnMut` +> } +> ``` +> +> The second clause for a regular value capture can be illustrated with the following: +> +> ```rust,compile_fail +> fn takes_callback<Fut: Future>(c: impl Fn() -> Fut) {} +> +> fn f() { +> let x = &1i32; +> let c = async move || { +> let a = x + 2; // x captured ByValue +> }; +> takes_callback(c); // ERROR: async closure does not implement `Fn` +> } +> ``` +> +> The exception of the the second clause can be illustrated by using a dereference, which does allow `Fn` and `FnMut` to be implemented: +> +> ```rust +> fn takes_callback<Fut: Future>(c: impl Fn() -> Fut) {} +> +> fn f() { +> let x = &1i32; +> let c = async move || { +> let a = *x + 2; +> }; +> takes_callback(c); // OK: implements `Fn` +> } +> ``` + +r[type.closure.async.traits.async-family] +Async closures implement [`AsyncFn`], [`AsyncFnMut`], and [`AsyncFnOnce`] in an analogous way as regular closures implement [`Fn`], [`FnMut`], and [`FnOnce`]; that is, depending on the use of the captured variables in its body. + +r[type.closure.traits] +### Other traits + +r[type.closure.traits.intro] +All closure types implement [`Sized`]. Additionally, closure types implement the following traits if allowed to do so by the types of the captures it stores: + +* [`Clone`] +* [`Copy`] +* [`Sync`] +* [`Send`] + +r[type.closure.traits.behavior] +The rules for [`Send`] and [`Sync`] match those for normal struct types, while [`Clone`] and [`Copy`] behave as if [derived]. For [`Clone`], the order of cloning of the captured values is left unspecified. + +Because captures are often by reference, the following general rules arise: + +* A closure is [`Sync`] if all captured values are [`Sync`]. +* A closure is [`Send`] if all values captured by non-unique immutable reference are [`Sync`], and all values captured by unique immutable or mutable reference, copy, or move are [`Send`]. +* A closure is [`Clone`] or [`Copy`] if it does not capture any values by unique immutable or mutable reference, and if all values it captures by copy or move are [`Clone`] or [`Copy`], respectively. + +[`Clone`]: ../special-types-and-traits.md#clone +[`Copy`]: ../special-types-and-traits.md#copy +[`Send`]: ../special-types-and-traits.md#send +[`Sized`]: ../special-types-and-traits.md#sized +[`Sync`]: ../special-types-and-traits.md#sync +[closure expression]: ../expressions/closure-expr.md +[derived]: ../attributes/derive.md + +r[type.closure.drop-order] +## Drop order + +If a closure captures a field of a composite types such as structs, tuples, and enums by value, the field's lifetime would now be tied to the closure. As a result, it is possible for disjoint fields of a composite types to be dropped at different times. + +```rust +{ + let tuple = + (String::from("foo"), String::from("bar")); // --+ + { // | + let c = || { // ----------------------------+ | + // tuple.0 is captured into the closure | | + drop(tuple.0); // | | + }; // | | + } // 'c' and 'tuple.0' dropped here ------------+ | +} // tuple.1 dropped here -----------------------------+ +``` + +r[type.closure.capture.precision.edition2018.entirety] +## Edition 2018 and before + +### Closure types difference + +In Edition 2018 and before, closures always capture a variable in its entirety, without its precise capture path. This means that for the example used in the [Closure types](#closure-types) section, the generated closure type would instead look something like this: + +<!-- ignore: simplified --> +```rust,ignore +struct Closure<'a> { + rect : &'a mut Rectangle, +} + +impl<'a> FnOnce<()> for Closure<'a> { + type Output = String; + extern "rust-call" fn call_once(self, args: ()) -> String { + self.rect.left_top.x += 1; + self.rect.right_bottom.x += 1; + format!("{:?}", self.rect.left_top) + } +} +``` + +and the call to `f` would work as follows: + +<!-- ignore: continuation of above --> +```rust,ignore +f(Closure { rect: rect }); +``` + +r[type.closure.capture.precision.edition2018.composite] +### Capture precision difference + +Composite types such as structs, tuples, and enums are always captured in its entirety, not by individual fields. As a result, it may be necessary to borrow into a local variable in order to capture a single field: + +```rust +# use std::collections::HashSet; +# +struct SetVec { + set: HashSet<u32>, + vec: Vec<u32> +} + +impl SetVec { + fn populate(&mut self) { + let vec = &mut self.vec; + self.set.iter().for_each(|&n| { + vec.push(n); + }) + } +} +``` + +If, instead, the closure were to use `self.vec` directly, then it would attempt to capture `self` by mutable reference. But since `self.set` is already borrowed to iterate over, the code would not compile. + +r[type.closure.capture.precision.edition2018.move] +If the `move` keyword is used, then all captures are by move or, for `Copy` types, by copy, regardless of whether a borrow would work. The `move` keyword is usually used to allow the closure to outlive the captured values, such as if the closure is being returned or used to spawn a new thread. + +r[type.closure.capture.precision.edition2018.wildcard] +Regardless of if the data will be read by the closure, i.e. in case of wild card patterns, if a variable defined outside the closure is mentioned within the closure the variable will be captured in its entirety. + +r[type.closure.capture.precision.edition2018.drop-order] +### Drop order difference + +As composite types are captured in their entirety, a closure which captures one of those composite types by value would drop the entire captured variable at the same time as the closure gets dropped. + +```rust +{ + let tuple = + (String::from("foo"), String::from("bar")); + { + let c = || { // --------------------------+ + // tuple is captured into the closure | + drop(tuple.0); // | + }; // | + } // 'c' and 'tuple' dropped here ------------+ +} +``` diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/enum.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/enum.md new file mode 100644 index 00000000..8fa2dfd9 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/enum.md @@ -0,0 +1,22 @@ +r[type.enum] +# Enumerated types + +r[type.enum.intro] +An *enumerated type* is a nominal, heterogeneous disjoint union type, denoted by the name of an [`enum` item]. [^enumtype] + +r[type.enum.declaration] +An [`enum` item] declares both the type and a number of *variants*, each of which is independently named and has the syntax of a struct, tuple struct or unit-like struct. + +r[type.enum.constructor] +New instances of an `enum` can be constructed with a [struct expression]. + +r[type.enum.value] +Any `enum` value consumes as much memory as the largest variant for its corresponding `enum` type, as well as the size needed to store a discriminant. + +r[type.enum.name] +Enum types cannot be denoted *structurally* as types, but must be denoted by named reference to an [`enum` item]. + +[^enumtype]: The `enum` type is analogous to a `data` constructor declaration in Haskell, or a *pick ADT* in Limbo. + +[`enum` item]: ../items/enumerations.md +[struct expression]: ../expressions/struct-expr.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/function-item.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/function-item.md new file mode 100644 index 00000000..1be2efa1 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/function-item.md @@ -0,0 +1,54 @@ +r[type.fn-item] +# Function item types + +r[type.fn-item.intro] +When referred to, a function item, or the constructor of a tuple-like struct or enum variant, yields a [zero-sized] value of its _function item type_. + +r[type.fn-item.unique] +That type explicitly identifies the function - its name, its type arguments, and its early-bound lifetime arguments (but not its late-bound lifetime arguments, which are only assigned when the function is called) - so the value does not need to contain an actual function pointer, and no indirection is needed when the function is called. + +r[type.fn-item.name] +There is no syntax that directly refers to a function item type, but the compiler will display the type as something like `fn(u32) -> i32 {fn_name}` in error messages. + +Because the function item type explicitly identifies the function, the item types of different functions - different items, or the same item with different generics - are distinct, and mixing them will create a type error: + +```rust,compile_fail,E0308 +fn foo<T>() { } +let x = &mut foo::<i32>; +*x = foo::<u32>; //~ ERROR mismatched types +``` + +r[type.fn-item.coercion] +However, there is a [coercion] from function items to [function pointers] with the same signature, which is triggered not only when a function item is used when a function pointer is directly expected, but also when different function item types with the same signature meet in different arms of the same `if` or `match`: + +```rust +# let want_i32 = false; +# fn foo<T>() { } + +// `foo_ptr_1` has function pointer type `fn()` here +let foo_ptr_1: fn() = foo::<i32>; + +// ... and so does `foo_ptr_2` - this type-checks. +let foo_ptr_2 = if want_i32 { + foo::<i32> +} else { + foo::<u32> +}; +``` + +r[type.fn-item.traits] +All function items implement [`Copy`], [`Clone`], [`Send`], and [`Sync`]. + +[`Fn`], [`FnMut`], and [`FnOnce`] are implemented unless the function has any of the following: + +- an [`unsafe`][unsafe.fn] qualifier +- a [`target_feature` attribute][attributes.codegen.target_feature] +- an [ABI][items.fn.extern] other than `"Rust"` + +[`Clone`]: ../special-types-and-traits.md#clone +[`Copy`]: ../special-types-and-traits.md#copy +[`Send`]: ../special-types-and-traits.md#send +[`Sync`]: ../special-types-and-traits.md#sync +[coercion]: ../type-coercions.md +[function pointers]: function-pointer.md +[zero-sized]: glossary.zst diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/function-pointer.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/function-pointer.md new file mode 100644 index 00000000..70db4965 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/function-pointer.md @@ -0,0 +1,66 @@ +r[type.fn-pointer] +# Function pointer types + +r[type.fn-pointer.syntax] +```grammar,types +BareFunctionType -> + ForLifetimes? FunctionTypeQualifiers `fn` + `(` FunctionParametersMaybeNamedVariadic? `)` BareFunctionReturnType? + +FunctionTypeQualifiers -> `unsafe`? (`extern` Abi?)? + +BareFunctionReturnType -> `->` TypeNoBounds + +FunctionParametersMaybeNamedVariadic -> + MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic + +MaybeNamedFunctionParameters -> + MaybeNamedParam ( `,` MaybeNamedParam )* `,`? + +MaybeNamedParam -> + OuterAttribute* ( ( IDENTIFIER | `_` ) `:` )? Type + +MaybeNamedFunctionParametersVariadic -> + ( MaybeNamedParam `,` )* MaybeNamedParam `,` OuterAttribute* `...` +``` + +r[type.fn-pointer.intro] +A function pointer type, written using the `fn` keyword, refers to a function whose identity is not necessarily known at compile-time. + +An example where `Binop` is defined as a function pointer type: + +```rust +fn add(x: i32, y: i32) -> i32 { + x + y +} + +let mut x = add(5,7); + +type Binop = fn(i32, i32) -> i32; +let bo: Binop = add; +x = bo(5,7); +``` + +r[type.fn-pointer.coercion] +Function pointers can be created via a coercion from both [function items] and non-capturing, non-async [closures]. + +r[type.fn-pointer.qualifiers] +The `unsafe` qualifier indicates that the type's value is an [unsafe function], and the `extern` qualifier indicates it is an [extern function]. + +r[type.fn-pointer.constraint-variadic] +For the function to be variadic, its `extern` ABI must be one of those listed in [items.extern.variadic.conventions]. + +r[type.fn-pointer.extern-custom] +An `extern "custom"` function pointer must follow the rules in [items.fn.extern.custom.signature]. + +r[type.fn-pointer.attributes] +## Attributes on function pointer parameters + +Attributes on function pointer parameters follow the same rules and restrictions as [regular function parameters]. + +[`extern`]: ../items/external-blocks.md +[closures]: closure.md +[extern function]: ../items/functions.md#extern-function-qualifier +[function items]: function-item.md +[unsafe function]: ../unsafe-keyword.md +[regular function parameters]: ../items/functions.md#attributes-on-function-parameters diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/impl-trait.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/impl-trait.md new file mode 100644 index 00000000..e5f05a4d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/impl-trait.md @@ -0,0 +1,176 @@ +r[type.impl-trait] +# Impl trait + +r[type.impl-trait.syntax] +```grammar,types +ImplTraitType -> `impl` Bounds? + +ImplTraitTypeOneBound -> `impl` TraitBound? +``` + +r[type.impl-trait.intro] +`impl Trait` provides ways to specify unnamed but concrete types that implement a specific trait. It can appear in two sorts of places: argument position (where it can act as an anonymous type parameter to functions), and return position (where it can act as an abstract return type). + +```rust +trait Trait {} +# impl Trait for () {} + +// argument position: anonymous type parameter +fn foo(arg: impl Trait) { +} + +// return position: abstract return type +fn bar() -> impl Trait { +} +``` + +r[type.impl-trait.bounds] +There must be at least one trait bound, no more than one `use<..>` bound, and no more than one opt-out bound (e.g., `?Sized`). + +r[type.impl-trait.param] +## Anonymous type parameters + +r[type.impl-trait.param.intro] +> [!NOTE] +> This is often called "impl Trait in argument position". (The term "parameter" is more correct here, but "impl Trait in argument position" is the phrasing used during the development of this feature, and it remains in parts of the implementation.) + +Functions can use `impl` followed by a set of trait bounds to declare a parameter as having an anonymous type. The caller must provide a type that satisfies the bounds declared by the anonymous type parameter, and the function can only use the methods available through the trait bounds of the anonymous type parameter. + +For example, these two forms are almost equivalent: + +```rust +trait Trait {} + +// generic type parameter +fn with_generic_type<T: Trait>(arg: T) { +} + +// impl Trait in argument position +fn with_impl_trait(arg: impl Trait) { +} +``` + +r[type.impl-trait.param.generic] +That is, `impl Trait` in argument position is syntactic sugar for a generic type parameter like `<T: Trait>`, except that the type is anonymous and doesn't appear in the [GenericParams] list. + +> [!NOTE] +> For function parameters, generic type parameters and `impl Trait` are not exactly equivalent. With a generic parameter such as `<T: Trait>`, the caller has the option to explicitly specify the generic argument for `T` at the call site using [GenericArgs], for example, `foo::<usize>(1)`. Changing a parameter from either one to the other can constitute a breaking change for the callers of a function, since this changes the number of generic arguments. + +r[type.impl-trait.return] +## Abstract return types + +r[type.impl-trait.return.intro] +> [!NOTE] +> This is often called "impl Trait in return position". + +Functions can use `impl Trait` to return an abstract return type. These types stand in for another concrete type where the caller may only use the methods declared by the specified `Trait`. + +r[type.impl-trait.return.constraint-body] +Each possible return value from the function must resolve to the same concrete type. + +`impl Trait` in return position allows a function to return an unboxed abstract type. This is particularly useful with [closures] and iterators. For example, closures have a unique, un-writable type. Previously, the only way to return a closure from a function was to use a [trait object]: + +```rust +fn returns_closure() -> Box<dyn Fn(i32) -> i32> { + Box::new(|x| x + 1) +} +``` + +This could incur performance penalties from heap allocation and dynamic dispatch. It wasn't possible to fully specify the type of the closure, only to use the `Fn` trait. That means that the trait object is necessary. However, with `impl Trait`, it is possible to write this more simply: + +```rust +fn returns_closure() -> impl Fn(i32) -> i32 { + |x| x + 1 +} +``` + +which also avoids the drawbacks of using a boxed trait object. + +Similarly, the concrete types of iterators could become very complex, incorporating the types of all previous iterators in a chain. Returning `impl Iterator` means that a function only exposes the `Iterator` trait as a bound on its return type, instead of explicitly specifying all of the other iterator types involved. + +r[type.impl-trait.return-in-trait] +## Return-position `impl Trait` in traits and trait implementations + +r[type.impl-trait.return-in-trait.intro] +Functions in traits may also use `impl Trait` as a syntax for an anonymous associated type. + +r[type.impl-trait.return-in-trait.desugaring] +Every `impl Trait` in the return type of an associated function in a trait is desugared to an anonymous associated type. The return type that appears in the implementation's function signature is used to determine the value of the associated type. + +r[type.impl-trait.generic-captures] +## Capturing + +Behind each return-position `impl Trait` abstract type is some hidden concrete type. For this concrete type to use a generic parameter, that generic parameter must be *captured* by the abstract type. + +r[type.impl-trait.generic-capture.auto] +## Automatic capturing + +r[type.impl-trait.generic-capture.auto.intro] +Return-position `impl Trait` abstract types automatically capture all in-scope generic parameters, including generic type, const, and lifetime parameters (including higher-ranked ones). + +r[type.impl-trait.generic-capture.edition2024] +> [!EDITION-2024] +> Before the 2024 edition, on free functions and on associated functions and methods of inherent impls, generic lifetime parameters that do not appear in the bounds of the abstract return type are not automatically captured. + +r[type.impl-trait.generic-capture.precise] +## Precise capturing + +r[type.impl-trait.generic-capture.precise.use] +The set of generic parameters captured by a return-position `impl Trait` abstract type may be explicitly controlled with a [`use<..>` bound]. If present, only the generic parameters listed in the `use<..>` bound will be captured. E.g.: + +```rust +fn capture<'a, 'b, T>(x: &'a (), y: T) -> impl Sized + use<'a, T> { + // ~~~~~~~~~~~~~~~~~~~~~~~ + // Captures `'a` and `T` only. + (x, y) +} +``` + +r[type.impl-trait.generic-capture.precise.constraint-single] +Currently, only one `use<..>` bound may be present in a bounds list, all in-scope type and const generic parameters must be included, and all lifetime parameters that appear in other bounds of the abstract type must be included. + +r[type.impl-trait.generic-capture.precise.constraint-lifetime] +Within the `use<..>` bound, any lifetime parameters present must appear before all type and const generic parameters, and the elided lifetime (`'_`) may be present if it is otherwise allowed to appear within the `impl Trait` return type. + +r[type.impl-trait.generic-capture.precise.constraint-param-impl-trait] +Because all in-scope type parameters must be included by name, a `use<..>` bound may not be used in the signature of items that use argument-position `impl Trait`, as those items have anonymous type parameters in scope. + +r[type.impl-trait.generic-capture.precise.constraint-in-trait] +Any `use<..>` bound that is present in an associated function in a trait definition must include all generic parameters of the trait, including the implicit `Self` generic type parameter of the trait. + +## Differences between generics and `impl Trait` in return position + +In argument position, `impl Trait` is very similar in semantics to a generic type parameter. However, there are significant differences between the two in return position. With `impl Trait`, unlike with a generic type parameter, the function chooses the return type, and the caller cannot choose the return type. + +The function: + +```rust +# trait Trait {} +fn foo<T: Trait>() -> T { + // ... +# panic!() +} +``` + +allows the caller to determine the return type, `T`, and the function returns that type. + +The function: + +```rust +# trait Trait {} +# impl Trait for () {} +fn foo() -> impl Trait { + // ... +} +``` + +doesn't allow the caller to determine the return type. Instead, the function chooses the return type, but only promises that it will implement `Trait`. + +r[type.impl-trait.constraint] +## Limitations + +`impl Trait` can only appear as a parameter or return type of a non-`extern` function. It cannot be the type of a `let` binding, field type, or appear inside a type alias. + +[`use<..>` bound]: ../trait-bounds.md#use-bounds +[closures]: closure.md +[trait object]: trait-object.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/inferred.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/inferred.md new file mode 100644 index 00000000..fcbb149e --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/inferred.md @@ -0,0 +1,26 @@ +r[type.inferred] +# Inferred type + +r[type.inferred.syntax] +```grammar,types +InferredType -> `_` +``` + +r[type.inferred.intro] +The inferred type asks the compiler to infer the type if possible based on the surrounding information available. + +> [!EXAMPLE] +> The inferred type is often used in generic arguments: +> +> ```rust +> let x: Vec<_> = (0..10).collect(); +> ``` + +r[type.inferred.constraint] +The inferred type cannot be used in item signatures. + +<!-- + What else should be said here? + The only documentation I am aware of is https://rustc-dev-guide.rust-lang.org/type-inference.html + There should be a broader discussion of type inference somewhere. +--> diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/never.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/never.md new file mode 100644 index 00000000..414862fe --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/never.md @@ -0,0 +1,58 @@ +r[type.never] +# Never type + +r[type.never.intro] +The never type `!` is a type with no values, representing computations that never complete, also known as [diverging][divergence] computations. + +> [!EXAMPLE] +> ```rust +> fn foo() -> ! { +> loop {} +> } +> ``` +> +> ```rust +> unsafe extern "C" { +> pub safe fn no_return_extern_func() -> !; +> } +> ``` +> +> ```rust,no_run +> let _: ! = loop {}; +> ``` +> +> ```rust +> fn always_ok() -> Result<u32, !> { +> Ok(42) +> } +> ``` +> +> ```rust +> # use std::str::FromStr; +> struct Anything(String); +> +> impl FromStr for Anything { +> type Err = !; +> +> fn from_str(s: &str) -> Result<Self, !> { +> Ok(Anything(s.to_owned())) +> } +> } +> +> // This does not need to check for the `Err` variant because +> // `FromStr::Err` is the never type. +> let Ok(s) = Anything::from_str("example"); +> ``` + +r[type.never.syntax] +```grammar,types +NeverType -> `!` +``` + +r[type.never.coercion] +Expressions of type `!` can be coerced into any type. + +> [!NOTE] +> The standard library type [`Infallible`] is a type alias for `!`. + +[`Infallible`]: core::convert::Infallible diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/numeric.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/numeric.md new file mode 100644 index 00000000..ec7309b7 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/numeric.md @@ -0,0 +1,57 @@ +r[type.numeric] +# Numeric types + +r[type.numeric.int] +## Integer types + +r[type.numeric.int.unsigned] +The unsigned integer types consist of: + +Type | Minimum | Maximum +-------|---------|------------------- +`u8` | 0 | 2<sup>8</sup>-1 +`u16` | 0 | 2<sup>16</sup>-1 +`u32` | 0 | 2<sup>32</sup>-1 +`u64` | 0 | 2<sup>64</sup>-1 +`u128` | 0 | 2<sup>128</sup>-1 + +r[type.numeric.int.signed] +The signed two's complement integer types consist of: + +Type | Minimum | Maximum +-------|--------------------|------------------- +`i8` | -(2<sup>7</sup>) | 2<sup>7</sup>-1 +`i16` | -(2<sup>15</sup>) | 2<sup>15</sup>-1 +`i32` | -(2<sup>31</sup>) | 2<sup>31</sup>-1 +`i64` | -(2<sup>63</sup>) | 2<sup>63</sup>-1 +`i128` | -(2<sup>127</sup>) | 2<sup>127</sup>-1 + +r[type.numeric.float] +## Floating-point types + +The IEEE 754-2008 "binary32" and "binary64" floating-point types are `f32` and `f64`, respectively. + +r[type.numeric.int.size] +## Machine-dependent integer types + +r[type.numeric.int.size.usize] +The `usize` type is an unsigned integer type with the same number of bits as the platform's pointer type. It can represent every memory address in the process. + +> [!NOTE] +> While a `usize` can represent every *address*, converting a *pointer* to a `usize` is not necessarily a reversible operation. For more information, see the documentation for [type cast expressions], [`std::ptr`], and [provenance][std::ptr#provenance] in particular. + +r[type.numeric.int.size.isize] +The `isize` type is a signed two's complement integer type with the same number of bits as the platform's pointer type. The theoretical upper bound on object and array size is the maximum `isize` value. This ensures that `isize` can be used to calculate differences between pointers into an object or array and can address every byte within an object along with one byte past the end. + +r[type.numeric.int.size.minimum] +`usize` and `isize` are at least 16-bits wide. + +> [!NOTE] +> Many pieces of Rust code may assume that pointers, `usize`, and `isize` are either 32-bit or 64-bit. As a consequence, 16-bit pointer support is limited and may require explicit care and acknowledgment from a library to support. + +r[type.numeric.validity] +## Bit validity + +For every numeric type, `T`, the bit validity of `T` is equivalent to the bit validity of `[u8; size_of::<T>()]`. An uninitialized byte is not a valid `u8`. + +[type cast expressions]: ../expressions/operator-expr.md#type-cast-expressions diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/parameters.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/parameters.md new file mode 100644 index 00000000..88932f86 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/parameters.md @@ -0,0 +1,18 @@ +r[type.generic] +# Type parameters + +Within the body of an item that has type parameter declarations, the names of its type parameters are types: + +```rust +fn to_vec<A: Clone>(xs: &[A]) -> Vec<A> { + if xs.is_empty() { + return vec![]; + } + let first: A = xs[0].clone(); + let mut rest: Vec<A> = to_vec(&xs[1..]); + rest.insert(0, first); + rest +} +``` + +Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and `rest` has type `Vec<A>`, a vector with element type `A`. diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/pointer.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/pointer.md new file mode 100644 index 00000000..ffd234a3 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/pointer.md @@ -0,0 +1,79 @@ +r[type.pointer] +# Pointer types + +r[type.pointer.intro] +All pointers are explicit first-class values. They can be moved or copied, stored into data structs, and returned from functions. + +r[type.pointer.reference] +## References (`&` and `&mut`) + +r[type.pointer.reference.syntax] +```grammar,types +ReferenceType -> `&` Lifetime? `mut`? TypeNoBounds +``` + +r[type.pointer.reference.shared] +### Shared references (`&`) + +r[type.pointer.reference.shared.intro] +Shared references point to memory which is owned by some other value. + +r[type.pointer.reference.shared.constraint-mutation] +When a shared reference to a value is created, it prevents direct mutation of the value. [Interior mutability] provides an exception for this in certain circumstances. As the name suggests, any number of shared references to a value may exist. A shared reference type is written `&type`, or `&'a type` when you need to specify an explicit lifetime. + +r[type.pointer.reference.shared.copy] +Copying a reference is a "shallow" operation: it involves only copying the pointer itself, that is, pointers are `Copy`. Releasing a reference has no effect on the value it points to, but referencing of a [temporary value] will keep it alive during the scope of the reference itself. + +r[type.pointer.reference.mut] +### Mutable references (`&mut`) + +r[type.pointer.reference.mut.intro] +Mutable references point to memory which is owned by some other value. A mutable reference type is written `&mut type` or `&'a mut type`. + +r[type.pointer.reference.mut.copy] +A mutable reference (that hasn't been borrowed) is the only way to access the value it points to, so is not `Copy`. + +r[type.pointer.raw] +## Raw pointers (`*const` and `*mut`) + +r[type.pointer.raw.syntax] +```grammar,types +RawPointerType -> `*` ( `mut` | `const` ) TypeNoBounds +``` + +r[type.pointer.raw.intro] +Raw pointers are pointers without safety or liveness guarantees. Raw pointers are written as `*const T` or `*mut T`. For example `*const i32` means a raw pointer to a 32-bit integer. + +r[type.pointer.raw.copy] +Copying or dropping a raw pointer has no effect on the lifecycle of any other value. + +r[type.pointer.raw.safety] +Dereferencing a raw pointer is an [`unsafe` operation]. + +This can also be used to convert a raw pointer to a reference by reborrowing it (`&*` or `&mut *`). Raw pointers are generally discouraged; they exist to support interoperability with foreign code, and writing performance-critical or low-level functions. + +r[type.pointer.raw.cmp] +When comparing raw pointers they are compared by their address, rather than by what they point to. When comparing raw pointers to [dynamically sized types] they also have their additional data compared. + +r[type.pointer.raw.constructor] +Raw pointers can be created directly using `&raw const` for `*const` pointers and `&raw mut` for `*mut` pointers. + +r[type.pointer.smart] +## Smart pointers + +The standard library contains additional 'smart pointer' types beyond references and raw pointers. + +r[type.pointer.validity] +## Bit validity + +r[type.pointer.validity.pointer-fragment] +Despite pointers and references being similar to `usize`s in the machine code emitted on most platforms, the semantics of transmuting a reference or pointer type to a non-pointer type is currently undecided. Thus, it may not be valid to transmute a pointer or reference type, `P`, to a `[u8; size_of::<P>()]`. + +r[type.pointer.validity.raw] +For thin raw pointers (i.e., for `P = *const T` or `P = *mut T` for `T: Sized`), the inverse direction (transmuting from an integer or array of integers to `P`) is always valid. However, the pointer produced via such a transmutation may not be dereferenced (not even if `T` has [size zero]). + +[Interior mutability]: ../interior-mutability.md +[`unsafe` operation]: ../unsafety.md +[dynamically sized types]: ../dynamically-sized-types.md +[size zero]: glossary.zst +[temporary value]: ../expressions.md#temporaries diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/slice.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/slice.md new file mode 100644 index 00000000..e8be3a9f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/slice.md @@ -0,0 +1,32 @@ +r[type.slice] +# Slice types + +r[type.slice.syntax] +```grammar,types +SliceType -> `[` Type `]` +``` + +r[type.slice.intro] +A slice is a [dynamically sized type] representing a 'view' into a sequence of elements of type `T`. The slice type is written as `[T]`. + +r[type.slice.unsized] +Slice types are generally used through pointer types. For example: + +* `&[T]`: a 'shared slice', often just called a 'slice'. It doesn't own the data it points to; it borrows it. +* `&mut [T]`: a 'mutable slice'. It mutably borrows the data it points to. +* `Box<[T]>`: a 'boxed slice' + +Examples: + +```rust +// A heap-allocated array, coerced to a slice +let boxed_array: Box<[i32]> = Box::new([1, 2, 3]); + +// A (shared) slice into an array +let slice: &[i32] = &boxed_array[..]; +``` + +r[type.slice.safe] +All elements of slices are always initialized, and access to a slice is always bounds-checked in safe methods and operators. + +[dynamically sized type]: ../dynamically-sized-types.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/str.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/str.md new file mode 100644 index 00000000..cf730fce --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/str.md @@ -0,0 +1,25 @@ +r[type.str] +# String slice type + +r[type.str.intro] +The string slice (`str`) type represents a sequence of characters. + +```rust +let greeting1: &str = "Hello, world!"; +let greeting2: &str = "你好,世界"; +``` + +> [!NOTE] +> See [the standard library docs][`str`] for information on the impls of the `str` type. + +r[type.str.value] +A value of type `str` is represented in the same way as `[u8]`, a slice of 8-bit unsigned bytes. + +> [!NOTE] +> The standard library makes extra assumptions about `str`: methods working on `str` assume and ensure that the data it contains is valid UTF-8. Calling a `str` method with a non-UTF-8 buffer can cause [undefined behavior] now or in the future. + +r[type.str.unsized] +A `str` is a [dynamically sized type]. It can only be instantiated through a pointer type, such as `&str`. The layout of `&str` is the same as the layout of `&[u8]`. + +[undefined behavior]: ../behavior-considered-undefined.md +[dynamically sized type]: ../dynamically-sized-types.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/struct.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/struct.md new file mode 100644 index 00000000..3e0cf383 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/struct.md @@ -0,0 +1,26 @@ +r[type.struct] +# Struct types + +r[type.struct.intro] +A `struct` *type* is a heterogeneous product of other types, called the *fields* of the type.[^structtype] + +r[type.struct.constructor] +New instances of a `struct` can be constructed with a [struct expression]. + +r[type.struct.layout] +The memory layout of a `struct` is undefined by default to allow for compiler optimizations like field reordering, but it can be fixed with the [`repr` attribute]. In either case, fields may be given in any order in a corresponding struct *expression*; the resulting `struct` value will always have the same memory layout. + +r[type.struct.field-visibility] +The fields of a `struct` may be qualified by [visibility modifiers], to allow access to data in a struct outside a module. + +r[type.struct.tuple] +A _tuple struct_ type is just like a struct type, except that the fields are anonymous. + +r[type.struct.unit] +A _unit-like struct_ type is like a struct type, except that it has no fields. The one value constructed by the associated [struct expression] is the only value that inhabits such a type. + +[^structtype]: `struct` types are analogous to `struct` types in C, the *record* types of the ML family, or the *struct* types of the Lisp family. + +[`repr` attribute]: ../type-layout.md#representations +[struct expression]: ../expressions/struct-expr.md +[visibility modifiers]: ../visibility-and-privacy.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/trait-object.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/trait-object.md new file mode 100644 index 00000000..27303d0b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/trait-object.md @@ -0,0 +1,88 @@ +r[type.trait-object] +# Trait objects + +r[type.trait-object.syntax] +```grammar,types +TraitObjectType -> Bounds[^bare-2021] | `dyn`[^dyn-2018] Bounds? + +TraitObjectTypeOneBound -> TraitBound[^bare-2021] | `dyn`[^dyn-2018] TraitBound? +``` + +[^bare-2021]: See [type.trait-object.syntax-edition2021]. +[^dyn-2018]: See [type.trait-object.syntax-edition2018]. + +r[type.trait-object.intro] +A *trait object* is an opaque value of another type that implements a set of traits. The set of traits is made up of a [dyn compatible] *base trait* plus any number of [auto traits]. + +r[type.trait-object.impls] +Trait objects implement the base trait, its auto traits, and any [supertraits] of the base trait. + +r[type.trait-object.bounds] +There must be at least one trait bound, there may not be more than one non-auto trait, no more than one lifetime, and opt-out bounds (e.g., `?Sized`) and `use<..>` bounds are not allowed. + +For example, given a trait `Trait`, the following are all trait objects: + +* `dyn Trait` +* `dyn Trait + Send` +* `dyn Trait + Send + Sync` +* `dyn Trait + 'static` +* `dyn Trait + Send + 'static` +* `dyn Trait +` +* `dyn 'static + Trait`. +* `dyn (Trait)` + +r[type.trait-object.syntax-edition2021] +> [!EDITION-2021] +> Before the 2021 edition, the `dyn` keyword may be omitted. In the 2021 edition and beyond, the `dyn` keyword is required semantically. + +r[type.trait-object.syntax-edition2018] +> [!EDITION-2018] +> In the 2015 edition, `dyn` must be followed by [PathIdentSegment], [LIFETIME_TOKEN], `for`, `(` or `?` to be interpreted as a keyword instead of a regular identifier. +> +> Most notably, `dyn`, `dyn::T` and `dyn<T>` will all be treated as type paths. As such, if you want a trait object type with the trait `::module::Trait`, you need to put the path in parentheses and write it as `dyn (::module::Trait)`. +> +> Beginning in the 2018 edition, `dyn` is a true keyword and is not allowed in paths, so the parentheses are not necessary. + +r[type.trait-object.alias] +Two trait object types alias each other if the base traits alias each other and if the sets of auto traits are the same and the lifetime bounds are the same. For example, `dyn Trait + Send + UnwindSafe` is the same as `dyn Trait + UnwindSafe + Send`. + +r[type.trait-object.unsized] +Due to the opaqueness of which concrete type the value is of, trait objects are [dynamically sized types]. Like all <abbr title="dynamically sized types">DSTs</abbr>, trait objects are used behind some type of pointer; for example `&dyn SomeTrait` or `Box<dyn SomeTrait>`. Each instance of a pointer to a trait object includes: + + - a pointer to an instance of a type `T` that implements `SomeTrait` + - a _virtual method table_, often just called a _vtable_, which contains, for each method of `SomeTrait` and its [supertraits] that `T` implements, a pointer to `T`'s implementation (i.e. a function pointer). + +The purpose of trait objects is to permit "late binding" of methods. Calling a method on a trait object results in virtual dispatch at runtime: that is, a function pointer is loaded from the trait object vtable and invoked indirectly. The actual implementation for each vtable entry can vary on an object-by-object basis. + +An example of a trait object: + +```rust +trait Printable { + fn stringify(&self) -> String; +} + +impl Printable for i32 { + fn stringify(&self) -> String { self.to_string() } +} + +fn print(a: Box<dyn Printable>) { + println!("{}", a.stringify()); +} + +fn main() { + print(Box::new(10) as Box<dyn Printable>); +} +``` + +In this example, the trait `Printable` occurs as a trait object in both the type signature of `print`, and the cast expression in `main`. + +r[type.trait-object.lifetime-bounds] +## Trait object lifetime bounds + +Since a trait object can contain references, the lifetimes of those references need to be expressed as part of the trait object. This lifetime is written as `Trait + 'a`. There are [defaults] that allow this lifetime to usually be inferred with a sensible choice. + +[auto traits]: ../special-types-and-traits.md#auto-traits +[defaults]: ../lifetime-elision.md#default-trait-object-lifetimes +[dyn compatible]: ../items/traits.md#dyn-compatibility +[dynamically sized types]: ../dynamically-sized-types.md +[supertraits]: ../items/traits.md#supertraits diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/tuple.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/tuple.md new file mode 100644 index 00000000..9a190eaf --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/tuple.md @@ -0,0 +1,49 @@ +r[type.tuple] +# Tuple types + +r[type.tuple.syntax] +```grammar,types +TupleType -> + `(` `)` + | `(` ( Type `,` )+ Type? `)` +``` + +r[type.tuple.intro] +*Tuple types* are a family of structural types[^1] for heterogeneous lists of other types. + +The syntax for a tuple type is a parenthesized, comma-separated list of types. + +r[type.tuple.restriction] +1-ary tuples require a comma after their element type to be disambiguated with a [parenthesized type]. + +r[type.tuple.field-number] +A tuple type has a number of fields equal to the length of the list of types. This number of fields determines the *arity* of the tuple. A tuple with `n` fields is called an *n-ary tuple*. For example, a tuple with 2 fields is a 2-ary tuple. + +r[type.tuple.field-name] +Fields of tuples are named using increasing numeric names matching their position in the list of types. The first field is `0`. The second field is `1`. And so on. The type of each field is the type of the same position in the tuple's list of types. + +r[type.tuple.unit] +For convenience and historical reasons, the tuple type with no fields (`()`) is often called *unit* or *the unit type*. Its one value is also called *unit* or *the unit value*. + +Some examples of tuple types: + +* `()` (unit) +* `(i32,)` (1-ary tuple) +* `(f64, f64)` +* `(String, i32)` +* `(i32, String)` (different type from the previous example) +* `(i32, f64, Vec<String>, Option<bool>)` + +r[type.tuple.constructor] +Values of this type are constructed using a [tuple expression]. Furthermore, various expressions will produce the unit value if there is no other meaningful value for it to evaluate to. + +r[type.tuple.access] +Tuple fields can be accessed by either a [tuple index expression] or [pattern matching]. + +[^1]: Structural types are always equivalent if their internal types are equivalent. For a nominal version of tuples, see [tuple structs]. + +[parenthesized type]: ../types.md#parenthesized-types +[pattern matching]: ../patterns.md#tuple-patterns +[tuple expression]: ../expressions/tuple-expr.md#tuple-expressions +[tuple index expression]: ../expressions/tuple-expr.md#tuple-indexing-expressions +[tuple structs]: ./struct.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/types/union.md b/stdlib/kvlang/reference/rust/reference-repo/src/types/union.md new file mode 100644 index 00000000..3ba187d5 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/types/union.md @@ -0,0 +1,20 @@ +r[type.union] +# Union types + +r[type.union.intro] +A *union type* is a nominal, heterogeneous C-like union, denoted by the name of a [`union` item][item]. + +r[type.union.access] +Unions have no notion of an "active field". Instead, every union access transmutes parts of the content of the union to the type of the accessed field. + +r[type.union.safety] +Since transmutes can cause unexpected or undefined behaviour, `unsafe` is required to read from a union field. + +r[type.union.constraint] +Union field types are also restricted to a subset of types which ensures that they never need dropping. See the [item] documentation for further details. + +r[type.union.layout] +The memory layout of a `union` is undefined by default (in particular, fields do *not* have to be at offset 0), but the `#[repr(...)]` attribute can be used to fix a layout. + +[`Copy`]: ../special-types-and-traits.md#copy +[item]: ../items/unions.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/unsafe-keyword.md b/stdlib/kvlang/reference/rust/reference-repo/src/unsafe-keyword.md new file mode 100644 index 00000000..8c725390 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/unsafe-keyword.md @@ -0,0 +1,90 @@ +r[unsafe] +# The `unsafe` keyword + +r[unsafe.intro] +The `unsafe` keyword is used to create or discharge the obligation to prove something safe. Specifically: + +- It is used to mark code that *defines* extra safety conditions that must be upheld elsewhere. + - This includes `unsafe fn`, `unsafe static`, and `unsafe trait`. +- It is used to mark code that the programmer *asserts* satisfies safety conditions defined elsewhere. + - This includes `unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`, and `#[unsafe(attr)]`. + +The following discusses each of these cases. See the [keyword documentation][keyword] for some illustrative examples. + +r[unsafe.positions] +The `unsafe` keyword can occur in several different contexts: + +- unsafe functions (`unsafe fn`) +- unsafe blocks (`unsafe {}`) +- unsafe traits (`unsafe trait`) +- unsafe trait implementations (`unsafe impl`) +- unsafe external blocks (`unsafe extern`) +- unsafe external statics (`unsafe static`) +- unsafe attributes (`#[unsafe(attr)]`) + +r[unsafe.fn] +## Unsafe functions (`unsafe fn`) + +r[unsafe.fn.intro] +Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs. We say they have *extra safety conditions*, which are requirements that must be upheld by all callers and that the compiler does not check. For example, [`get_unchecked`] has the extra safety condition that the index must be in-bounds. The unsafe function should come with documentation explaining what those extra safety conditions are. + +r[unsafe.fn.safety] +Such a function must be prefixed with the keyword `unsafe` and can only be called from inside an `unsafe` block, or inside `unsafe fn` without the [`unsafe_op_in_unsafe_fn`] lint. + +r[unsafe.block] +## Unsafe blocks (`unsafe {}`) + +r[unsafe.block.intro] +A block of code can be prefixed with the `unsafe` keyword to permit using the unsafe actions as defined in the [Unsafety] chapter, such as calling other unsafe functions or dereferencing raw pointers. + +r[unsafe.block.fn-body] +By default, the body of an unsafe function is also considered to be an unsafe block; this can be changed by enabling the [`unsafe_op_in_unsafe_fn`] lint. + +By putting operations into an unsafe block, the programmer states that they have taken care of satisfying the extra safety conditions of all operations inside that block. + +Unsafe blocks are the logical dual to unsafe functions: where unsafe functions define a proof obligation that callers must uphold, unsafe blocks state that all relevant proof obligations of functions or operations called inside the block have been discharged. There are many ways to discharge proof obligations; for example, there could be run-time checks or data structure invariants that guarantee that certain properties are definitely true, or the unsafe block could be inside an `unsafe fn`, in which case the block can use the proof obligations of that function to discharge the proof obligations arising inside the block. + +Unsafe blocks are used to wrap foreign libraries, make direct use of hardware or implement features not directly present in the language. For example, Rust provides the language features necessary to implement memory-safe concurrency in the language but the implementation of threads and message passing in the standard library uses unsafe blocks. + +Rust's type system is a conservative approximation of the dynamic safety requirements, so in some cases there is a performance cost to using safe code. For example, a doubly-linked list is not a tree structure and can only be represented with reference-counted pointers in safe code. By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented without reference counting. (See ["Learn Rust With Entirely Too Many Linked Lists"](https://rust-unofficial.github.io/too-many-lists/) for a more in-depth exploration of this particular example.) + +[Unsafety]: unsafety.md + +r[unsafe.trait] +## Unsafe traits (`unsafe trait`) + +r[unsafe.trait.intro] +An unsafe trait is a trait that comes with extra safety conditions that must be upheld by *implementations* of the trait. The unsafe trait should come with documentation explaining what those extra safety conditions are. + +r[unsafe.trait.safety] +Such a trait must be prefixed with the keyword `unsafe` and can only be implemented by `unsafe impl` blocks. + +r[unsafe.impl] +## Unsafe trait implementations (`unsafe impl`) + +When implementing an unsafe trait, the implementation needs to be prefixed with the `unsafe` keyword. By writing `unsafe impl`, the programmer states that they have taken care of satisfying the extra safety conditions required by the trait. + +Unsafe trait implementations are the logical dual to unsafe traits: where unsafe traits define a proof obligation that implementations must uphold, unsafe implementations state that all relevant proof obligations have been discharged. + +[keyword]: ../std/keyword.unsafe.html +[`get_unchecked`]: slice::get_unchecked +[`unsafe_op_in_unsafe_fn`]: ../rustc/lints/listing/allowed-by-default.html#unsafe-op-in-unsafe-fn + +r[unsafe.extern] +## Unsafe external blocks (`unsafe extern`) + +r[unsafe.extern.intro] +The programmer who declares an [external block] must assure that the signatures of the items contained within are correct. Failing to do so may lead to undefined behavior. That this obligation has been met is indicated by writing `unsafe extern`. + +r[unsafe.extern.edition2024] +> [!EDITION-2024] +> Prior to edition 2024, `extern` blocks were allowed without being qualified as `unsafe`. + +[external block]: items/external-blocks.md + +r[unsafe.attribute] +## Unsafe attributes (`#[unsafe(attr)]`) + +An [unsafe attribute] is one that has extra safety conditions that must be upheld when using the attribute. The compiler cannot check whether these conditions have been upheld. To assert that they have been, these attributes must be wrapped in `unsafe(..)`, e.g. `#[unsafe(no_mangle)]`. + +[unsafe attribute]: attributes.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/unsafety.md b/stdlib/kvlang/reference/rust/reference-repo/src/unsafety.md new file mode 100644 index 00000000..2e3be722 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/unsafety.md @@ -0,0 +1,42 @@ +r[safety] +# Unsafety + +r[safety.intro] +Unsafe operations are those that can potentially violate the memory-safety guarantees of Rust's static semantics. + +r[safety.unsafe-ops] +The following language level features cannot be used in the safe subset of Rust: + +r[safety.unsafe-deref] +- Dereferencing a [raw pointer]. + +r[safety.unsafe-static] +- Reading or writing a [mutable] or unsafe [external] static variable. + +r[safety.unsafe-union-access] +- Accessing a field of a [`union`], other than to assign to it. + +r[safety.unsafe-call] +- Calling an unsafe function. + +r[safety.unsafe-target-feature-call] +- Calling a safe function marked with a [`target_feature`][attributes.codegen.target_feature] from a function that does not have a `target_feature` attribute enabling the same features (see [attributes.codegen.target_feature.safety-restrictions]). + +r[safety.unsafe-impl] +- Implementing an [unsafe trait]. + +r[safety.unsafe-extern] +- Declaring an [`extern`] block[^extern-2024]. + +r[safety.unsafe-attribute] +- Applying an [unsafe attribute] to an item. + +[^extern-2024]: Prior to the 2024 edition, extern blocks were allowed to be declared without `unsafe`. + +[`extern`]: items/external-blocks.md +[`union`]: items/unions.md +[mutable]: items/static-items.md#mutable-statics +[external]: items/external-blocks.md +[raw pointer]: types/pointer.md +[unsafe trait]: items/traits.md#unsafe-traits +[unsafe attribute]: attributes.md diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/variables.md b/stdlib/kvlang/reference/rust/reference-repo/src/variables.md new file mode 100644 index 00000000..e20e51e0 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/variables.md @@ -0,0 +1,39 @@ +r[variable] +# Variables + +r[variable.intro] +A _variable_ is a component of a stack frame, either a named function parameter, an anonymous [temporary](expressions.md#temporaries), or a named local variable. + +r[variable.local] +A _local variable_ (or *stack-local* allocation) holds a value directly, allocated within the stack's memory. The value is a part of the stack frame. + +r[variable.local-mut] +Local variables are immutable unless declared otherwise. For example: `let mut x = ...`. + +r[variable.param-mut] +Function parameters are immutable unless declared with `mut`. The `mut` keyword applies only to the following parameter. For example: `|mut x, y|` and `fn f(mut x: Box<i32>, y: Box<i32>)` declare one mutable variable `x` and one immutable variable `y`. + +r[variable.init] +Local variables are not initialized when allocated. Instead, the entire frame worth of local variables are allocated, on frame-entry, in an uninitialized state. Subsequent statements within a function may or may not initialize the local variables. Local variables can be used only after they have been initialized through all reachable control flow paths. + +In this next example, `init_after_if` is initialized after the [`if` expression] while `uninit_after_if` is not because it is not initialized in the `else` case. + +```rust +# fn random_bool() -> bool { true } +fn initialization_example() { + let init_after_if: (); + let uninit_after_if: (); + + if random_bool() { + init_after_if = (); + uninit_after_if = (); + } else { + init_after_if = (); + } + + init_after_if; // ok + // uninit_after_if; // err: use of possibly uninitialized `uninit_after_if` +} +``` + +[`if` expression]: expressions/if-expr.md#if-expressions diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/visibility-and-privacy.md b/stdlib/kvlang/reference/rust/reference-repo/src/visibility-and-privacy.md new file mode 100644 index 00000000..656b8a14 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/visibility-and-privacy.md @@ -0,0 +1,214 @@ +r[vis] +# Visibility and privacy + +r[vis.syntax] +```grammar,items +Visibility -> + `pub` + | `pub` `(` `crate` `)` + | `pub` `(` `self` `)` + | `pub` `(` `super` `)` + | `pub` `(` `in` SimplePath `)` +``` + +r[vis.intro] +These two terms are often used interchangeably, and what they are attempting to convey is the answer to the question "Can this item be used at this location?" + +r[vis.name-hierarchy] +Rust's name resolution operates on a global hierarchy of namespaces. Each level in the hierarchy can be thought of as some item. The items are one of those mentioned above, but also include external crates. Declaring or defining a new module can be thought of as inserting a new tree into the hierarchy at the location of the definition. + +r[vis.privacy] +To control whether interfaces can be used across modules, Rust checks each use of an item to see whether it should be allowed or not. This is where privacy warnings are generated, or otherwise "you used a private item of another module and weren't allowed to." + +r[vis.default] +By default, everything is *private*, with two exceptions: Associated items in a `pub` Trait are public by default; Enum variants in a `pub` enum are also public by default. When an item is declared as `pub`, it can be thought of as being accessible to the outside world. For example: + +```rust +# fn main() {} +// Declare a private struct +struct Foo; + +// Declare a public struct with a private field +pub struct Bar { + field: i32, +} + +// Declare a public enum with two public variants +pub enum State { + PubliclyAccessibleState, + PubliclyAccessibleState2, +} +``` + +r[vis.access] +With the notion of an item being either public or private, Rust allows item accesses in two cases: + +1. If an item is public, then it can be accessed externally from some module `m` if you can access all the item's ancestor modules from `m`. You can also potentially be able to name the item through re-exports. See below. +2. If an item is private, it may be accessed by the current module and its descendants. + +These two cases are surprisingly powerful for creating module hierarchies exposing public APIs while hiding internal implementation details. To help explain, here's a few use cases and what they would entail: + +* A library developer needs to expose functionality to crates which link against their library. As a consequence of the first case, this means that anything which is usable externally must be `pub` from the root down to the destination item. Any private item in the chain will disallow external accesses. + +* A crate needs a global available "helper module" to itself, but it doesn't want to expose the helper module as a public API. To accomplish this, the root of the crate's hierarchy would have a private module which then internally has a "public API". Because the entire crate is a descendant of the root, then the entire local crate can access this private module through the second case. + +* When writing unit tests for a module, it's often a common idiom to have an immediate child of the module to-be-tested named `mod test`. This module could access any items of the parent module through the second case, meaning that internal implementation details could also be seamlessly tested from the child module. + +In the second case, it mentions that a private item "can be accessed" by the current module and its descendants, but the exact meaning of accessing an item depends on what the item is. + +r[vis.use] +Accessing a module, for example, would mean looking inside of it (to import more items). On the other hand, accessing a function would mean that it is invoked. Additionally, path expressions and import statements are considered to access an item in the sense that the import/expression is only valid if the destination is in the current visibility scope. + +Here's an example of a program which exemplifies the three cases outlined above: + +```rust +// This module is private, meaning that no external crate can access this +// module. Because it is private at the root of this current crate, however, any +// module in the crate may access any publicly visible item in this module. +mod crate_helper_module { + + // This function can be used by anything in the current crate + pub fn crate_helper() {} + + // This function *cannot* be used by anything else in the crate. It is not + // publicly visible outside of the `crate_helper_module`, so only this + // current module and its descendants may access it. + fn implementation_detail() {} +} + +// This function is "public to the root" meaning that it's available to external +// crates linking against this one. +pub fn public_api() {} + +// Similarly to 'public_api', this module is public so external crates may look +// inside of it. +pub mod submodule { + use crate::crate_helper_module; + + pub fn my_method() { + // Any item in the local crate may invoke the helper module's public + // interface through a combination of the two rules above. + crate_helper_module::crate_helper(); + } + + // This function is hidden to any module which is not a descendant of + // `submodule` + fn my_implementation() {} + + #[cfg(test)] + mod test { + + #[test] + fn test_my_implementation() { + // Because this module is a descendant of `submodule`, it's allowed + // to access private items inside of `submodule` without a privacy + // violation. + super::my_implementation(); + } + } +} + +# fn main() {} +``` + +For a Rust program to pass the privacy checking pass, all paths must be valid accesses given the two rules above. This includes all use statements, expressions, types, etc. + +r[vis.scoped] +## `pub(in path)`, `pub(crate)`, `pub(super)`, and `pub(self)` + +r[vis.scoped.intro] +In addition to public and private, Rust allows users to declare an item as visible only within a given scope. The rules for `pub` restrictions are as follows: + +r[vis.scoped.in] +- `pub(in path)` makes an item visible within the provided `path`. `path` must be a simple path which resolves to an ancestor module of the item whose visibility is being declared. Each identifier in `path` must refer directly to a module (not to a name introduced by a `use` statement). + +r[vis.scoped.crate] +- `pub(crate)` makes an item visible within the current crate. + +r[vis.scoped.super] +- `pub(super)` makes an item visible to the parent module. This is equivalent to `pub(in super)`. + +r[vis.scoped.self] +- `pub(self)` makes an item visible to the current module. This is equivalent to `pub(in self)` or not using `pub` at all. + +r[vis.scoped.edition2018] +> [!EDITION-2018] +> Starting with the 2018 edition, paths for `pub(in path)` must start with `crate`, `self`, or `super`. The 2015 edition may also use paths starting with `::` or modules from the crate root. + +Here's an example: + +```rust,edition2015 +pub mod outer_mod { + pub mod inner_mod { + // This function is visible within `outer_mod` + pub(in crate::outer_mod) fn outer_mod_visible_fn() {} + // Same as above, this is only valid in the 2015 edition. + pub(in outer_mod) fn outer_mod_visible_fn_2015() {} + + // This function is visible to the entire crate + pub(crate) fn crate_visible_fn() {} + + // This function is visible within `outer_mod` + pub(super) fn super_mod_visible_fn() { + // This function is visible since we're in the same `mod` + inner_mod_visible_fn(); + } + + // This function is visible only within `inner_mod`, + // which is the same as leaving it private. + pub(self) fn inner_mod_visible_fn() {} + } + pub fn foo() { + inner_mod::outer_mod_visible_fn(); + inner_mod::crate_visible_fn(); + inner_mod::super_mod_visible_fn(); + + // This function is no longer visible since we're outside of `inner_mod` + // Error! `inner_mod_visible_fn` is private + //inner_mod::inner_mod_visible_fn(); + } +} + +fn bar() { + // This function is still visible since we're in the same crate + outer_mod::inner_mod::crate_visible_fn(); + + // This function is no longer visible since we're outside of `outer_mod` + // Error! `super_mod_visible_fn` is private + //outer_mod::inner_mod::super_mod_visible_fn(); + + // This function is no longer visible since we're outside of `outer_mod` + // Error! `outer_mod_visible_fn` is private + //outer_mod::inner_mod::outer_mod_visible_fn(); + + outer_mod::foo(); +} + +fn main() { bar() } +``` + +> [!NOTE] +> This syntax only adds another restriction to the visibility of an item. It does not guarantee that the item is visible within all parts of the specified scope. To access an item, all of its parent items up to the current scope must still be visible as well. + +r[vis.reexports] +## Re-exporting and visibility + +r[vis.reexports.intro] +Rust allows publicly re-exporting items through a `pub use` directive. Because this is a public directive, this allows the item to be used in the current module through the rules above. It essentially allows public access into the re-exported item. For example, this program is valid: + +```rust +pub use self::implementation::api; + +mod implementation { + pub mod api { + pub fn f() {} + } +} + +# fn main() {} +``` + +This means that any external crate referencing `implementation::api::f` would receive a privacy violation, while the path `api::f` would be allowed. + +r[vis.reexports.private-item] +When re-exporting a private item, it can be thought of as allowing the "privacy chain" being short-circuited through the reexport instead of passing through the namespace hierarchy as it normally would. diff --git a/stdlib/kvlang/reference/rust/reference-repo/src/whitespace.md b/stdlib/kvlang/reference/rust/reference-repo/src/whitespace.md new file mode 100644 index 00000000..9034b7fa --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/src/whitespace.md @@ -0,0 +1,37 @@ +r[lex.whitespace] +# Whitespace + +r[whitespace.syntax] +```grammar,lexer +WHITESPACE -> + U+0009 // Horizontal tab, `'\t'` + | U+000A // Line feed, `'\n'` + | U+000B // Vertical tab + | U+000C // Form feed + | U+000D // Carriage return, `'\r'` + | U+0020 // Space, `' '` + | U+0085 // Next line + | U+200E // Left-to-right mark + | U+200F // Right-to-left mark + | U+2028 // Line separator + | U+2029 // Paragraph separator + +TAB -> U+0009 // Horizontal tab, `'\t'` + +LF -> U+000A // Line feed, `'\n'` + +CR -> U+000D // Carriage return, `'\r'` + +SP -> U+0020 // Space, `' '` +``` + +r[lex.whitespace.intro] +Whitespace is any non-empty string containing only characters that have the [`Pattern_White_Space`] Unicode property. + +r[lex.whitespace.token-sep] +Rust is a "free-form" language, meaning that all forms of whitespace serve only to separate _tokens_ in the grammar, and have no semantic significance. + +r[lex.whitespace.replacement] +A Rust program has identical meaning if each whitespace element is replaced with any other legal whitespace element, such as a single space character. + +[`Pattern_White_Space`]: https://www.unicode.org/reports/tr31/ diff --git a/stdlib/kvlang/reference/rust/reference-repo/theme/reference.css b/stdlib/kvlang/reference/rust/reference-repo/theme/reference.css new file mode 100644 index 00000000..fa487688 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/theme/reference.css @@ -0,0 +1,693 @@ +/* Custom CSS for the Rust Specification. */ + +/* Per-theme variables. */ +.light { + --alert-note-color: #0969da; + --alert-warning-color: #9a6700; + --alert-edition-color: #1a7f37; + --alert-example-color: #8250df; + --grammar-literal-bg: #fafafa; +} +.rust { + --alert-note-color: #023b95; + --alert-warning-color: #603700; + --alert-edition-color: #008200; + --alert-example-color: #8250df; + --grammar-literal-bg: #dedede; +} +.light, .rust { + --grammar-comment-color: lch(from var(--quote-bg) calc(l - 50) 0 0); + --inline-code-color: var(--grammar-comment-color); +} +.coal, .navy { + --alert-note-color: #4493f8; + --alert-warning-color: #d29922; + --alert-edition-color: #3fb950; + --alert-example-color: #ab7df8; + --grammar-literal-bg: #1d1f21; +} +.ayu { + --alert-note-color: #74b9ff; + --alert-warning-color: #f0b72f; + --alert-edition-color: #2bd853; + --alert-example-color: #d3abff; + --grammar-literal-bg: #191f26; +} +.coal, .navy, .ayu { + --grammar-comment-color: lch(from var(--quote-bg) calc(l + 50) 0 0); + --inline-code-color: var(--grammar-comment-color); +} + +/* +.parenthetical class used to keep e.g. "less-than symbol (<)" from wrapping +the end parenthesis onto its own line. Use in a span between the last word and +the parenthetical. So for this example, you'd use +```less-than <span class="parenthetical">symbol (`<`)</span>``` +*/ +.parenthetical { + white-space: nowrap; +} + +/* +Admonitions are defined with blockquotes: + +> [!WARNING] +> This is bad! + +See tools/mdbook-spec/src/admonitions.rs. +*/ +.alert blockquote { + /* Add some padding to make the vertical bar a little taller than the text.*/ + padding: 8px 0px 8px 20px; + /* Add a solid color bar on the left side. */ + border-inline-start-style: solid; + border-inline-start-width: 4px; + /* Disable the background color from mdbook for a cleaner look. */ + background-color: inherit; + /* Disable border blocks from mdbook. */ + border-block-start: none; + border-block-end: none; + /* Reduce margin from mdbook, it uses a lot of space. */ + margin: 10px 0; +} + +.alert-title { + /* Slightly increase the weight for more emphasis. */ + font-weight: 600; + /* Vertically center the icon with the text. */ + display: flex; + align-items: center; + /* Remove default large margins for a more compact display. + Important to override .alert p rule. */ + margin: 0 0 8px 0 !important; +} +.alert blockquote > :nth-child(2) { + /* Default margins of content just below the label add too much space. */ + margin-top: 0; +} +.alert blockquote > :last-child { + /* Default margins of content add too much space. */ + margin-bottom: 0; +} + +.alert-title svg { + fill: currentColor; + /* Add some space between the icon and the text. */ + margin-right: 8px; +} + +.alert-note blockquote { + border-inline-start-color: var(--alert-note-color); +} +.alert-warning blockquote { + border-inline-start-color: var(--alert-warning-color); +} +.alert-edition blockquote { + border-inline-start-color: var(--alert-edition-color); +} +.alert-example blockquote { + border-inline-start-color: var(--alert-example-color); +} +.alert-note .alert-title { + color: var(--alert-note-color); +} +.alert-warning .alert-title { + color: var(--alert-warning-color); +} +.alert-edition .alert-title { + color: var(--alert-edition-color); +} +/* Puts a rounded rectangle around the edition date. */ +.alert-title-edition { + padding: 0px 5px; + margin-right: 1rem; + border: 2px solid var(--alert-edition-color); + border-radius: 15px; + font-weight: bold; + color: var(--alert-edition-color); +} +.alert-example .alert-title { + color: var(--alert-example-color); +} + +/* <kbd> tags can be used to highlight specific character elements. */ +kbd { + border: 1px solid #999; + display: inline-block; + border-radius: 3px; + padding: 0 0.6ex; + background: #eee; + box-shadow: inset -1px -1px 0 #999; + vertical-align: baseline; + color: #000; + height: 1.55em; + font-style: normal; + font-weight: bold; + font-family: inherit; + font-size: revert; + line-height: revert; +} +kbd.optional { + border-style: dashed; + background: #fff; +} +var.optional { + border-style: dashed; +} + +/* <var> tags can be used for non-terminals. */ +var { + border: 1px solid #9c9; + box-shadow: inset -1px -1px 0 #9c9; + font-style: normal; + display: inline-block; + vertical-align: baseline; + border-radius: 7px; + padding: 0 4px; + background: #dfd; + margin: 2px; +} +var.type { + box-shadow: inset -1px -1px 0 #c99; + border-color: #c99; + background: #fdd; +} + +/* <span class="repeat"> can be used for a grammar production that repeats zero or more times. */ +span.repeat { + position: relative; + border: 1px dashed #393; + border-radius: 10px; + display: inline-block; + padding: 6px; + margin-left: 0.5ex; + margin-top: 1em; + margin-bottom: 0.5ex; + min-width: 3.8em; + text-align: center; +} +span.repeat::before { + content: "zero or more"; + white-space: nowrap; + display: block; + text-align: center; + font-size: 0.75em; + position: absolute; + left: 0; + right: 0; + top: -1.4em; + color: #393; +} +var > span { + display: inline-block; + border-right: 1px dotted green; + padding-right: 0.5ex; + margin-right: 0.5ex; + font-style: italic; +} + +/* <span class="version"> can be used to highlight a specific version of Rust. */ +span.version { + float: right; + margin-left: 1em; + margin-bottom: 1em; + background: #f7c0eb; + padding: 0.2ex 0.5ex; + border-radius: 5px; + display: block; + box-shadow: inset -1px -1px 0 #a06894; + font-size: 0.9em; +} + +/* <dfn> tags are used to indicate a specific word or phrase is being defined. */ +dfn { + font-style: italic; + text-decoration: underline; +} + +.content main { + /* Provides space on the left for the rule call-outs. */ + padding-left: 4em; +} + +/* Rules are generated via r[foo.bar] syntax, processed by mdbook-spec. */ +.rule { + --font-size-mult: 0.8; + --font-size: calc(1em * var(--font-size-mult)); + + font-size: var(--font-size); +} + +/* included in the grid below as 20px */ +.page, .content { + padding-left: 0; + padding-right: 0; +} +/* required to accommodate above, somehow... */ +#mdbook-menu-bar { + margin-left: 0; +} + +main { + /* To nicely display rules (`[a.b.c]`) on a side of the main text body we + use grid layout. */ + display: grid; + grid-template-columns: + /* Left margin / place for rules */ + [rules] minmax(36px, 1fr) + /* The main text body */ + [text] auto + /* Right margin */ + [margin] minmax(36px, 1fr); + + /* We do these by hand via the grid */ + margin: 0; + padding: 0 !important; + max-width: none !important; +} + +main > * { + /* By default grid items can't be smaller than their content. + That is, by default `min-width: auto`. + We want to be able to force code blocks to be scrollable, + so we need to overwrite `min-width`. */ + min-width: 0; + max-width: var(--content-max-width); + + /* All elements should be in the main text body... */ + grid-column: text; +} + +main > .rule { + /* ... except the rules, which must be in the left margin */ + grid-column: rules; +} + +hr { + /* For some reason, grid is shrinking this to a point. */ + width: 100%; +} + +/* Too much space with the grid. +*/ +.footnote-definition { + margin-top: 0; +} +.footnote-definition li:first-child > *:first-child { + margin-top: 0; +} + +/* This is quite dumb, ugh. + CSS doesn't allow margin collapsing between grid items and anything else + (src: <https://stackoverflow.com/a/37837971>), which means that the margins + of li's children are not collapsed with ul's margins, adding too much margins. + + Ideally we'd add `<div>`s for each grid cell, so that margin collapsing happens + as-usual inside of them. But, we don't have that kind of control over mdbook. */ +main > ul > li > *:first-child, +main > ul > li > pre:first-child > pre.playground, +main > ol:not(.footnote-definition) > li > *:first-child, +main > ol:not(.footnote-definition) > li > pre:first-child > pre.playground { + margin-top: 0; +} +main > ul > li > *:last-child, +main > ul > li > pre:last-child > pre.playground, +main > ol:not(.footnote-definition) > li > *:last-child, +main > ol:not(.footnote-definition) > li > pre:last-child > pre.playground { + margin-bottom: 0; +} + +/* Similarly to the above, margin collapse doesn't happen between grid items, + so we have to replace it with grid gap. (p, pre, and ul had 16px vertical margins) */ +main { + row-gap: 16px; +} +main > p, +main > pre, +main > pre > pre.playground, +main > ul, +main > ol { + margin-top: 0; + margin-bottom: 0; +} + +/* Values for header margin-top and blockquote margin are taken from mdbook's general.css, + values for header margin-bottom are taken from <https://www.w3schools.com/cssref/css_default_values.php> */ +:root { + /* 1.6 is body font-size */ + --h2-margin-top: calc(1.5rem * 1.6 * 2.5 - 16px); + --h3-margin-top: calc(1.17rem * 1.6 * 2.5 - 16px); + --h4-margin-top: calc(1.00rem * 1.6 * 2 - 16px); + --h5-margin-top: calc(0.83rem * 1.6 * 2 - 16px); + --h6-margin-top: calc(0.67rem * 1.6 * 2 - 16px); +} +main > h2 { + margin-top: var(--h2-margin-top); + margin-bottom: calc(0.83em - 16px); +} +main > h3 { + margin-top: var(--h3-margin-top); + margin-bottom: calc(1em - 16px); +} +main > h4 { + margin-top: var(--h4-margin-top); + margin-bottom: calc(1.33em - 16px); +} +main > h5 { + margin-top: var(--h5-margin-top); + margin-bottom: calc(1.67em - 16px); +} +main > h6 { + margin-top: var(--h6-margin-top); + margin-bottom: calc(2.33em - 16px); +} +main > blockquote { + margin-top: calc(20px - 16px); + margin-bottom: calc(20px - 16px); +} + +main > .rule { + max-width: unset; + justify-self: right; + width: 100%; + /* We use a container query to know the size of the "left margin", + so that we can hide rules is there is not enough space. */ + container-type: inline-size; + container-name: rule; +} + +.rule-link { + float: right; + text-align: right; + padding-right: 10px; + /* We add `<wbr>` ourselves and only want breaks there */ + word-break: keep-all; + /* Remove the blue coloring of links on rules that mdbook normally sets. */ + color: #999 !important; +} + +/* Test links */ +.test-link { + float: right; + padding-right: 10px; +} + +.rule .popup-container > a { + float: right; + text-align: right; +} + +/* When clicking a rule, it is added as a URL fragment and the browser will + navigate to it. This adds an indicator that the linked rule is the one that + is "current", just like normal headers are in mdbook. +*/ +.rule:target .rule-link::before { + display: inline-block; + content: "»"; + padding-right: 5px; +} + +/* Make it bolder/easier to read when selected. */ +.rule:target .rule-link { + color: var(--fg) !important; +} + +/* Dodge » from headings */ +/* Note: Some rules have a .tests-popup in the way, so that's why this selects + either with or without. */ +.rule:has(+ h1:target, + .tests-popup + h1:target), +.rule:has(+ h2:target, + .tests-popup + h2:target), +.rule:has(+ h3:target, + .tests-popup + h3:target), +.rule:has(+ h4:target, + .tests-popup + h4:target), +.rule:has(+ h5:target, + .tests-popup + h5:target), +.rule:has(+ h6:target, + .tests-popup + h6:target) { + padding-right: 24px; +} + +/* This positioning is to push the popup down over the header's top margin. + Ideally I would like the popup to show *below* the header, but I have no idea how to do that. +*/ +.tests-popup:has(+ h2) { + position: relative; + top: calc(var(--h2-margin-top) + 10px); +} +.tests-popup:has(+ h3) { + position: relative; + top: calc(var(--h3-margin-top) + 10px); +} +.tests-popup:has(+ h4) { + position: relative; + top: calc(var(--h4-margin-top) + 10px); +} +.tests-popup:has(+ h5) { + position: relative; + top: calc(var(--h5-margin-top) + 10px); +} +.tests-popup:has(+ h6) { + position: relative; + top: calc(var(--h6-margin-top) + 10px); +} + +/* Hide the rules if the width of the container is too small. + The cutoff point is chosen semi-arbitrary, it felt that + when `width < 14em`, there are too many breaks. */ +@container rule (width < 14em) { + main > .rule a.rule-link span, + .test-link > a span { + display: none; + } + + main > .rule > a.rule-link::before { + content: "[*]"; + } + + .test-link > a::before { + content: "[T]"; + } +} + +/* Align rules to various siblings */ +.rule:has(+ p, + .tests-popup + p), +.rule:has(+ ul, + .tests-popup + ul), +.rule:has(+ ol, + .tests-popup + ol) { + margin-top: calc((1em - var(--font-size)) / var(--font-size-mult) / 2); +} + +.rule:has(+ h1, + .tests-popup + h1) { + align-self: center; +} + +.rule:has(+ h2, + .tests-popup + h2) { + /* multiplying by this turns h2's em into .rule's em*/ + --h2-em-mult: calc( + (1 / var(--font-size-mult)) /* to main font size */ + * 1.5 /* to h2 font size */ + ); + + margin-top: calc( + /* h2 margin top */ + 2.5em * var(--h2-em-mult) - 16px + /* half of the font size difference */ + + (1em * var(--h2-em-mult) - 1em) / 2 + ); +} +.rule:has(+ h3, + .tests-popup + h3) { + /* multiplying by this turns h3's em into .rule's em*/ + --h3-em-mult: calc( + (1 / var(--font-size-mult)) /* to main font size */ + * 1.17 /* to h3 font size */ + ); + + margin-top: calc( + /* h3 margin top */ + 2.5em * var(--h3-em-mult) - 16px + /* half of the font size difference */ + + (1em * var(--h3-em-mult) - 1em) / 2 + ); +} + +.rule:has(+ h4, + .tests-popup + h4) { + /* multiplying by this turns h4's em into .rule's em*/ + --h4-em-mult: calc( + (1 / var(--font-size-mult)) /* to main font size */ + * 1 /* to h4 font size */ + ); + + margin-top: calc( + /* h4 margin top */ + 2em * var(--h4-em-mult) - 16px + /* half of the font size difference */ + + (1em * var(--h4-em-mult) - 1em) / 2 + ); +} + +.rule:has(+ h5, + .tests-popup + h5) { + /* multiplying by this turns h5's em into .rule's em*/ + --h5-em-mult: calc( + (1 / var(--font-size-mult)) /* to main font size */ + * 0.83 /* to h5 font size */ + ); + + margin-top: calc( + /* h5 margin top */ + 2em * var(--h5-em-mult) - 16px + /* half of the font size difference */ + + (1em * var(--h5-em-mult) - 1em) / 2 + ); +} + +.rule:has(+ h6, + .tests-popup + h6) { + /* multiplying by this turns h6's em into .rule's em*/ + --h6-em-mult: calc( + (1 / var(--font-size-mult)) /* to main font size */ + * 0.67 /* to h6 font size */ + ); + + margin-top: calc( + /* h6 margin top */ + 2em * var(--h6-em-mult) - 16px + /* half of the font size difference */ + + (1em * var(--h6-em-mult) - 1em) / 2 + ); +} + +/* Sets the color for [!HISTORY] blockquote admonitions. */ +.history > blockquote { + background: #f7c0eb; +} + +/* Provides a anchor container for positioning popups. */ +.popup-container { + position: relative; +} +/* In the test summary page, a convenience class for toggling visibility. */ +.popup-hidden { + display: none; +} +/* In the test summary page, the styling for the uncovered rule popup. */ +.uncovered-rules-popup { + position: absolute; + left: -250px; + width: 400px; + background: var(--bg); + border-radius: 4px; + border: 1px solid; + z-index: 1000; + padding: 1rem; +} + +/* The popup that shows when viewing tests for a specific rule. */ +.tests-popup { + color: var(--fg); + background: var(--bg); + border-radius: 4px; + border: 1px solid; + z-index: 1000; + padding: 1rem; +} + +/* The box that contains the grammar. */ +.grammar-container { + font-family: var(--mono-font); + /* Enable absolute positioning for the target chevron. */ + position: relative; + background-color: var(--quote-bg); + border-block-start: .1em solid var(--quote-border); + border-block-end: .1em solid var(--quote-border); + margin-top: 4px; + margin-bottom: 4px; + padding: 0 20px; +} + +/* English words inside the grammar. */ +.grammar-text { + font-family: "Open Sans", sans-serif; +} + +/* Comments inside the grammar. */ +.grammar-comment { + font-family: "Open Sans", sans-serif; + color: var(--grammar-comment-color); +} +.grammar-comment code.hljs { + background: var(--grammar-literal-bg); +} + +/* Places a box around literals to differentiate from other grammar punctuation like | and ( . */ +.grammar-literal { + font-family: var(--mono-font); + border-radius: 4px; + border: solid 1px var(--theme-popup-border); + font-weight: bold; + font-size: var(--code-font-size); + padding: 1px 4px; + color: var(--inline-code-color); +} + +.grammar-literal { + background-color: var(--grammar-literal-bg); +} + +.grammar-production:target, .railroad-production:target { + scroll-margin-top: 50vh; +} + +.railroad-production { + /* Enables absolute positioning of the target chevron. */ + position: relative; +} + +/* Adds an indicator to the targeted production name. */ +.grammar-production:target::before, .railroad-production:target::before { + content: "»"; + position: absolute; + left: 3px; + font-size: 2rem; + font-weight: bolder; + /* For some reason, the vertical alignment is slightly off center. This helps + with that alignment. It was too difficult to try to fix that via + absolute positioning. */ + line-height: 1; +} + +/* Overrides the positioning of the chevron from the rule above. */ +.railroad-production:target::before { + left: -20px; + top: 8px; +} + +/* The toggle button. */ +.grammar-toggle-railroad { + width: 160px; + padding: 5px 0px; + border-radius: 5px; + cursor: pointer; +} + +/* This is used to toggle the hidden status of the railroad diagrams. */ +.grammar-hidden { + display: none; +} + +/* +The theme-specific railroad backgrounds intentionally match mdBook's page +backgrounds. Offset only their lightness here so embedded diagrams remain +visually distinct while retaining each theme's hue and saturation. The Light +railroad theme already provides this contrast itself. + +Including `html` makes these selectors more specific than the stylesheets +embedded by mdbook-spec. +*/ +html.rust svg.railroad { + background-color: hsl(from var(--bg) h s calc(l - 5)); +} +html.coal svg.railroad, +html.navy svg.railroad, +html.ayu svg.railroad { + background-color: hsl(from var(--bg) h s calc(l + 5)); +} + +/* Styling specific to the Reference's negative-lookahead railroad node. */ +svg.railroad g.exceptbox > rect { + fill:rgba(245, 160, 125, .1); +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/theme/reference.js b/stdlib/kvlang/reference/rust/reference-repo/theme/reference.js new file mode 100644 index 00000000..5fdf6f10 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/theme/reference.js @@ -0,0 +1,78 @@ +/* On the test summary page, toggles the popup for the uncovered tests. */ +function spec_toggle_uncovered(item_index) { + let el = document.getElementById(`uncovered-${item_index}`); + const currently_hidden = el.classList.contains('popup-hidden'); + const all = document.querySelectorAll('.uncovered-rules-popup'); + all.forEach(element => { + element.classList.add('popup-hidden'); + }); + if (currently_hidden) { + el.classList.remove('popup-hidden'); + } +} + +function spec_toggle_tests(rule_id) { + let el = document.getElementById(`tests-${rule_id}`); + const currently_hidden = el.classList.contains('popup-hidden'); + const all = document.querySelectorAll('.tests-popup'); + all.forEach(element => { + element.classList.add('popup-hidden'); + }); + if (currently_hidden) { + el.classList.remove('popup-hidden'); + } +} + +function toggle_railroad() { + const grammarRailroad = get_railroad(); + set_railroad(!grammarRailroad); + update_railroad(); +} + +function show_railroad() { + set_railroad(true); + update_railroad(); +} + +function get_railroad() { + let grammarRailroad = null; + try { + grammarRailroad = localStorage.getItem('grammar-railroad'); + } catch (e) { + // Ignore error. + } + grammarRailroad = grammarRailroad === 'true' ? true : false; + return grammarRailroad; +} + +function set_railroad(newValue) { + try { + localStorage.setItem('grammar-railroad', newValue); + } catch (e) { + // Ignore error. + } +} + +function update_railroad() { + const grammarRailroad = get_railroad(); + const railroads = document.querySelectorAll('.grammar-railroad'); + railroads.forEach(element => { + if (grammarRailroad) { + element.classList.remove('grammar-hidden'); + } else { + element.classList.add('grammar-hidden'); + } + }); + const buttons = document.querySelectorAll('.grammar-toggle-railroad'); + buttons.forEach(button => { + if (grammarRailroad) { + button.innerText = "Hide syntax diagrams"; + } else { + button.innerText = "Show syntax diagrams"; + } + }); +} + +(function railroad_onload() { + update_railroad(); +})(); diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/Cargo.toml new file mode 100644 index 00000000..8652629a --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "diagnostics" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/README.md b/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/README.md new file mode 100644 index 00000000..1d43f396 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/README.md @@ -0,0 +1,3 @@ +# Diagnostics library + +This is an extremely basic library to provide diagnostics output for the Reference tools. It provides the ability to emit warnings or errors, and to upgrade warnings to errors via an environment variable. diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/src/lib.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/src/lib.rs new file mode 100644 index 00000000..cced66c8 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/diagnostics/src/lib.rs @@ -0,0 +1,51 @@ +//! Very basic diagnostics output support. + +use std::fmt; + +/// Handler for errors and warnings. +pub struct Diagnostics { + /// Whether or not warnings should be errors (set by SPEC_DENY_WARNINGS + /// environment variable). + pub deny_warnings: bool, + /// Number of messages generated. + pub count: u32, +} + +impl Diagnostics { + pub fn new() -> Diagnostics { + let deny_warnings = std::env::var("SPEC_DENY_WARNINGS").as_deref() == Ok("1"); + Diagnostics { + deny_warnings, + count: 0, + } + } + + /// Displays a warning or error (depending on whether warnings are denied). + /// + /// Usually you want the [`warn_or_err!`] macro. + pub fn warn_or_err(&mut self, args: fmt::Arguments<'_>) { + if self.deny_warnings { + eprintln!("error: {args}"); + } else { + eprintln!("warning: {args}"); + } + self.count += 1; + } +} + +/// Displays a warning or error (depending on whether warnings are denied). +#[macro_export] +macro_rules! warn_or_err { + ($diag:expr, $($arg:tt)*) => { + $diag.warn_or_err(format_args!($($arg)*)); + }; +} + +/// Displays a message for an internal error, and immediately exits. +#[macro_export] +macro_rules! bug { + ($($arg:tt)*) => { + eprintln!("mdbook-spec internal error: {}", format_args!($($arg)*)); + std::process::exit(1); + }; +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/Cargo.toml new file mode 100644 index 00000000..aafdc49f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "grammar-check" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +clap = "4.5.53" +ctrlc = "3.5.1" +diagnostics = { path = "../diagnostics" } +grammar = { path = "../grammar" } +indicatif = "0.18.3" +parser = { path = "../parser" } +proc-macro2 = { version = "1.0.103", features = ["span-locations"] } +regex = "1.12.2" +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.145" +tracing = "0.1.43" +tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } +tracing-tree = "0.4.1" +unicode-ident = "1.0.22" +walkdir = "2.5.0" + +[package.metadata.rust-analyzer] +rustc_private = true diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/README.md b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/README.md new file mode 100644 index 00000000..80ae0939 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/README.md @@ -0,0 +1,57 @@ +# Reference grammar checker + +This is a CLI tool for validating the Reference grammar against other parsers (called *tools*). + +## Commands + +There are several different subcommands: + +- `grammar-check lex-compare` — Compare tokenization between implementations. +- `grammar-check tokenize` — Convert source to tokens. +- `grammar-check tree` — Convert source to a tree. + +Pass `--help` for more information. + +It is recommended to run this in the release profile, especially when testing against a large corpus. + +```shell +cargo r -r -- lex-compare --path /path/to/rust/tests +``` + +Some subcommands like `lex-compare` can parse multiple different kinds of sources, like stdin or auto-generated permutations. See the help output for more. + +## Tools + +This tool supports various parsers which are called *tools*. They are: + +- `reference` — The Reference interpreter using the grammar from the Reference. +- `rustc_parse` — The AST parser from `rustc`. +- `rustc_lexer` — The low-level lexer from `rustc`. This generally isn't useful other than doing deeper analysis on rustc. +- `proc-macro2` — The `proc-macro2` crate. + +## Coverage analysis + +The tool can emit an HTML coverage report of the Reference grammar. Run a command like this: + +```shell +cargo r -r -- lex-compare --coverage --permute Token +``` + +Then open `coverage.html` and look at the token rules to see how well they were covered. Green means it was fully covered, yellow was partially covered, and red is not covered at all. You can mouse-over to get a popup that shows more details about each sub-expression. + +Ideally this should have full coverage, but it's not quite there. + +## Edition support + +There are the beginnings of edition support here, but generally it is incomplete. The Reference grammar itself is not Edition-aware. This will take some significant more work to support properly. Ideally the path-based input could parse the compiletest-based headers to figure out which edition to use for each file. + +## AST parsing + +The tree-based parsing is incomplete and needs some work. It can parse a simple individual item (like `struct S;`), but otherwise can't parse general Rust source. It needs work on both the parser itself and the Reference grammar itself. Example command: + +```shell +cargo r -r -- tree --string 'struct S {x: i32}' +``` + +Comparison against other parsers is not implemented. A new `tree-compare` subcommand needs to be added. It will need to somehow be able to compare the trees between the Reference and the tool (either by normalizing, or having a large `match` that would compare every expression kind). + diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/lex_compare.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/lex_compare.rs new file mode 100644 index 00000000..a9a52580 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/lex_compare.rs @@ -0,0 +1,378 @@ +//! Subcommand that compares lexer tokenization between tools. +//! +//! To compare against the Reference grammar, this needs to do some +//! normalization because different tools have different ideas of exactly what +//! is a token, or the exact span of bytes of a token. +//! +//! Unfortunately this does a poor job of handling when both the Reference and +//! the tool fails to parse some input. Ideally it should compare the exact +//! error (or the span of the error), but that would be extremely difficult. + +use crate::CommonOptions; +use crate::tools::{pm2, rustc}; +use crate::{Message, Tool, display_line}; +use clap::ArgMatches; +use diagnostics::Diagnostics; +use grammar::Grammar; +use parser::Edition; +use parser::ParseError; +use parser::coverage::Coverage; +use parser::lexer::Tokens; +use std::cell::RefCell; +use std::ops::Range; +use std::panic::AssertUnwindSafe; +use std::sync::{Arc, Mutex}; +use std::time::Instant; + +const DEFAULT_COMPARE_TOOLS: [Tool; 2] = [Tool::RustcParse, Tool::ProcMacro2]; + +thread_local! { + static PANIC_OUTPUT: RefCell<Option<String>> = const { RefCell::new(None) }; +} + +pub fn compare_parallel(matches: &ArgMatches) { + let start = Instant::now(); + let (opts, receiver) = CommonOptions::new(matches, &DEFAULT_COMPARE_TOOLS); + if opts.tools.iter().any(|t| *t == Tool::Reference) { + panic!("can't compare reference to itself"); + } + if let Some(t) = opts + .tools + .iter() + .find(|t| !DEFAULT_COMPARE_TOOLS.contains(t)) + { + panic!("tool {t} is not supported for comparison"); + } + + std::panic::set_hook(Box::new(|info| { + let payload = info.payload(); + let msg = if let Some(s) = payload.downcast_ref::<&str>() { + s + } else if let Some(s) = payload.downcast_ref::<String>() { + s.as_str() + } else { + "Box<dyn Any>" + }; + let location = info + .location() + .map(|l| format!("{}:{}:{}", l.file(), l.line(), l.column())) + .unwrap_or_else(|| "unknown".to_string()); + let thread = std::thread::current(); + let name = thread.name().unwrap_or("<unnamed>"); + let output = format!("thread '{name}' panicked at {location}:\n{msg}"); + + // We print it here as well to ensure it is seen if the thread dies unexpectedly. + // eprintln!("{}", output); + + PANIC_OUTPUT.with(|c| { + *c.borrow_mut() = Some(output); + }); + })); + + let mut diag = Diagnostics::new(); + let grammar = Arc::new(grammar::load_grammar_with_frontmatter(&mut diag)); + let coverage = Arc::new(Mutex::new(Coverage::default())); + + // Spawn threads to run the tests. + let sender = opts.channel.clone(); + let mut thread_count = opts.thread_count; + let opts = Arc::new(Mutex::new(opts)); + for _ in 0..thread_count { + let opts_c = opts.clone(); + let grammar = grammar.clone(); + let coverage = coverage.clone(); + std::thread::spawn(move || { + compare_loop(opts_c, grammar, coverage); + }); + } + ctrlc::set_handler(move || { + sender.send(Message::CtrlC).unwrap(); + }) + .unwrap(); + // Receive results from the threads. + loop { + match receiver.recv().unwrap() { + Message::ThreadComplete => { + thread_count -= 1; + if thread_count == 0 { + break; + } + } + Message::CtrlC => { + break; + } + } + } + + if opts.lock().unwrap().coverage { + coverage.lock().unwrap().save(&grammar); + } + print_final_summary(&opts, start); +} + +fn compare_loop( + opts: Arc<Mutex<CommonOptions>>, + grammar: Arc<Grammar>, + final_coverage: Arc<Mutex<Coverage>>, +) { + let mut coverage = Coverage::default(); + let channel = opts.lock().unwrap().channel.clone(); + let edition = opts.lock().unwrap().edition(); + loop { + let mut opts_l = opts.lock().unwrap(); + let Some((name, src)) = opts_l.next() else { + break; + }; + let tools = opts_l.tools.clone(); + drop(opts_l); + let lexer_result = match std::panic::catch_unwind(AssertUnwindSafe(|| { + parser::lexer::tokenize(&grammar, &mut coverage, &src) + })) { + Ok(r) => r, + Err(_) => { + let panic_msg = PANIC_OUTPUT.with(|c| { + c.borrow_mut() + .take() + .unwrap_or_else(|| "unknown panic".to_string()) + }); + let mut opts_l = opts.lock().unwrap(); + opts_l.errors.push(format!( + "test {name} for reference lexer panicked:\n{panic_msg}" + )); + opts_l.set_progress_err_msg(); + break; + } + }; + + for tool in &*tools { + match std::panic::catch_unwind(|| { + compare_src(lexer_result.clone(), &name, &src, *tool, edition) + }) { + Ok(Ok(())) => {} + Ok(Err(e)) => { + let mut opts_l = opts.lock().unwrap(); + opts_l.errors.push(e); + opts_l.set_progress_err_msg(); + } + Err(_) => { + let panic_msg = PANIC_OUTPUT.with(|c| { + c.borrow_mut() + .take() + .unwrap_or_else(|| "unknown panic".to_string()) + }); + let mut opts_l = opts.lock().unwrap(); + opts_l.errors.push(format!( + "test {name} for tool {tool} panicked:\n{panic_msg}" + )); + opts_l.set_progress_err_msg(); + } + } + let opts_l = opts.lock().unwrap(); + opts_l.progress.inc(1); + } + } + final_coverage.lock().unwrap().merge(coverage); + channel.send(Message::ThreadComplete).unwrap(); +} + +fn compare_src( + lexer_result: Result<Tokens, ParseError>, + name: &str, + src: &str, + tool: Tool, + edition: Edition, +) -> Result<(), String> { + let (tool_result, mut lexer_result) = match tool { + Tool::RustcParse => { + let lexer_result = lexer_result.and_then(|ts| rustc::normalize(&ts.tokens)); + (rustc::tokenize(src, edition), lexer_result) + } + Tool::ProcMacro2 => { + // Unfortunately proc-macro2 does not handle shebang or + // frontmatter. In order to handle files with that, this replaces + // those with whitespace in order to retain the original byte + // positions. + if let Err(ParseError { message, .. }) = &lexer_result + && message.contains("invalid frontmatter") + { + return Ok(()); + } + let mut stripped_src = String::from(src); + let mut replace = |range: &Range<usize>| { + let replacement = "\n".repeat(range.end - range.start); + stripped_src.replace_range(range.clone(), &replacement); + }; + if let Ok(Tokens { + shebang: Some(shebang), + .. + }) = &lexer_result + { + replace(&shebang.range); + } + if let Ok(Tokens { + frontmatter: Some(frontmatter), + .. + }) = &lexer_result + { + replace(&frontmatter.range); + } + let pm2_result = pm2::tokenize(&stripped_src); + pm2::normalize(pm2_result, lexer_result, src) + } + _ => unreachable!(), + }; + if let Ok(tokens) = &lexer_result + && let Some(invalid) = tokens + .iter() + .find(|token| token.name == "RESERVED_TOKEN" || token.name.starts_with("INVALID_")) + { + lexer_result = Err(ParseError { + byte_offset: invalid.range.start, + message: format!("invalid token {}", invalid.name), + }); + } + + match (lexer_result, tool_result) { + (Ok(lex_tokens), Ok(tool_tokens)) => { + let mut lex_iter = lex_tokens.iter(); + let mut tool_iter = tool_tokens.iter(); + loop { + let lex_token = lex_iter.next(); + let tool_token = tool_iter.next(); + match (lex_token, tool_token) { + (Some(lex_token), Some(tool_token)) => { + let lex_text = &src[lex_token.range.clone()]; + let tool_text = &src[tool_token.range.clone()]; + if lex_text != tool_text || lex_token.name != tool_token.name { + return Err(format!( + "error: token mismatch\n\ + test: {name}\n\ + reference token: {:?} {:?} {:?}\n\ + {}\n\ + {tool} token: {:?} {:?} {:?}\n\ + {}", + lex_token.name, + lex_text, + lex_token.range, + display_line(src, &lex_token.range), + tool_token.name, + tool_text, + tool_token.range, + display_line(src, &tool_token.range), + )); + } + } + (None, None) => break, + (Some(lex_token), None) => { + return Err(format!( + "error: reference has more tokens (compared to {tool})\n\ + test: {name}\n\ + reference token: {:?} {:?}\n\ + {}", + lex_token.name, + &src[lex_token.range.clone()], + display_line(src, &lex_token.range), + )); + } + (None, Some(tool_token)) => { + return Err(format!( + "error: {tool} has more tokens (compared to reference grammar)\n\ + test: {name}\n\ + {tool} token: {:?} {:?}\n\ + {}", + tool_token.name, + &src[tool_token.range.clone()], + display_line(src, &tool_token.range), + )); + } + } + } + return Ok(()); + } + (Err(e), Ok(_)) => { + return Err(format!( + "error: reference failed, {tool} passed\n\ + test: {name}\n\ + reference error: {}\n\ + {}", + e.display(src), + display_line( + src, + &Range { + start: e.byte_offset, + end: e.byte_offset + 1 + } + ) + )); + } + (Ok(_), Err(e)) => { + return Err(format!( + "error: {tool} failed, reference passed\n\ + test: {name}\n\ + {tool} error: {}\n\ + {}", + e.display(src), + display_line( + src, + &Range { + start: e.byte_offset, + end: e.byte_offset + 1 + } + ) + )); + } + (Err(_), Err(_)) => { + // Unfortunately getting the error byte offsets to match between + // the reference lexer and the tools is probably just too much + // effort. This means that they could be reporting errors for + // different reasons, but we wouldn't know. + // + // There are some substantial challenges here: + // + // - Cut errors can supersede previous RESERVED_ tokens, making the offset wildly different. + // - Recovery is a problem, for tests that have several errors. + // Example is /rust/tests/ui/rust-2021/reserved-prefixes.rs. + // - rustc ParseError only includes the byte offset of the first error. + // - reference has no recovery. + return Ok(()); + } + } +} + +fn print_final_summary(opts: &Arc<Mutex<CommonOptions>>, start: Instant) { + let opts_l = opts.lock().unwrap(); + // Get the actual count of tests run from progress position. + let actual_test_count = opts_l.progress.position() as u32; + opts_l.progress.finish_and_clear(); + if !opts_l.errors.is_empty() { + eprintln!("------------------------------------------------------------"); + for error in &opts_l.errors { + eprintln!( + "{error}\n\ + ------------------------------------------------------------" + ); + } + } + let n_errs = opts_l.errors.len() as u32; + // Use actual test count (from progress) when test_count is 0 (spinner mode). + let total = if opts_l.test_count == 0 { + actual_test_count + } else { + opts_l.test_count + }; + eprintln!("passed: {}", total.saturating_sub(n_errs)); + eprintln!("failed: {n_errs}"); + let elapsed = start.elapsed(); + if elapsed.as_secs() < 60 { + eprintln!("finished in {:.1} seconds", elapsed.as_secs_f64()); + } else { + eprintln!( + "finished in {} minutes {} seconds", + elapsed.as_secs() / 60, + elapsed.as_secs() % 60 + ); + } + if !opts_l.errors.is_empty() { + std::process::exit(1); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/print_grammar.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/print_grammar.rs new file mode 100644 index 00000000..f17d0fcf --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/print_grammar.rs @@ -0,0 +1,29 @@ +//! Simple subcommand that just spits out the grammar. +//! +//! This is helpful for getting a consolidated capture of all the grammar +//! rules in a plain text format for doing manual analysis and other +//! debugging. + +use clap::ArgMatches; +use diagnostics::Diagnostics; + +pub fn print_grammar(matches: &ArgMatches) { + let debug = matches.get_flag("debug"); + let mut diag = Diagnostics::new(); + let grammar = grammar::load_grammar(&mut diag); + + if debug { + for name in &grammar.name_order { + let production = grammar.productions.get(name).unwrap(); + println!("{} ->", name); + println!("{:#?}", production.expression); + println!(); + } + } else { + for name in &grammar.name_order { + let production = grammar.productions.get(name).unwrap(); + println!("{} -> {}", name, production.expression); + println!(); + } + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/split_check.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/split_check.rs new file mode 100644 index 00000000..8041d71a --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/split_check.rs @@ -0,0 +1,441 @@ +//! Experimental subcommand to identify token-splitting locations. +//! +//! This tries to find where multi-character tokens might be candidates to be +//! split into smaller tokens. This has a fairly high false-positive rate, so +//! it can take some manual effort to analyze. +//! +//! The current analysis of places where tokens are split are exhaustively +//! listed in https://github.com/rust-lang/rust/issues/152398. That issue also +//! highlights situations where rustc fails to split tokens (since it has to +//! do it manually). This highlights a situation where it will be difficult to +//! align the reference grammar with rustc, particularly when doing +//! permutation tests. + +use clap::ArgMatches; +use diagnostics::Diagnostics; +use grammar::{Expression, ExpressionKind, Grammar}; +use std::collections::{HashMap, HashSet}; + +// Multi-character tokens that may need to be split +const MULTI_CHAR_TOKENS: &[&str] = &[ + "...", "..=", "<<=", ">>=", "!=", "%=", "&&", "&=", "*=", "+=", "-=", "->", "..", "/=", "::", + "<-", "<<", "<=", "==", "=>", ">=", ">>", "^=", "|=", "||", +]; + +pub fn split_check(_matches: &ArgMatches) { + let mut diag = Diagnostics::new(); + let grammar = grammar::load_grammar(&mut diag); + + println!("Checking grammar for potential token splitting locations...\n"); + + // Map to store all locations where token splitting may be necessary + // Key: token, Value: list of (production_name, context) + let mut split_locations: HashMap<&str, Vec<(String, String)>> = HashMap::new(); + + // Check each production + for (prod_name, production) in &grammar.productions { + let mut locations_in_prod = Vec::new(); + let mut visited = HashSet::new(); + find_split_locations( + &grammar, + &production.expression, + &mut locations_in_prod, + prod_name, + &mut visited, + ); + + for (token, context) in locations_in_prod { + split_locations + .entry(token) + .or_insert_with(Vec::new) + .push((prod_name.clone(), context)); + } + } + + // Print results grouped by token + if split_locations.is_empty() { + println!("No potential token splitting locations found."); + } else { + for token in MULTI_CHAR_TOKENS { + if let Some(locations) = split_locations.get(token) { + println!("Token: `{}`", token); + println!(" Locations: {}", locations.len()); + for (prod_name, context) in locations { + println!(" - {}: {}", prod_name, context); + } + println!(); + } + } + } +} + +fn find_split_locations<'a>( + grammar: &'a Grammar, + expr: &'a Expression, + locations: &mut Vec<(&'a str, String)>, + current_production: &str, + visited: &mut HashSet<String>, +) { + match &expr.kind { + ExpressionKind::Grouped(e) => { + find_split_locations(grammar, e, locations, current_production, visited); + } + ExpressionKind::Alt(es) => { + for e in es { + find_split_locations(grammar, e, locations, current_production, visited); + } + } + ExpressionKind::Sequence(es) => { + // Check for adjacent elements that might require token splitting + for (i, e) in es.iter().enumerate() { + find_split_locations(grammar, e, locations, current_production, visited); + + // Check if this element could combine with following elements + // Skip non-token-producing elements (Break, Comment) when looking for the next element + if !matches!( + e.kind, + ExpressionKind::Break(_) | ExpressionKind::Comment(_) + ) { + // Find the next token-producing element + for j in (i + 1)..es.len() { + let next = &es[j]; + if !matches!( + next.kind, + ExpressionKind::Break(_) | ExpressionKind::Comment(_) + ) { + check_adjacent_for_splits( + grammar, + e, + next, + locations, + current_production, + ); + break; // Only check the immediate next token-producing element + } + } + } + } + } + ExpressionKind::Optional(e) + | ExpressionKind::NegativeLookahead(e) + | ExpressionKind::NegExpression(e) + | ExpressionKind::Cut(e) => { + find_split_locations(grammar, e, locations, current_production, visited); + } + ExpressionKind::Repeat(e) | ExpressionKind::RepeatPlus(e) => { + find_split_locations(grammar, e, locations, current_production, visited); + // Check if repeating this element could create a multi-char token + check_repeat_for_splits(grammar, e, locations, current_production, "repeat"); + } + ExpressionKind::RepeatRange { expr: e, .. } | ExpressionKind::RepeatRangeNamed(e, _) => { + find_split_locations(grammar, e, locations, current_production, visited); + check_repeat_for_splits(grammar, e, locations, current_production, "repeat range"); + } + ExpressionKind::Nt(_nt) => { + // Don't recurse into nonterminals - we only want to find direct uses + // and adjacent elements within the current production level. + // The main loop in split_check already visits each production. + } + ExpressionKind::Terminal(term) => { + // Check if this terminal is a multi-char token + for &multi_token in MULTI_CHAR_TOKENS { + if term == multi_token { + locations.push(( + multi_token, + format!("direct use of terminal `{}`", multi_token), + )); + } + } + } + ExpressionKind::Prose(_) + | ExpressionKind::Break(_) + | ExpressionKind::Comment(_) + | ExpressionKind::Charset(_) + | ExpressionKind::CharacterRange(..) + | ExpressionKind::Unicode(_) => { + // These don't contribute to token splitting + } + } +} + +fn describe_expression(expr: &Expression) -> String { + match &expr.kind { + ExpressionKind::Nt(nt) => nt.clone(), + ExpressionKind::Terminal(t) => format!("terminal `{}`", t), + ExpressionKind::Optional(e) => format!("optional {}", describe_expression(e)), + ExpressionKind::Grouped(e) => format!("grouped {}", describe_expression(e)), + ExpressionKind::Repeat(e) => format!("{} repeated", describe_expression(e)), + ExpressionKind::RepeatPlus(e) => format!("{} repeated (+)", describe_expression(e)), + ExpressionKind::Alt(_) => "alternative".to_string(), + ExpressionKind::Sequence(_) => "sequence".to_string(), + ExpressionKind::Prose(p) => format!("<{}>", p), + _ => "expression".to_string(), + } +} + +fn check_adjacent_for_splits<'a>( + grammar: &'a Grammar, + left: &'a Expression, + right: &'a Expression, + locations: &mut Vec<(&'a str, String)>, + _current_production: &str, +) { + // Get the possible ending tokens from the left expression + let left_endings = get_possible_endings(grammar, left); + // Get the possible starting tokens from the right expression + let right_starts = get_possible_starts(grammar, right); + + // Get descriptions of the left and right elements + let left_desc = describe_expression(left); + let right_desc = describe_expression(right); + + // Check if any combination could form a multi-char token + for left_end in &left_endings { + for right_start in &right_starts { + let combined = format!("{}{}", left_end, right_start); + for &multi_token in MULTI_CHAR_TOKENS { + if combined == multi_token { + // Exact match - the two elements combine to form the token + locations.push(( + multi_token, + format!( + "{} ends with `{}` and can be immediately followed by {} which can start with `{}`, forming `{}`", + left_desc, left_end, right_desc, right_start, multi_token + ), + )); + } else if combined.starts_with(multi_token) { + // Combined is longer and starts with the token (e.g., "+=" in "+==" for token "+=") + locations.push(( + multi_token, + format!( + "{} ends with `{}` followed by {} starting with `{}` could form `{}`", + left_desc, left_end, right_desc, right_start, multi_token + ), + )); + } else if multi_token.starts_with(&combined) { + // Token is longer than combined (e.g., "+" and "=" is partial for "+=") + // This shouldn't happen since combined should be complete, but keep for completeness + locations.push(( + multi_token, + format!( + "{} ends with `{}` followed by {} starting with `{}` (partial match for `{}`)", + left_desc, left_end, right_desc, right_start, multi_token + ), + )); + } + } + } + } +} + +fn check_repeat_for_splits<'a>( + grammar: &'a Grammar, + expr: &'a Expression, + locations: &mut Vec<(&'a str, String)>, + _current_production: &str, + repeat_type: &str, +) { + // Get the possible endings and starts from the expression + let endings = get_possible_endings(grammar, expr); + let starts = get_possible_starts(grammar, expr); + + let expr_desc = describe_expression(expr); + + // Check if repeating could form a multi-char token + for ending in &endings { + for start in &starts { + let combined = format!("{}{}", ending, start); + for &multi_token in MULTI_CHAR_TOKENS { + if combined == multi_token { + locations.push(( + multi_token, + format!( + "{} (in {}) ends with `{}` and can be immediately followed by another {} which can start with `{}`, forming `{}`", + expr_desc, repeat_type, ending, expr_desc, start, multi_token + ), + )); + } else if combined.starts_with(multi_token) || multi_token.starts_with(&combined) { + locations.push(( + multi_token, + format!( + "{} (in {}) ending with `{}` followed by start `{}` could form `{}`", + expr_desc, repeat_type, ending, start, multi_token + ), + )); + } + } + } + } +} + +fn get_possible_endings(grammar: &Grammar, expr: &Expression) -> HashSet<String> { + let mut endings = HashSet::new(); + get_possible_endings_impl(grammar, expr, &mut endings, &mut HashSet::new()); + endings +} + +fn get_possible_endings_impl( + grammar: &Grammar, + expr: &Expression, + endings: &mut HashSet<String>, + visited: &mut HashSet<String>, +) { + match &expr.kind { + ExpressionKind::Terminal(term) => { + // Extract the last character from the terminal + if let Some(last_ch) = term.chars().last() { + endings.insert(last_ch.to_string()); + } + } + ExpressionKind::Grouped(e) + | ExpressionKind::Optional(e) + | ExpressionKind::NegativeLookahead(e) + | ExpressionKind::Repeat(e) + | ExpressionKind::RepeatPlus(e) + | ExpressionKind::RepeatRange { expr: e, .. } + | ExpressionKind::RepeatRangeNamed(e, _) + | ExpressionKind::NegExpression(e) + | ExpressionKind::Cut(e) => { + get_possible_endings_impl(grammar, e, endings, visited); + } + ExpressionKind::Alt(es) => { + for e in es { + get_possible_endings_impl(grammar, e, endings, visited); + } + } + ExpressionKind::Sequence(es) => { + // The ending comes from the last element in the sequence that produces tokens + // Skip trailing Breaks and Comments + for e in es.iter().rev() { + if !matches!( + e.kind, + ExpressionKind::Break(_) | ExpressionKind::Comment(_) + ) { + get_possible_endings_impl(grammar, e, endings, visited); + break; + } + } + } + ExpressionKind::Nt(nt) => { + if visited.insert(nt.clone()) { + if let Some(prod) = grammar.productions.get(nt) { + get_possible_endings_impl(grammar, &prod.expression, endings, visited); + } + } + } + ExpressionKind::Charset(chars) => { + for ch in chars { + get_possible_endings_impl(grammar, ch, endings, visited); + } + } + ExpressionKind::CharacterRange(a, b) => { + // For ranges, we'll just add the boundary characters + endings.insert(a.get_ch().to_string()); + endings.insert(b.get_ch().to_string()); + } + ExpressionKind::Unicode((ch, _)) => { + endings.insert(ch.to_string()); + } + ExpressionKind::Prose(text) => { + // Handle "Token" prose - it can be any token + if text.to_lowercase().contains("token") { + // Add all characters that could be part of multi-char tokens + for &token in MULTI_CHAR_TOKENS { + for ch in token.chars() { + endings.insert(ch.to_string()); + } + } + } + } + ExpressionKind::Break(_) | ExpressionKind::Comment(_) => { + // These don't produce tokens + } + } +} + +fn get_possible_starts(grammar: &Grammar, expr: &Expression) -> HashSet<String> { + let mut starts = HashSet::new(); + get_possible_starts_impl(grammar, expr, &mut starts, &mut HashSet::new()); + starts +} + +fn get_possible_starts_impl( + grammar: &Grammar, + expr: &Expression, + starts: &mut HashSet<String>, + visited: &mut HashSet<String>, +) { + match &expr.kind { + ExpressionKind::Terminal(term) => { + // Extract the first character from the terminal + if let Some(first_ch) = term.chars().next() { + starts.insert(first_ch.to_string()); + } + } + ExpressionKind::Grouped(e) + | ExpressionKind::NegativeLookahead(e) + | ExpressionKind::Repeat(e) + | ExpressionKind::RepeatPlus(e) + | ExpressionKind::RepeatRange { expr: e, .. } + | ExpressionKind::RepeatRangeNamed(e, _) + | ExpressionKind::NegExpression(e) + | ExpressionKind::Cut(e) => { + get_possible_starts_impl(grammar, e, starts, visited); + } + ExpressionKind::Optional(e) => { + get_possible_starts_impl(grammar, e, starts, visited); + // Optional also means the next element could be the start + } + ExpressionKind::Alt(es) => { + for e in es { + get_possible_starts_impl(grammar, e, starts, visited); + } + } + ExpressionKind::Sequence(es) => { + // The start comes from the first element in the sequence that produces tokens + // Skip leading Breaks and Comments + for e in es.iter() { + if !matches!( + e.kind, + ExpressionKind::Break(_) | ExpressionKind::Comment(_) + ) { + get_possible_starts_impl(grammar, e, starts, visited); + break; + } + } + } + ExpressionKind::Nt(nt) => { + if visited.insert(nt.clone()) { + if let Some(prod) = grammar.productions.get(nt) { + get_possible_starts_impl(grammar, &prod.expression, starts, visited); + } + } + } + ExpressionKind::Charset(chars) => { + for ch in chars { + get_possible_starts_impl(grammar, ch, starts, visited); + } + } + ExpressionKind::CharacterRange(a, b) => { + starts.insert(a.get_ch().to_string()); + starts.insert(b.get_ch().to_string()); + } + ExpressionKind::Unicode((ch, _)) => { + starts.insert(ch.to_string()); + } + ExpressionKind::Prose(text) => { + // Handle "Token" prose - it can be any token + if text.to_lowercase().contains("token") { + // Add all characters that could be part of multi-char tokens + for &token in MULTI_CHAR_TOKENS { + for ch in token.chars() { + starts.insert(ch.to_string()); + } + } + } + } + ExpressionKind::Break(_) | ExpressionKind::Comment(_) => { + // These don't produce tokens + } + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tokenize.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tokenize.rs new file mode 100644 index 00000000..55785e31 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tokenize.rs @@ -0,0 +1,73 @@ +//! A subcommand that converts input to human-readable sequence of tokens. + +use crate::tools::{pm2, rustc, rustc_lexer}; +use crate::{CommonOptions, Tool, display_line}; +use clap::ArgMatches; +use diagnostics::Diagnostics; +use parser::Edition; +use parser::coverage::Coverage; +use parser::lexer::Tokens; +use std::ops::Range; + +pub fn tokenize(matches: &ArgMatches) { + let (mut opts, _) = CommonOptions::new(matches, &[Tool::Reference]); + opts.progress.finish_and_clear(); + for tool in &*opts.tools.clone() { + while let Some((name, src)) = opts.next() { + println!("------------------------------------------------------------"); + println!("tool `{tool}` token results for `{name}`:"); + tokenize_src(&src, *tool, opts.edition()); + println!("------------------------------------------------------------"); + } + } +} + +fn tokenize_src(src: &str, tool: Tool, edition: Edition) { + let tokens = match tool { + Tool::Reference => { + let mut diag = Diagnostics::new(); + let grammar = grammar::load_grammar_with_frontmatter(&mut diag); + let mut coverage = Coverage::default(); + let tokens = parser::lexer::tokenize(&grammar, &mut coverage, src); + if let Ok(Tokens { + shebang: Some(shebang), + .. + }) = &tokens + { + println!("Shebang in range: {:?}", shebang); + } + if let Ok(Tokens { + frontmatter: Some(frontmatter), + .. + }) = &tokens + { + println!("Frontmatter in range: {:?}", frontmatter); + } + tokens.map(|ts| ts.tokens) + } + Tool::RustcParse => rustc::tokenize(src, edition), + Tool::ProcMacro2 => pm2::tokenize(src), + Tool::RustcLexer => rustc_lexer::tokenize(src), + }; + let tokens = match tokens { + Ok(tokens) => tokens, + Err(e) => { + eprintln!( + "error: {}\n\ + {}", + e.message, + display_line( + src, + &Range { + start: e.byte_offset, + end: e.byte_offset + 1 + } + ) + ); + return; + } + }; + for token in tokens { + println!("{:?}: {}", &src[token.range], token.name); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tree.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tree.rs new file mode 100644 index 00000000..e2e6e7ab --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/commands/tree.rs @@ -0,0 +1,73 @@ +//! A subcommand that converts input to a human-readable tree. +//! +//! The output here is pretty hard to read. It could definitely be improved, +//! or maybe even use an HTML-based output. + +use crate::{CommonOptions, Tool, display_line}; +use clap::ArgMatches; +use diagnostics::Diagnostics; +use std::ops::Range; + +pub fn tree(matches: &ArgMatches) { + let (mut opts, _) = CommonOptions::new(matches, &[Tool::Reference]); + opts.progress.finish_and_clear(); + let production = matches.get_one::<String>("production").unwrap(); + for tool in &*opts.tools.clone() { + while let Some((name, src)) = opts.next() { + println!("------------------------------------------------------------"); + println!("tool `{tool}` tree results for `{name}`:"); + display_tree(&src, *tool, production); + println!("------------------------------------------------------------"); + } + } +} + +fn display_tree(src: &str, tool: Tool, production: &str) { + match tool { + Tool::Reference => display_reference_tree(src, production), + _ => unimplemented!("{tool} not implemented yet"), + } +} + +fn display_reference_tree(src: &str, production: &str) { + let mut diag = Diagnostics::new(); + let grammar = grammar::load_grammar_with_frontmatter(&mut diag); + let node = match parser::tree::parse(&grammar, src, production) { + Ok(node) => node, + Err(e) => { + eprintln!( + "error: {}\n\ + {}", + e.message, + display_line( + src, + &Range { + start: e.byte_offset, + end: e.byte_offset + 1 + } + ) + ); + std::process::exit(1); + } + }; + display_tree_node(src, &node, 0); +} + +fn display_tree_node(src: &str, node: &parser::Node, indent: usize) { + let node_text = &src[node.range.clone()]; + let display_text = if node_text.len() > 20 { + format!("{}…", &node_text[..20]) + } else { + node_text.to_string() + }; + println!( + "{}{} {:?} {:?}", + " ".repeat(indent), + node.name, + node.range, + display_text + ); + for child in &node.children.0 { + display_tree_node(src, child, indent + 2); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/main.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/main.rs new file mode 100644 index 00000000..ea571d59 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/main.rs @@ -0,0 +1,428 @@ +#![feature(rustc_private)] + +extern crate rustc_interface; +extern crate rustc_span; + +use clap::{Command, arg}; +use diagnostics::Diagnostics; +use indicatif::{ProgressBar, ProgressStyle}; +use parser::Edition; +use std::cmp::min; +use std::fmt::Display; +use std::io::{IsTerminal, Read}; +use std::ops::Range; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; +use std::sync::Mutex; +use std::sync::mpsc::{Receiver, Sender, channel}; +use std::time::Duration; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use walkdir::WalkDir; + +mod permute; +mod test_cases; +mod commands { + pub mod lex_compare; + pub mod print_grammar; + pub mod split_check; + pub mod tokenize; + pub mod tree; +} +mod tools { + pub mod pm2; + pub mod rustc; + pub mod rustc_lexer; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Tool { + Reference, + RustcParse, + ProcMacro2, + RustcLexer, +} + +impl FromStr for Tool { + type Err = String; + fn from_str(s: &str) -> Result<Self, String> { + match s { + "reference" => Ok(Tool::Reference), + "rustc_parse" => Ok(Tool::RustcParse), + "proc-macro2" => Ok(Tool::ProcMacro2), + "rustc_lexer" => Ok(Tool::RustcLexer), + _ => Err(format!("invalid tool: {s}")), + } + } +} + +impl Display for Tool { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + match self { + Tool::Reference => write!(f, "reference"), + Tool::RustcParse => write!(f, "rustc_parse"), + Tool::ProcMacro2 => write!(f, "proc-macro2"), + Tool::RustcLexer => write!(f, "rustc_lexer"), + } + } +} + +enum Message { + ThreadComplete, + CtrlC, +} + +struct CommonOptions { + strings: Vec<(String, String)>, + paths: Vec<PathBuf>, + permute_iter: Option<Mutex<Box<dyn Iterator<Item = String> + Send>>>, + tools: Arc<Vec<Tool>>, + edition: Option<Edition>, + coverage: bool, + test_count: u32, + thread_count: u32, + errors: Vec<String>, + progress: ProgressBar, + channel: Sender<Message>, + use_spinner: bool, +} + +impl CommonOptions { + fn new( + matches: &clap::ArgMatches, + default_tools: &[Tool], + ) -> (CommonOptions, Receiver<Message>) { + fn map_case(case: &String) -> Vec<(String, String)> { + match case.as_ref() { + "all" => test_cases::LEX_CASES + .iter() + .flat_map(|(name, cases)| { + cases.iter().map(|c| (name.to_string(), c.to_string())) + }) + .collect(), + case_pattern => { + let cs: Vec<_> = test_cases::LEX_CASES + .iter() + .filter(|(name, _)| { + let name_parts: Vec<_> = name.split("::").collect(); + let pattern_parts: Vec<_> = case_pattern.split("::").collect(); + if pattern_parts.len() > name_parts.len() { + return false; + } + name_parts + .iter() + .zip(pattern_parts.iter()) + .all(|(n, p)| n == p) + }) + .flat_map(|(name, cases)| { + cases.iter().map(|c| (name.to_string(), c.to_string())) + }) + .collect(); + if cs.is_empty() { + eprintln!( + "error: case pattern `{case_pattern}` did not match any test cases" + ); + std::process::exit(1); + } + cs + } + } + } + fn map_path(path: &String) -> Result<Vec<PathBuf>, walkdir::Error> { + WalkDir::new(path) + .into_iter() + .collect::<Result<Vec<_>, _>>() + .map(|entries| { + entries + .into_iter() + .filter(|e| e.file_type().is_file()) + .filter(|e| e.path().extension().map(|ext| ext == "rs").unwrap_or(false)) + .map(|e| e.into_path()) + .collect() + }) + } + let mut strings: Vec<_> = matches + .get_many("string") + .map(|ss| { + ss.map(|s: &String| ("CLI string".to_string(), s.to_string())) + .collect() + }) + .unwrap_or_default(); + let cases: Vec<_> = matches + .get_many("case") + .map(|ps| ps.flat_map(map_case).collect()) + .unwrap_or_default(); + strings.extend(cases); + if matches.get_flag("stdin") { + let mut buffer = String::new(); + if std::io::stdin().is_terminal() { + println!("Enter source text:"); + } + std::io::stdin().read_to_string(&mut buffer).unwrap(); + strings.push(("stdin".to_string(), buffer)); + } + let paths: Vec<_> = matches + .get_many("path") + .map(|ps| { + ps.map(map_path) + .collect::<Result<Vec<_>, _>>() + .unwrap_or_else(|e| { + eprintln!("error: failed to read path: {}", e); + std::process::exit(1); + }) + .into_iter() + .flatten() + .collect() + }) + .unwrap_or_default(); + + // Handle --permute flag to generate test cases from grammar productions. + let permute_iter = matches.get_one::<String>("permute").map(|permute_name| { + if permute_name == "three" { + return Mutex::new(Box::new(permute::ThreeIterator::new()) + as Box<dyn Iterator<Item = String> + Send>); + } + let mut diag = Diagnostics::new(); + let grammar = grammar::load_grammar(&mut diag); + + // Leak the grammar to get a 'static reference for the iterator + let grammar_ref: &'static grammar::Grammar = Box::leak(Box::new(grammar)); + let production = &grammar_ref + .productions + .get(permute_name) + .unwrap_or_else(|| panic!("production `{permute_name}` not found")) + .expression; + + Mutex::new( + Box::new(permute::PermutationIterator::new(grammar_ref, production)) + as Box<dyn Iterator<Item = String> + Send>, + ) + }); + + let use_spinner = permute_iter.is_some(); + + if strings.is_empty() && paths.is_empty() && permute_iter.is_none() { + strings.extend(map_case(&"all".to_string())); + } + let tools: Vec<_> = matches + .get_many("tool") + .map(|ts| ts.cloned().collect()) + .unwrap_or_else(|| default_tools.to_vec()); + let tools = Arc::new(tools); + let edition = matches + .get_one::<String>("edition") + .map(|e| e.parse::<Edition>().unwrap()); + for tool in &*tools { + match (tool, edition) { + (Tool::RustcParse, _) => {} + (Tool::Reference, Some(_)) => panic!("reference does not yet support editions"), + (Tool::ProcMacro2, Some(_)) => panic!("proc-macro2 does not support editions"), + (Tool::RustcLexer, Some(_)) => panic!("rustc_lexer is edition agnostic"), + (_, None) => {} + } + } + let coverage = matches.get_flag("coverage"); + // When using permute, we don't know the total count upfront. + let test_count = if use_spinner { + 0 + } else { + ((strings.len() + paths.len()) as u32) * tools.len() as u32 + }; + let available_parallelism = std::thread::available_parallelism().unwrap().get() as u32; + let thread_count = if use_spinner { + available_parallelism + } else { + min(test_count.max(1), available_parallelism) + }; + let progress = if use_spinner { + let p = ProgressBar::new_spinner(); + p.enable_steady_tick(Duration::from_millis(100)); + p + } else { + let p = ProgressBar::new(test_count as u64); + p.enable_steady_tick(Duration::from_millis(200)); + p + }; + progress.set_message("0"); + let (channel, receiver) = channel(); + let opts = CommonOptions { + strings, + paths, + permute_iter, + tools, + edition, + coverage, + test_count, + thread_count, + errors: Vec::new(), + progress, + channel, + use_spinner, + }; + opts.set_progress_style(); + (opts, receiver) + } + + fn next(&mut self) -> Option<(String, String)> { + if let Some((name, src)) = self.strings.pop() { + return Some((name, src)); + } + if let Some(path) = self.paths.pop() { + // TODO: Switch path to a string, not needed as PathBuf anymore. + let contents = std::fs::read_to_string(&path).unwrap(); + let display = format!("{}", path.display()); + return Some((display, contents)); + } + if let Some(ref iter) = self.permute_iter { + if let Ok(mut iter) = iter.lock() { + if let Some(content) = iter.next() { + // println!("{:?}", content); + return Some(("permutation".to_string(), content)); + } + } + } + None + } + + fn set_progress_style(&self) { + let color = if self.errors.is_empty() { + "green" + } else { + "red" + }; + let tick_chars = "🌑🌒🌓🌔🌕🌖🌗🌘"; + if self.use_spinner { + self.progress.set_style( + ProgressStyle::with_template(&format!( + "{{spinner:.green}} [{{elapsed_precise}}] {{pos}} tests — {{msg:.{color}}} failures" + )) + .unwrap() + .tick_chars(tick_chars), + ); + } else { + self.progress.set_style(ProgressStyle::with_template(&format!("{{spinner:.green}} [{{elapsed_precise}}] [{{wide_bar:.blue}}] {{pos}}/{{len}} — {{msg:.{color}}} failures")).unwrap() + .progress_chars("█▉▊▋▌▍▎▏ ") + .tick_chars(tick_chars)); + } + } + + fn set_progress_err_msg(&self) { + self.progress.set_message(format!("{}", self.errors.len())); + self.set_progress_style(); + } + + fn edition(&self) -> Edition { + self.edition.unwrap_or(Edition::Edition2024) + } +} + +fn common_args() -> Vec<clap::Arg> { + vec![ + arg!(--case <CASE> ... "internal test cases to compare"), + arg!(--string <STRING> ... "source string to tokenize"), + arg!(--path <PATH> ... "path of rust files to compare"), + arg!(--permute <NAME> "grammar production to generate permutations for"), + arg!(--tool <TOOLS> ... "tool to compare").value_parser(clap::value_parser!(Tool)), + arg!(--edition <EDITION> "edition to use"), + arg!(--coverage "record coverage data"), + arg!(--stdin "read input from stdin"), + ] +} + +fn main() { + let filter = tracing_subscriber::EnvFilter::builder() + .with_env_var("GRAMMAR_LOG") + .with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into()) + .from_env_lossy(); + + tracing_subscriber::registry() + .with(filter) + .with( + tracing_tree::HierarchicalLayer::new(2) + .with_writer(std::io::stderr) + .with_ansi(std::io::IsTerminal::is_terminal(&std::io::stderr())), + ) + .init(); + + let matches = Command::new("grammar-check") + .subcommand_required(true) + .arg_required_else_help(true) + .subcommand( + Command::new("lex-compare") + .about("Compare tokenization between implementations") + .args(common_args()), + ) + .subcommand( + Command::new("tokenize") + .about("Convert source to tokens") + .args(common_args()), + ) + .subcommand( + Command::new("tree") + .about("Convert source to a tree") + .arg( + arg!(--production <NAME> "the production name to parse").default_value("Crate"), + ) + .args(common_args()), + ) + .subcommand( + Command::new("split-check") + .about("Check for potential token splitting locations in the grammar"), + ) + .subcommand( + Command::new("print-grammar") + .about("Print the grammar to stdout") + .arg(arg!(--debug "Print using Debug format")), + ) + .get_matches(); + match matches.subcommand() { + Some(("lex-compare", sub_matches)) => { + commands::lex_compare::compare_parallel(sub_matches); + } + Some(("tokenize", sub_matches)) => { + commands::tokenize::tokenize(sub_matches); + } + Some(("tree", sub_matches)) => { + commands::tree::tree(sub_matches); + } + Some(("split-check", sub_matches)) => { + commands::split_check::split_check(sub_matches); + } + Some(("print-grammar", sub_matches)) => { + commands::print_grammar::print_grammar(sub_matches); + } + _ => unreachable!(), + } +} + +/// Helper to translate a byte index to a `(line, line_no, col_no)` (1-based). +fn translate_position(input: &str, index: usize) -> (&str, usize, usize) { + if input.is_empty() { + return ("", 0, 0); + } + let index = index.min(input.len()); + + let mut line_start = 0; + let mut line_number = 0; + for line in input.lines() { + let line_end = line_start + line.len(); + if index >= line_start && index <= line_end { + let column_number = index - line_start + 1; + return (line, line_number + 1, column_number); + } + line_start = line_end + 1; + line_number += 1; + } + ("", line_number + 1, 0) +} + +fn display_line(src: &str, range: &Range<usize>) -> String { + let (line, line_no, col_no) = translate_position(src, range.start); + let line = line.replace('\r', "␍"); + let prefix = format!("{line_no}: "); + let indent = col_no.saturating_sub(1); + let len = (range.end - range.start).min(line.len().saturating_sub(indent)); + let underline = format!("{}{}", " ".repeat(prefix.len() + indent), "━".repeat(len)); + format!("{prefix}{line}\n{underline}\n") +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/permute.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/permute.rs new file mode 100644 index 00000000..17bcbf0a --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/permute.rs @@ -0,0 +1,831 @@ +//! Permutation-based tests. +//! +//! This attempts to generate exhaustive coverage of the grammar by using +//! permutations of all of the possible inputs to the grammar. This includes +//! both valid and invalid inputs (particularly those that are truncated). +//! +//! It generates representative inputs for some of the expressions. For +//! example, a repetition generates an output that includes 0, 1, or 2 +//! repetitions of the expression. Or something like "Identifier" just does a +//! few representative values like "a", "ab", and "abb" (with the assumption +//! that the Identifier grammar is already correct). +//! +//! This uses a state machine and is driven using the `Iterator` API to fetch +//! each new input to test. +//! +//! This is incomplete, and I'm not entirely happy with the design. This +//! misses some inputs, particularly invalid ones with unexpected inputs. I +//! intended to spend more time reading +//! https://www.fuzzingbook.org/html/Grammars.html to think of better +//! strategies to stress the parser. +//! +//! However, a coverage-based fuzzer wouldn't necessarily give all the input +//! that I would want because the point of this tool is to compare against +//! rustc. The fuzzer would be fuzzing the Reference grammar, not the rustc +//! parser. We want to get full coverage of *both* those parsers. A fuzzer +//! based on just the Reference coverage wouldn't ensure that the Reference +//! isn't missing something. +//! +//! Known issues: +//! +//! - Permute didn't find that pm2 doesn't error on `prefix'x'` because it was +//! only generating `prefix'`. Any ideas on how to generate tests that +//! exercise this? + +use grammar::{Expression, ExpressionKind, Grammar, RangeLimit}; +use std::collections::HashMap; + +pub struct PermutationIterator<'g> { + pub grammar: &'g Grammar, + name_context: HashMap<String, usize>, + state: IteratorState<'g>, +} + +enum IteratorState<'g> { + Terminal { + value: String, + done: bool, + }, + Seq { + exprs: Vec<&'g Expression>, + /// Current active length; counts down from exprs.len() to 1 to emit truncated sequences. + truncated_len: usize, + iterators: Vec<PermutationIterator<'g>>, + current_values: Vec<String>, + initialized: bool, + exhausted: bool, + }, + SeqWithNamedRanges { + exprs: Vec<&'g Expression>, + named_range_indices: Vec<(usize, String, usize, usize)>, // (index, name, min, max) + current_named_values: HashMap<String, usize>, + iterators: Vec<PermutationIterator<'g>>, + current_values: Vec<String>, + exhausted: bool, + }, + Alt { + iterators: Vec<PermutationIterator<'g>>, + current_index: usize, + }, + Optional { + iterator: Box<PermutationIterator<'g>>, + emitted_empty: bool, + }, + Repeat { + expr: &'g Expression, + include_empty: bool, + current_stage: usize, // 0 = empty (if include_empty), 1 = single, 2 = double + iterator: Option<Box<PermutationIterator<'g>>>, + }, + RepeatRange { + expr: &'g Expression, + max: usize, + current_count: usize, + iterator: Option<Box<PermutationIterator<'g>>>, + pending_repeat: Option<(String, usize)>, // (value, times_left_to_emit) + }, +} + +impl<'g> PermutationIterator<'g> { + pub fn new(grammar: &'g Grammar, expression: &'g Expression) -> PermutationIterator<'g> { + Self::new_with_context(grammar, expression, HashMap::new()) + } + + fn new_with_context( + grammar: &'g Grammar, + expression: &'g Expression, + name_context: HashMap<String, usize>, + ) -> PermutationIterator<'g> { + let state = match &expression.kind { + ExpressionKind::Alt(exprs) => { + let iterators: Vec<_> = exprs + .iter() + .map(|e| Self::new_with_context(grammar, e, name_context.clone())) + .collect(); + IteratorState::Alt { + iterators, + current_index: 0, + } + } + ExpressionKind::Grouped(expr) => { + return Self::new_with_context(grammar, expr, name_context); + } + ExpressionKind::Sequence(exprs) => { + if exprs.is_empty() { + IteratorState::Terminal { + value: String::new(), + done: false, + } + } else { + let filtered_exprs: Vec<&Expression> = exprs + .iter() + .filter(|e| { + !matches!( + e.kind, + ExpressionKind::Break(_) | ExpressionKind::Comment(_) + ) + }) + .collect(); + + // Check if any expressions are named repeat ranges + let mut named_range_indices = Vec::new(); + for (idx, expr) in filtered_exprs.iter().enumerate() { + if let ExpressionKind::RepeatRange { + name: Some(name), + min, + max, + limit, + .. + } = &expr.kind + { + let min_count = min.unwrap_or(0) as usize; + let max_count = match max { + Some(m) => match limit { + RangeLimit::HalfOpen => *m as usize, + RangeLimit::Closed => (*m + 1) as usize, + }, + None => min_count + 3, + }; + named_range_indices.push((idx, name.clone(), min_count, max_count)); + } + } + + if named_range_indices.is_empty() { + // No named ranges, use regular Seq + let n = filtered_exprs.len(); + + IteratorState::Seq { + exprs: filtered_exprs, + truncated_len: n, + iterators: Vec::new(), + current_values: Vec::new(), + initialized: false, + exhausted: false, + } + } else { + // Has named ranges, use special handling + let current_named_values: HashMap<String, usize> = named_range_indices + .iter() + .map(|(_, name, min, _)| (name.clone(), *min)) + .collect(); + + IteratorState::SeqWithNamedRanges { + exprs: filtered_exprs, + named_range_indices, + current_named_values, + iterators: Vec::new(), + current_values: Vec::new(), + exhausted: false, + } + } + } + } + ExpressionKind::Optional(expr) => { + let iterator = + Box::new(Self::new_with_context(grammar, expr, name_context.clone())); + IteratorState::Optional { + iterator, + emitted_empty: false, + } + } + ExpressionKind::NegativeLookahead(expr) => { + let iterator = + Box::new(Self::new_with_context(grammar, expr, name_context.clone())); + IteratorState::Optional { + iterator, + emitted_empty: false, + } + } + ExpressionKind::Repeat(expr) | ExpressionKind::RepeatPlus(expr) => { + IteratorState::Repeat { + expr, + include_empty: true, + current_stage: 0, + iterator: None, + } + } + ExpressionKind::RepeatRange { + expr, + name, + min, + max, + limit, + } => { + // If this has a name and it's in the context, use that specific count + if let Some(name) = name { + if let Some(&count) = name_context.get(name) { + // Use the specified count from context + IteratorState::RepeatRange { + expr, + max: count + 1, + current_count: count, + iterator: None, + pending_repeat: None, + } + } else { + // Name not in context yet, this shouldn't happen in SeqWithNamedRanges + // but handle it anyway + let min_count = min.unwrap_or(0) as usize; + let max_count = match max { + Some(m) => match limit { + RangeLimit::HalfOpen => *m as usize, + RangeLimit::Closed => (*m + 1) as usize, + }, + None => min_count + 3, + }; + let start_count = if min_count == 0 { 0 } else { min_count }; + IteratorState::RepeatRange { + expr, + max: max_count, + current_count: start_count, + iterator: None, + pending_repeat: None, + } + } + } else { + // No name, normal behavior + let min_count = min.unwrap_or(0) as usize; + let max_count = match max { + Some(m) => match limit { + RangeLimit::HalfOpen => *m as usize, + RangeLimit::Closed => (*m + 1) as usize, + }, + None => min_count + 3, + }; + let start_count = if min_count == 0 { 0 } else { min_count }; + IteratorState::RepeatRange { + expr, + max: max_count, + current_count: start_count, + iterator: None, + pending_repeat: None, + } + } + } + ExpressionKind::RepeatRangeNamed(expr, name) => { + // Look up the count from the context + let count = name_context.get(name).copied().unwrap_or(1); + IteratorState::RepeatRange { + expr, + max: count + 1, + current_count: count, + iterator: None, + pending_repeat: None, + } + } + ExpressionKind::Nt(name) => { + let prod = grammar.productions.get(name).unwrap(); + return Self::new_with_context(grammar, &prod.expression, name_context); + } + ExpressionKind::Terminal(s) => IteratorState::Terminal { + value: s.clone(), + done: false, + }, + ExpressionKind::Prose(prose) => match prose.as_str() { + "`XID_Start` defined by Unicode" => IteratorState::Terminal { + value: "a".to_string(), + done: false, + }, + "`XID_Continue` defined by Unicode" => IteratorState::Terminal { + value: "b".to_string(), + done: false, + }, + _ => panic!("prose {prose} not supported"), + }, + ExpressionKind::Break(_) => unreachable!(), + ExpressionKind::Comment(_) => unreachable!(), + ExpressionKind::Charset(chars) => { + let iterators: Vec<_> = chars + .iter() + .map(|e| Self::new_with_context(grammar, e, name_context.clone())) + .collect(); + IteratorState::Alt { + iterators, + current_index: 0, + } + } + ExpressionKind::CharacterRange(start, end) => { + // Behave like Alt of start and end characters + let mut iterators = Vec::new(); + let start_ch = start.get_ch(); + let end_ch = end.get_ch(); + iterators.push(PermutationIterator { + grammar, + name_context: name_context.clone(), + state: IteratorState::Terminal { + value: start_ch.to_string(), + done: false, + }, + }); + iterators.push(PermutationIterator { + grammar, + name_context: name_context.clone(), + state: IteratorState::Terminal { + value: end_ch.to_string(), + done: false, + }, + }); + IteratorState::Alt { + iterators, + current_index: 0, + } + } + ExpressionKind::NegExpression(_expr) => IteratorState::Terminal { + value: String::from("a"), // TODO: Comment here why this choice. + done: false, + }, + ExpressionKind::Cut(expr) => { + return Self::new_with_context(grammar, expr, name_context); + } + ExpressionKind::Unicode((ch, _)) => IteratorState::Terminal { + value: ch.to_string(), + done: false, + }, + }; + PermutationIterator { + grammar, + name_context, + state, + } + } +} + +impl<'g> Iterator for PermutationIterator<'g> { + type Item = String; + + fn next(&mut self) -> Option<Self::Item> { + // Capture grammar reference before mutably borrowing state + let grammar = self.grammar; + + match &mut self.state { + IteratorState::Terminal { value, done } => { + if *done { + None + } else { + *done = true; + Some(value.clone()) + } + } + IteratorState::Alt { + iterators, + current_index, + } => { + while *current_index < iterators.len() { + if let Some(val) = iterators[*current_index].next() { + return Some(val); + } + *current_index += 1; + } + None + } + IteratorState::Optional { + iterator, + emitted_empty, + } => { + if !*emitted_empty { + *emitted_empty = true; + return Some(String::new()); + } + iterator.next() + } + IteratorState::Repeat { + expr, + include_empty, + current_stage, + iterator, + } => { + // Stage 0: emit empty string (only for Repeat, not RepeatPlus) + if *current_stage == 0 && *include_empty { + *current_stage = 1; + return Some(String::new()); + } + + // Stage 1: emit single permutations + if *current_stage == 1 { + if iterator.is_none() { + *iterator = Some(Box::new(Self::new_with_context( + grammar, + expr, + self.name_context.clone(), + ))); + } + + if let Some(iter) = iterator { + if let Some(result) = iter.next() { + return Some(result); + } + } + + // Stage 1 complete, move to stage 2 + *current_stage = 2; + *iterator = Some(Box::new(Self::new_with_context( + grammar, + expr, + self.name_context.clone(), + ))); + } + + // Stage 2: emit double permutations (each element repeated twice) + if *current_stage == 2 { + // Get next single value and prepare to emit it twice + if let Some(iter) = iterator { + if let Some(val) = iter.next() { + let doubled = format!("{val}{val}"); + return Some(doubled); + } + } + } + + None + } + IteratorState::RepeatRange { + expr, + max, + current_count, + iterator, + pending_repeat, + } => { + // If we're at count 0 (min was 0), emit empty string + if *current_count == 0 { + *current_count = 1; + if *current_count >= *max { + return None; + } + return Some(String::new()); + } + + loop { + // If we haven't reached max count yet + if *current_count >= *max { + return None; + } + + // Check if we have a pending repeat to emit + if let Some((val, times_left)) = pending_repeat { + if *times_left > 1 { + *times_left -= 1; + return Some(val.clone()); + } else { + // Emit last repetition and clear pending + let result = val.clone(); + *pending_repeat = None; + return Some(result); + } + } + + // Initialize iterator for current count if needed + if iterator.is_none() { + *iterator = Some(Box::new(Self::new_with_context( + grammar, + expr, + self.name_context.clone(), + ))); + } + + // Try to get next value from iterator + if let Some(iter) = iterator { + if let Some(val) = iter.next() { + let result = val.repeat(*current_count); + return Some(result); + } + } + + // Current count exhausted, move to next + *current_count += 1; + *iterator = None; + } + } + IteratorState::Seq { + exprs, + truncated_len, + iterators, + current_values, + initialized, + exhausted, + } => { + if *exhausted { + return None; + } + + loop { + // (Re)initialize iterators for the current truncated_len. + if !*initialized { + let tlen = *truncated_len; + *iterators = exprs[..tlen] + .iter() + .map(|e| Self::new_with_context(grammar, e, self.name_context.clone())) + .collect(); + *current_values = vec![String::new(); tlen]; + + // Get first value from each iterator. + let mut ok = true; + for (i, iter) in iterators.iter_mut().enumerate() { + if let Some(val) = iter.next() { + current_values[i] = val; + } else { + ok = false; + break; + } + } + + if ok { + *initialized = true; + return Some(current_values.concat()); + } else { + // Empty iterator at this length; try shorter. + if *truncated_len > 1 { + *truncated_len -= 1; + continue; + } else { + *exhausted = true; + return None; + } + } + } + + // Try to advance the rightmost iterator. + let mut pos = iterators.len() - 1; + let mut advanced = false; + loop { + if let Some(val) = iterators[pos].next() { + current_values[pos] = val; + advanced = true; + break; + } else { + // This iterator is exhausted; reset it and move left. + if pos == 0 { + // All iterators for this truncated_len are exhausted. + break; + } + iterators[pos] = Self::new_with_context( + grammar, + &exprs[pos], + self.name_context.clone(), + ); + if let Some(val) = iterators[pos].next() { + current_values[pos] = val; + } + pos -= 1; + } + } + + if advanced { + return Some(current_values.concat()); + } + + // Current length exhausted; move to the next shorter truncation. + if *truncated_len > 1 { + *truncated_len -= 1; + *initialized = false; + } else { + *exhausted = true; + return None; + } + } + } + IteratorState::SeqWithNamedRanges { + exprs, + named_range_indices, + current_named_values, + iterators, + current_values, + exhausted, + } => { + if *exhausted { + return None; + } + + loop { + // Initialize iterators if needed + if iterators.is_empty() { + for expr in exprs.iter() { + iterators.push(Self::new_with_context( + grammar, + expr, + current_named_values.clone(), + )); + } + *current_values = iterators.iter().map(|_| String::new()).collect(); + + // Get first value from each iterator + for (i, iter) in iterators.iter_mut().enumerate() { + if let Some(val) = iter.next() { + current_values[i] = val; + } else { + // Empty iterator, try next name values + break; + } + } + + if current_values.iter().all(|v| !v.is_empty()) { + return Some(current_values.concat()); + } + } + + // Try to advance rightmost iterator + let mut pos = iterators.len().checked_sub(1)?; + loop { + if let Some(val) = iterators[pos].next() { + current_values[pos] = val; + return Some(current_values.concat()); + } else { + // This iterator exhausted + if pos == 0 { + // All iterators for this name combo exhausted + // Try to increment named values (only min and max, not values in between) + let mut incremented = false; + for (_idx, name, min, max) in named_range_indices.iter().rev() { + let current_val = + current_named_values.get(name).copied().unwrap_or(*min); + // Only generate for min and max values + if current_val == *min && *min + 1 < *max { + // Jump from min to max-1 (which is the actual max value since max is exclusive) + current_named_values.insert(name.clone(), *max - 1); + incremented = true; + break; + } else { + // Reset to min + current_named_values.insert(name.clone(), *min); + } + } + + if !incremented { + *exhausted = true; + return None; + } + + // Reset all iterators with new named values + iterators.clear(); + current_values.clear(); + break; // Go back to initialization + } + + // Reset this iterator and move left + iterators[pos] = Self::new_with_context( + grammar, + &exprs[pos], + current_named_values.clone(), + ); + if let Some(val) = iterators[pos].next() { + current_values[pos] = val; + } + pos -= 1; + } + } + } + } + } + } +} + +/// Generates all permutations of one, two, or three character long strings. +pub struct ThreeIterator { + /// Current string length being generated (1, 2, or 3). + len: u8, + /// Character indices for each position (values 0..=0x7F). + indices: [u8; 3], + /// Set when all lengths are exhausted. + done: bool, +} + +impl ThreeIterator { + pub fn new() -> ThreeIterator { + ThreeIterator { + len: 1, + indices: [0; 3], + done: false, + } + } +} + +impl Iterator for ThreeIterator { + type Item = String; + + fn next(&mut self) -> Option<Self::Item> { + if self.done { + return None; + } + + let len = self.len as usize; + + // Build the current string from the active indices. + let result: String = self.indices[..len] + .iter() + .map(|&i| char::from_u32(i as u32).unwrap()) + .collect(); + + // Advance indices right-to-left, carrying into higher positions. + let mut carry = true; + for i in (0..len).rev() { + if carry { + if self.indices[i] < 0x7F { + self.indices[i] += 1; + carry = false; + } else { + self.indices[i] = 0; + // carry remains true; propagate left + } + } + } + + if carry { + // All positions overflowed — this length is exhausted. + if self.len < 3 { + self.len += 1; + self.indices = [0; 3]; + } else { + self.done = true; + } + } + + Some(result) + } +} + +#[cfg(test)] +mod tests { + use super::*; + fn assert_permutations(grammar: &str, expected: &[&str]) { + let g = Grammar::grammar_from_str(grammar, "cat").unwrap(); + let e = &g.productions.get("P").unwrap().expression; + let ps: Vec<_> = PermutationIterator::new(&g, e).collect(); + assert_eq!(ps, expected); + } + + #[test] + fn seq_and_alt() { + // Full sequence, then truncations (length 2, then length 1). + assert_permutations( + "P -> `A` (`B` | (`C1` | `C2`) | `D`) `E`", + &["ABE", "AC1E", "AC2E", "ADE", "AB", "AC1", "AC2", "AD", "A"], + ); + } + + #[test] + fn optional() { + // Full sequence, then truncations. + assert_permutations( + "P -> `A` (`B` | `C`)? `D`", + &["AD", "ABD", "ACD", "A", "AB", "AC", "A"], + ); + } + + #[test] + fn seq_truncated() { + // A single sequence with no alternatives: ABC, then AB, then A. + assert_permutations("P -> `A` `B` `C`", &["ABC", "AB", "A"]); + } + + #[test] + fn seq_truncated_with_alts() { + // Each position has alternatives; verify all combos per length, then shorter lengths. + assert_permutations( + "P -> (`A` | `X`) (`B` | `Y`)", + &["AB", "AY", "XB", "XY", "A", "X"], + ); + } + + #[test] + fn repeat() { + assert_permutations("P -> (`A` | `B`)*", &["", "A", "B", "AA", "BB"]); + } + + #[test] + fn repeat_plus() { + assert_permutations("P -> (`A` | `B`)+", &["", "A", "B", "AA", "BB"]); + } + + #[test] + fn repeat_range() { + assert_permutations("P -> (`A` | `B`){0..}", &["", "A", "B", "AA", "BB"]); + + assert_permutations("P -> (`A` | `B`){1..3}", &["A", "B", "AA", "BB"]); + + assert_permutations("P -> (`A` | `B`){2..=3}", &["AA", "BB", "AAA", "BBB"]); + } + + #[test] + fn charset() { + // Test with Terminal and Range + assert_permutations("P -> [`A` `X`-`Z`]", &["A", "X", "Z"]); + + // Test with just Range + assert_permutations("P -> [`a`-`c`]", &["a", "c"]); + } + + #[test] + fn named_repeat_range() { + // Test named repeat ranges are synchronized (only min and max values) + assert_permutations("P -> `A`{n:1..=5} `B` `C`{n}", &["ABC", "AAAAABCCCCC"]); + } + + #[test] + fn negative_lookahead() { + // NegativeLookahead emits empty string first, then all permutations of the expression. + assert_permutations("P -> !`A`", &["", "A"]); + assert_permutations("P -> !(`A` | `B`)", &["", "A", "B"]); + // In a sequence: empty lookahead plus the rest, then lookahead expr plus the rest, + // then truncated-length permutations (just the lookahead expression alone). + assert_permutations("P -> !`X` `Y`", &["Y", "XY", "", "X"]); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/test_cases.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/test_cases.rs new file mode 100644 index 00000000..7b7b7f66 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/test_cases.rs @@ -0,0 +1,111 @@ +//! Built-in test cases. +//! +//! The initial idea with this was to collect a broad set of tests that +//! exercise all of the grammar rules. However, that's a tall order as it +//! would end up being quite large. I instead started leaning on the +//! permutation-based tests to more exhaustively cover the grammar. However, +//! there's less certainty using that mechanism, and it also makes it harder +//! to iterate on a single grammar rule. This may still be useful, but would +//! take some considerable work to make it useful. + +macro_rules! cases { + ($($name:path => $($s:literal)+)+) => { + pub static LEX_CASES: &[(&str, &[&str])] = &[ + $( + (stringify!($name), &[ $($s),* ]), + )+ + ]; + }; +} + +cases! { + empty => + "" + + comment::line_comment => + "// line comment" + "////" + "//// this is a comment" + "//\n" + comment::block_comment => + "/* block comment */" + comment::inner_line_doc => + "//! inner line doc" + comment::inner_block_doc => + "/*! inner block doc */" + comment::outer_line_doc => + "/// outer line doc" + "///" + "///\n" + "///abc\n" + "/// ☃" + comment::outer_block_doc => + "/** outer block doc */" + comment::cr_starting_block_doc => + "/**\r CR starting block doc comment */" + comment::cr_starting_inner_block_doc => + "/*!\r CR starting inner block doc comment */" + + comment::block::nested_cr1 => + "/* /**\r*/ */" + comment::block::nested_cr2 => + "/* /*!\r*/ */" + comment::block::nested_cr3 => + "/* /** x\r y */ */" + comment::block::nested_cr4 => + "/** /*\r*/ */" + comment::block::nested_cr5 => + "/*! /*\r*/ */" + comment::block::nested_cr6 => + "/** /* x\r y */ */" + comment::block::nested_cr7 => + "/** /* /*\r*/ */ */" + comment::block::nested_cr8 => + "/* /* /**\r*/ */ */" + + reserved::pounds => + "##" + "###" + "####" + "#####" + + raw_identifier => + "r#fn" + char => + "'x'" + string => + "\"string\"" + string::continuation::bare_carriage => + "\"string\\\n\n\r\tcontinuation\"" + + raw_string => + "r\"raw string\"" + "r#\"raw string\"#" + "r#\"\"\"#" + byte => + "b'x'" + byte_string => + "b\"byte\"" + raw_byte_string => + "br\"raw byte\"" + "br#\"raw byte\"#" + c_string => + "c\"c str\"" + raw_c_string => + "cr\"raw c str\"" + "cr#\"raw c str\"#" + float => + "1.2" + integer => + "123" + lifetime => + "'a" + punctuation => + "!" + identifier => + "ident" + "fn" + + shebang::doc_comment => + "#! /** doc */ [attr]\n" +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/pm2.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/pm2.rs new file mode 100644 index 00000000..f471daae --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/pm2.rs @@ -0,0 +1,455 @@ +//! The proc-macro2 tool. + +use parser::lexer::Tokens; +use parser::{Node, ParseError}; +use proc_macro2::{Spacing, TokenStream, TokenTree}; +use regex::Regex; +use std::ops::Range; +use std::str::FromStr; +use std::sync::LazyLock; + +pub fn tokenize(src: &str) -> Result<Vec<Node>, ParseError> { + let mut tokens = Vec::new(); + let stream = TokenStream::from_str(src).map_err(|e| ParseError { + byte_offset: 0, + message: e.to_string(), + })?; + tokens_from_ts(src, stream, &mut tokens)?; + Ok(tokens) +} + +// proc-macro2 does not reject literals starting with E. +// We'll need to do that to match behavior. +// https://github.com/dtolnay/proc-macro2/issues/506 +static SUFFIX_NO_E: LazyLock<Regex> = LazyLock::new(|| { + Regex::new( + r"(?x) + ^( + ([0-9][0-9_]*[eE]) # DEC_LITERAL + | (0b([01]|_)*?[01]([01]|_)*[eE]) # BIN_LITERL + | (0o([0-7]|_)*?[0-7]([0-7]|_)*[eE]) # OCT_LITERAL + | ([0-9]([0-9]|_)*\.[0-9]([0-9]|_)*[eE]) # FLOAT_LITERAL + ) + ", + ) + .unwrap() +}); + +static FLOAT_EXPONENT: LazyLock<Regex> = LazyLock::new(|| { + Regex::new( + r"(?x) + ^ + [0-9]([0-9]|_)* + (\. [0-9]([0-9]|_)*)? + [eE] [+-]? ([0-9]|_)*? [0-9] ([0-9]|_)* + ", + ) + .unwrap() +}); + +static NUM_DOT: LazyLock<Regex> = LazyLock::new(|| { + Regex::new( + r"(?x) + ^( + (0b([01]|_)*?[01]([01]|_)*) # BIN_LITERL + | (0o([0-7]|_)*?[0-7]([0-7]|_)*) # OCT_LITERAL + | (0x([0-9a-fA-F]|_)*?[0-9a-fA-F]([0-9a-fA-F]|_)*) # HEX_LITERAL + ) + \. + ", + ) + .unwrap() +}); + +fn tokens_from_ts(src: &str, ts: TokenStream, output: &mut Vec<Node>) -> Result<(), ParseError> { + let trees: Vec<TokenTree> = ts.into_iter().collect(); + let mut i = 0; + while i < trees.len() { + let tt = &trees[i]; + let span = tt.span(); + let mut range = span.byte_range(); + + // For OUTER_LINE_DOC and CRLF input, the range ends up pointing at + // the CR. Adjust this to match the other tools. + let s_range = &src[range.clone()]; + if (s_range.starts_with("///") || s_range.starts_with("//!")) && s_range.ends_with('\r') { + range.end -= 1; + } + + match tt { + TokenTree::Ident(_) => { + // proc-macro2 does not reject Edition 2021 reserved prefixes. + // https://github.com/dtolnay/proc-macro2/issues/534 + if src[range.end..].chars().next() == Some('"') + && !matches!(&src[range.clone()], "b" | "c" | "r" | "br" | "cr") + { + return Err(ParseError { + message: "RESERVED_TOKEN_DOUBLE_QUOTE".to_string(), + byte_offset: range.end, + }); + } + if src[range.end..].chars().next() == Some('\'') + && !matches!(&src[range.clone()], "b") + { + return Err(ParseError { + message: "RESERVED_TOKEN_SINGLE_QUOTE".to_string(), + byte_offset: range.end, + }); + } + + if src[range.end..].chars().next() == Some('#') { + return Err(ParseError { + message: "RESERVED_TOKEN_POUND".to_string(), + byte_offset: range.start, + }); + } + + i += 1; + let name = if src[range.start..].starts_with("r#") { + "RAW_IDENTIFIER" + } else { + "IDENTIFIER_OR_KEYWORD" + } + .to_string(); + output.push(Node::new(name, range)); + } + TokenTree::Punct(p) => { + // In order to be consistent with rustc which uses joined tokens, + // this looks to join multiple punctuation tokens. + + // s accumulates the punctuation string. + let mut s = p.as_char().to_string(); + i += 1; + let mut current_spacing = p.spacing(); + + // Try to consume subsequent punctuation if it is joint and + // forms a valid operator. + while current_spacing == Spacing::Joint && i < trees.len() { + match &trees[i] { + TokenTree::Punct(next_p) => { + s.push(next_p.as_char()); + if is_valid_punctuation(&s) { + range.end = next_p.span().byte_range().end; + current_spacing = next_p.spacing(); + i += 1; + } else { + s.pop(); + break; + } + } + TokenTree::Ident(ident) => { + // lifetime + s.push_str(&ident.to_string()); + range.end = ident.span().byte_range().end; + + // For some reason, proc-macro2 doesn't seem to fail + // when it sees IDENT'IDENT. + if i >= 2 { + let prev_tt = &trees[i - 2]; + let prev_range = prev_tt.span().byte_range(); + if let TokenTree::Ident(_) = prev_tt + && prev_range.end == range.start + { + return Err(ParseError { + message: "RESERVED_TOKEN_SINGLE_QUOTE".to_string(), + byte_offset: prev_range.start, + }); + } + } + i += 1; + break; + } + _ => break, + } + } + + // https://github.com/dtolnay/proc-macro2/issues/535 + if s == "#" + && i < trees.len() + && let TokenTree::Literal(lit) = &trees[i] + && lit.to_string().starts_with('"') + && trees[i].span().byte_range().start == range.start + 1 + { + return Err(ParseError { + message: "RESERVED_GUARDED_STRING_LITERAL".to_string(), + byte_offset: range.start, + }); + } + + let name = if s.starts_with('\'') && s.len() > 1 { + "LIFETIME_TOKEN" + } else { + "PUNCTUATION" + } + .to_string(); + output.push(Node::new(name, range)); + } + TokenTree::Literal(lit) => { + let s = lit.to_string(); + if SUFFIX_NO_E.is_match(&s) && !FLOAT_EXPONENT.is_match(&s) { + return Err(ParseError { + message: "bad E suffix".to_string(), + byte_offset: range.start, + }); + } + + // https://github.com/dtolnay/proc-macro2/issues/531 + if [ + "'''", "'\r'", "'\n'", "'\t'", "b'''", "b'\r'", "b'\n'", "b'\t'", + ] + .iter() + .any(|p| s.starts_with(p)) + { + return Err(ParseError { + message: "invalid byte or char literal".to_string(), + byte_offset: range.start, + }); + } + + // https://github.com/dtolnay/proc-macro2/issues/532 + if matches!(s.as_bytes().last_chunk::<2>(), Some(b"'_" | b"\"_" | b"#_")) { + return Err(ParseError { + message: "underscore suffix not allowed".to_string(), + byte_offset: range.start, + }); + } + + // https://github.com/dtolnay/proc-macro2/issues/533 + let s_rest = &src[range.start..]; + if let Some(m) = NUM_DOT.find(s_rest) { + let next = src[range.start + m.len()..].chars().next(); + if !matches!(next, Some('.' | '_')) + && !next + .map(|ch| unicode_ident::is_xid_start(ch)) + .unwrap_or(false) + { + return Err(ParseError { + message: "reserved bin/oct/hex literal followed by .".to_string(), + byte_offset: range.start, + }); + } + } + + output.push(Node::new(lit_to_reference(&s), range)); + i += 1; + } + TokenTree::Group(group) => { + let delim = group.delimiter(); + let delim_str = match &delim { + proc_macro2::Delimiter::Parenthesis => "(", + proc_macro2::Delimiter::Brace => "{", + proc_macro2::Delimiter::Bracket => "[", + proc_macro2::Delimiter::None => "", + }; + if !delim_str.is_empty() { + output.push(Node::new( + "PUNCTUATION".to_string(), + group.span_open().byte_range(), + )); + } + tokens_from_ts(src, group.stream(), output)?; + if !delim_str.is_empty() { + let close_delim = match delim_str { + "(" => ")", + "{" => "}", + "[" => "]", + _ => "", + }; + let mut range = group.span_close().byte_range(); + // proc-macro2's CRLF handling ends up with a range pointing + // at the CR instead of the byte before. + if &src[range.clone()] == "\r" && close_delim == "]" { + range.start -= 1; + range.end -= 1; + // After shifting back one byte we may now be inside a + // multi-byte UTF-8 character. Walk start back further + // until we're on a char boundary, then set end to the + // end of that character. + while range.start > 0 && !src.is_char_boundary(range.start) { + range.start -= 1; + } + range.end = range.start + + src[range.start..] + .chars() + .next() + .map_or(1, |c| c.len_utf8()); + } + output.push(Node::new("PUNCTUATION".to_string(), range)); + } + i += 1; + } + } + } + Ok(()) +} + +fn lit_to_reference(lit: &str) -> String { + if lit.starts_with("cr") { + "RAW_C_STRING_LITERAL".to_string() + } else if lit.starts_with('c') { + "C_STRING_LITERAL".to_string() + } else if lit.starts_with("br") { + "RAW_BYTE_STRING_LITERAL".to_string() + } else if lit.starts_with("b'") { + "BYTE_LITERAL".to_string() + } else if lit.starts_with("b\"") { + "BYTE_STRING_LITERAL".to_string() + } else if lit.starts_with("r\"") || lit.starts_with("r#") { + "RAW_STRING_LITERAL".to_string() + } else if lit.starts_with('\'') { + "CHAR_LITERAL".to_string() + } else if lit.starts_with('"') { + "STRING_LITERAL".to_string() + } else if lit.starts_with("0x") || lit.starts_with("0o") || lit.starts_with("0b") { + "INTEGER_LITERAL".to_string() + } else if lit.contains('.') { + "FLOAT_LITERAL".to_string() + } else if lit.contains('e') || lit.contains('E') { + // Could be float with exponent or integer with suffix containing 'e'/'E' + // Check if there's a valid float exponent pattern + if lit + .bytes() + .position(|b| b == b'e' || b == b'E') + .map(|pos| { + lit.as_bytes() + .get(pos - 1) + .map_or(false, |&ch| ch.is_ascii_digit() || ch == b'_') + }) + .unwrap_or(false) + { + "FLOAT_LITERAL".to_string() + } else { + "INTEGER_LITERAL".to_string() + } + } else { + "INTEGER_LITERAL".to_string() + } +} + +fn is_valid_punctuation(s: &str) -> bool { + matches!( + s, + "..." + | "..=" + | "<<=" + | ">>=" + | "!=" + | "%=" + | "&&" + | "&=" + | "*=" + | "+=" + | "-=" + | "->" + | ".." + | "/=" + | "::" + | "<-" + | "<<" + | "<=" + | "==" + | "=>" + | ">=" + | ">>" + | "^=" + | "|=" + | "||" + ) +} + +pub fn normalize( + pm2_result: Result<Vec<Node>, ParseError>, + reference_result: Result<Tokens, ParseError>, + src: &str, +) -> (Result<Vec<Node>, ParseError>, Result<Vec<Node>, ParseError>) { + let reference_result = + reference_result.map(|tokens| normalize_reference_tokens(tokens.tokens, src)); + let pm2_result = match (&pm2_result, &reference_result) { + (Ok(_), Err(e)) => { + // For some reason, proc-macro2 treats NBSP as whitespace. + if src[e.byte_offset..].chars().next() == Some('\u{a0}') { + Err(ParseError { + message: "unexpected NBSP whitespace".to_string(), + byte_offset: e.byte_offset, + }) + } else { + pm2_result + } + } + _ => pm2_result, + }; + (pm2_result, reference_result) +} + +fn normalize_reference_tokens(tokens: Vec<Node>, src: &str) -> Vec<Node> { + let len = tokens.len(); + tokens + .into_iter() + .filter(|token| !matches!(token.name.as_str(), "LINE_COMMENT" | "BLOCK_COMMENT")) + .fold(Vec::with_capacity(len), |mut acc, token| { + // proc-macro2 does not handle ## reserved tokens (treats them as individual punctuation) + // https://github.com/dtolnay/proc-macro2/issues/535 + if token.name == "RESERVED_TOKEN" && src[token.range.clone()].chars().all(|c| c == '#') + { + let count = token.range.len(); + for i in 0..count { + acc.push(Node::new( + String::from("PUNCTUATION"), // # + Range { + start: token.range.start + i, + end: token.range.start + i + 1, + }, + )); + } + return acc; + } + // proc-macro2 converts doc comments into doc attributes. + match &*token.name { + "OUTER_LINE_DOC" | "INNER_LINE_DOC" | "OUTER_BLOCK_DOC" | "INNER_BLOCK_DOC" => { + acc.push(Node::new( + String::from("PUNCTUATION"), // # + token.range.clone(), + )); + if token.name.starts_with("INNER") { + acc.push(Node::new( + String::from("PUNCTUATION"), // ! + token.range.clone(), + )); + } + acc.push(Node::new( + String::from("PUNCTUATION"), // [ + Range { + start: token.range.start, + end: token.range.start + 1, + }, + )); + acc.push(Node::new( + String::from("IDENTIFIER_OR_KEYWORD"), + token.range.clone(), + )); + acc.push(Node::new( + String::from("PUNCTUATION"), // = + token.range.clone(), + )); + acc.push(Node::new( + String::from("STRING_LITERAL"), + token.range.clone(), + )); + acc.push(Node::new( + String::from("PUNCTUATION"), // ] + Range { + start: token.range.end + - src[..token.range.end] + .chars() + .next_back() + .unwrap() + .len_utf8(), + end: token.range.end, + }, + )); + } + _ => acc.push(token), + } + acc + }) +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc.rs new file mode 100644 index 00000000..d374c93c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc.rs @@ -0,0 +1,267 @@ +//! The `rustc_parse`-based tool. + +use std::fmt::Write as _; +extern crate rustc_ast; +extern crate rustc_driver; +extern crate rustc_errors; +extern crate rustc_lexer; +extern crate rustc_parse; +extern crate rustc_session; +extern crate rustc_span; + +use parser::{Edition, Node, ParseError}; +use rustc_ast::ast::AttrStyle; +use rustc_ast::token::{CommentKind, IdentIsRaw, TokenKind}; +use rustc_errors::emitter::HumanReadableErrorType; +use rustc_errors::json::JsonEmitter; +use rustc_errors::{ColorConfig, DiagCtxt}; +use rustc_parse::lexer::StripTokens; +use rustc_session::parse::ParseSess; +use rustc_span::FileName; +use rustc_span::fatal_error::FatalError; +use rustc_span::source_map::{FilePathMapping, SourceMap}; +use std::io; +use std::io::Write; +use std::ops::Range; +use std::sync::{Arc, Mutex}; + +struct Shared<T> { + data: Arc<Mutex<T>>, +} + +impl<T: Write> Write for Shared<T> { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + self.data.lock().unwrap().write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.data.lock().unwrap().flush() + } +} + +fn to_rustc_edition(edition: Edition) -> rustc_span::edition::Edition { + match edition { + Edition::Edition2015 => rustc_span::edition::Edition::Edition2015, + Edition::Edition2018 => rustc_span::edition::Edition::Edition2018, + Edition::Edition2021 => rustc_span::edition::Edition::Edition2021, + Edition::Edition2024 => rustc_span::edition::Edition::Edition2024, + } +} + +pub fn tokenize(src: &str, edition: Edition) -> Result<Vec<Node>, ParseError> { + rustc_span::create_session_globals_then(to_rustc_edition(edition), &[], None, || { + let source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); + // TODO: probably not needed? + // source_map.new_source_file(Path::new("test.rs").to_owned().into(), "".to_owned()); + let output = Arc::new(Mutex::new(Vec::new())); + let je = JsonEmitter::new( + Box::new(Shared { + data: output.clone(), + }), + Some(source_map.clone()), + false, // pretty + HumanReadableErrorType { + short: true, + unicode: true, + }, + ColorConfig::Never, + ); + + let dcx = DiagCtxt::new(Box::new(je)); + let psess = ParseSess::with_dcx(dcx, source_map); + // TODO: Use StripTokens::Nothing before frontmatter is + // stabilized. Use StripTokens::ShebangAndFrontmatter after it is + // stabilized. + let strip_tokens = StripTokens::ShebangAndFrontmatter; + let source = String::from(src); + let filename = FileName::Custom("internal".into()); + rustc_driver::catch_fatal_errors(|| { + let mut parser = match rustc_parse::new_parser_from_source_str( + &psess, + filename, + source, + strip_tokens, + ) { + Ok(parser) => parser, + Err(e) => { + for diag in e { + diag.emit(); + } + FatalError.raise(); + } + }; + let mut tokens = Vec::new(); + while parser.token.kind != TokenKind::Eof { + let source_file = psess + .source_map() + .lookup_source_file(parser.token.span.lo()); + let start = source_file + .original_relative_byte_pos(parser.token.span.lo()) + .0 as usize; + let end = source_file + .original_relative_byte_pos(parser.token.span.hi()) + .0 as usize; + + let token = Node::new(to_reference_name(&parser.token.kind), Range { start, end }); + tokens.push(token); + parser.bump(); + } + // Unfortunately this is handled outside of normal lexing. + psess.bad_unicode_identifiers.with_lock(|idents| { + for (ident, spans) in idents.drain(..) { + psess + .dcx() + .struct_span_err( + spans, + format!("identifiers cannot contain emoji: {ident}"), + ) + .emit(); + } + }); + psess.dcx().emit_stashed_diagnostics(); + let diags = diagnostics(&output.lock().unwrap()); + if diags.iter().any(|diag| diag.level.starts_with("error")) { + FatalError.raise(); + } + tokens + }) + .map_err(|_| { + let mut message = String::new(); + let out = &output.lock().unwrap(); + let diags = diagnostics(out); + let mut byte_offset = 0; + for diag in diags { + write!(message, "error: {}", diag.rendered).unwrap(); + if byte_offset == 0 { + byte_offset = diag + .spans + .iter() + .find(|sp| sp.is_primary) + .map(|sp| sp.byte_start) + .unwrap_or_default(); + } + } + ParseError { + byte_offset: byte_offset as usize, + message, + } + }) + }) +} + +fn to_reference_name(kind: &TokenKind) -> String { + match kind { + TokenKind::Eq + | TokenKind::Lt + | TokenKind::Le + | TokenKind::EqEq + | TokenKind::Ne + | TokenKind::Ge + | TokenKind::Gt + | TokenKind::AndAnd + | TokenKind::OrOr + | TokenKind::Bang + | TokenKind::Tilde + | TokenKind::Plus + | TokenKind::Minus + | TokenKind::Star + | TokenKind::Slash + | TokenKind::Percent + | TokenKind::Caret + | TokenKind::And + | TokenKind::Or + | TokenKind::Shl + | TokenKind::Shr + | TokenKind::PlusEq + | TokenKind::MinusEq + | TokenKind::StarEq + | TokenKind::SlashEq + | TokenKind::PercentEq + | TokenKind::CaretEq + | TokenKind::AndEq + | TokenKind::OrEq + | TokenKind::ShlEq + | TokenKind::ShrEq + | TokenKind::At + | TokenKind::Dot + | TokenKind::DotDot + | TokenKind::DotDotDot + | TokenKind::DotDotEq + | TokenKind::Comma + | TokenKind::Semi + | TokenKind::Colon + | TokenKind::PathSep + | TokenKind::RArrow + | TokenKind::LArrow + | TokenKind::FatArrow + | TokenKind::Pound + | TokenKind::Dollar + | TokenKind::Question + | TokenKind::SingleQuote + | TokenKind::OpenParen + | TokenKind::CloseParen + | TokenKind::OpenBrace + | TokenKind::CloseBrace + | TokenKind::OpenBracket + | TokenKind::CloseBracket => "PUNCTUATION", + TokenKind::OpenInvisible(_) | TokenKind::CloseInvisible(_) => { + panic!("unexpected invisible token") + } + TokenKind::Literal(lit) => match lit.kind { + rustc_ast::token::LitKind::Bool => "IDENTIFIER_OR_KEYWORD", + rustc_ast::token::LitKind::Byte => "BYTE_LITERAL", + rustc_ast::token::LitKind::Char => "CHAR_LITERAL", + rustc_ast::token::LitKind::Integer => "INTEGER_LITERAL", + rustc_ast::token::LitKind::Float => "FLOAT_LITERAL", + rustc_ast::token::LitKind::Str => "STRING_LITERAL", + rustc_ast::token::LitKind::StrRaw(_) => "RAW_STRING_LITERAL", + rustc_ast::token::LitKind::ByteStr => "BYTE_STRING_LITERAL", + rustc_ast::token::LitKind::ByteStrRaw(_) => "RAW_BYTE_STRING_LITERAL", + rustc_ast::token::LitKind::CStr => "C_STRING_LITERAL", + rustc_ast::token::LitKind::CStrRaw(_) => "RAW_C_STRING_LITERAL", + // Diagnostics handle this below. + rustc_ast::token::LitKind::Err(_) => "Literal Error", + }, + TokenKind::Ident(_, IdentIsRaw::No) => "IDENTIFIER_OR_KEYWORD", + TokenKind::Ident(_, IdentIsRaw::Yes) => "RAW_IDENTIFIER", + TokenKind::NtIdent(..) => panic!("unexpected NtIdent"), + TokenKind::Lifetime(..) => "LIFETIME_TOKEN", + TokenKind::NtLifetime(..) => panic!("unexpected NtLifetime"), + TokenKind::DocComment(CommentKind::Line, AttrStyle::Inner, ..) => "INNER_LINE_DOC", + TokenKind::DocComment(CommentKind::Line, AttrStyle::Outer, ..) => "OUTER_LINE_DOC", + TokenKind::DocComment(CommentKind::Block, AttrStyle::Inner, ..) => "INNER_BLOCK_DOC", + TokenKind::DocComment(CommentKind::Block, AttrStyle::Outer, ..) => "OUTER_BLOCK_DOC", + TokenKind::Eof => panic!("unexpected EOF"), + } + .to_string() +} + +fn diagnostics(output: &[u8]) -> Vec<Diagnostic> { + let json = std::str::from_utf8(output).unwrap(); + json.lines() + .map(|line| serde_json::from_str(line).unwrap()) + .collect() +} + +#[derive(serde::Deserialize)] +struct Diagnostic { + rendered: String, + level: String, + spans: Vec<DiagSpan>, +} + +#[derive(serde::Deserialize)] +struct DiagSpan { + is_primary: bool, + byte_start: u32, +} + +pub fn normalize(tokens: &[Node]) -> Result<Vec<Node>, ParseError> { + let new_ts = tokens + .iter() + // rustc_parse does not retain comments. + .filter(|token| !matches!(token.name.as_str(), "LINE_COMMENT" | "BLOCK_COMMENT")) + .cloned() + .collect(); + Ok(new_ts) +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc_lexer.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc_lexer.rs new file mode 100644 index 00000000..16aad33b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar-check/src/tools/rustc_lexer.rs @@ -0,0 +1,30 @@ +//! The `rustc_lexer`-based tool. +//! +//! This is generally not useful, but is used for internal investigation. The +//! `rustc_parse` module does a lot of translations to the lower-level +//! `rustc_lexer`. The Reference is based on the tokens as used and seen by +//! macros, and those are not the same as the ones as generated by +//! `rustc_lexer`. + +extern crate rustc_lexer; + +use parser::{Node, ParseError}; +use rustc_lexer::{FrontmatterAllowed, TokenKind}; +use std::ops::Range; + +pub fn tokenize(src: &str) -> Result<Vec<Node>, ParseError> { + let mut pos = 0; + let ts: Vec<_> = rustc_lexer::tokenize(src, FrontmatterAllowed::Yes) + .filter_map(|token| { + let start = pos; + let end = pos + token.len as usize; + pos += token.len as usize; + if matches!(token.kind, TokenKind::Whitespace) { + return None; + } + let t = Node::new(format!("{:?}", token.kind), Range { start, end }); + Some(t) + }) + .collect(); + Ok(ts) +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/Cargo.toml new file mode 100644 index 00000000..87d93f5c --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "grammar" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +diagnostics = { path = "../diagnostics" } +pathdiff = "0.2.3" +regex = "1.12.2" +walkdir = "2.5.0" diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/README.md b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/README.md new file mode 100644 index 00000000..960b4f96 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/README.md @@ -0,0 +1,3 @@ +# Grammar parser + +This is a library that provides a parser for the grammar rules in the Reference. diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/display.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/display.rs new file mode 100644 index 00000000..f2319491 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/display.rs @@ -0,0 +1,67 @@ +use super::{Expression, ExpressionKind}; +use std::fmt::{Display, Formatter}; + +impl Display for Expression { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { + match &self.kind { + ExpressionKind::Grouped(e) => write!(f, "({e})")?, + ExpressionKind::Alt(es) => { + for (i, e) in es.iter().enumerate() { + if i > 0 { + write!(f, " | ")?; + } + write!(f, "{e}")?; + } + } + ExpressionKind::Sequence(es) => { + for (i, e) in es.iter().enumerate() { + if i > 0 { + write!(f, " ")?; + } + write!(f, "{e}")?; + } + } + ExpressionKind::Optional(e) => write!(f, "{e}?")?, + ExpressionKind::NegativeLookahead(e) => write!(f, "!{e}")?, + ExpressionKind::Repeat(e) => write!(f, "{e}*")?, + ExpressionKind::RepeatPlus(e) => write!(f, "{e}+")?, + ExpressionKind::RepeatRange { + expr, + name, + min, + max, + limit, + } => write!( + f, + "{expr}{{{}{}{limit}{}}}", + name.as_ref().map(|n| format!("{n}:")).unwrap_or_default(), + min.map(|v| v.to_string()).unwrap_or_default(), + max.map(|v| v.to_string()).unwrap_or_default(), + )?, + ExpressionKind::RepeatRangeNamed(e, name) => write!(f, "{e}{{{name}}}")?, + ExpressionKind::Nt(s) => write!(f, "{s}")?, + ExpressionKind::Terminal(s) => write!(f, "`{s}`")?, + ExpressionKind::Prose(s) => write!(f, "<{s}>")?, + ExpressionKind::Break(_) => write!(f, " ")?, + ExpressionKind::Comment(_) => {} + ExpressionKind::Charset(es) => { + write!(f, "[")?; + for (i, e) in es.iter().enumerate() { + if i > 0 { + write!(f, " ")?; + } + write!(f, "{e}")?; + } + write!(f, "]")?; + } + ExpressionKind::CharacterRange(start, end) => write!(f, "{start}-{end}")?, + ExpressionKind::NegExpression(e) => write!(f, "~{e}")?, + ExpressionKind::Cut(e) => write!(f, "^ {e}")?, + ExpressionKind::Unicode((_, s)) => write!(f, "U+{s}")?, + } + if let Some(suffix) = &self.suffix { + write!(f, " _{suffix}_")?; + } + Ok(()) + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/frontmatter.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/frontmatter.rs new file mode 100644 index 00000000..36fe5b46 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/frontmatter.rs @@ -0,0 +1,55 @@ +//! This is a temporary hack to include the frontmatter grammar until it is +//! stabilized. +//! +//! This should be removed once FRONTMATTER is added to the Reference. + +use crate::{Grammar, parser}; +use diagnostics::Diagnostics; +use std::path::Path; + +pub fn load_grammar_with_frontmatter(diag: &mut Diagnostics) -> Grammar { + let mut grammar = super::load_grammar(diag); + + parser::parse_grammar(FRONTMATTER, &mut grammar, "lexer", Path::new("")).unwrap(); + + grammar +} + +static FRONTMATTER: &str = "⊥ -> CHAR* CHAR + +error -> ^ ⊥ // Should be a hard error. + +@root FRONTMATTER -> + WHITESPACE_ONLY_LINE* + !FRONTMATTER_INVALID + FRONTMATTER_MAIN + +WHITESPACE_ONLY_LINE -> (!LF WHITESPACE)* LF + +FRONTMATTER_INVALID -> (!LF WHITESPACE)+ `---` error + +FRONTMATTER_MAIN -> + `-`{n:3..=255} ^ FRONTMATTER_REST + +FRONTMATTER_REST -> + FRONTMATTER_FENCE_START + FRONTMATTER_LINE* + FRONTMATTER_FENCE_END + +FRONTMATTER_FENCE_START -> + MAYBE_INFOSTRING_OR_WS LF + +FRONTMATTER_FENCE_END -> + `-`{n} HORIZONTAL_WHITESPACE* ( LF | EOF ) + +FRONTMATTER_LINE -> !`-`{n} ~[LF CR]* LF + +MAYBE_INFOSTRING_OR_WS -> + HORIZONTAL_WHITESPACE* INFOSTRING? HORIZONTAL_WHITESPACE* + +INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* + +HORIZONTAL_WHITESPACE -> + U+0009 // Horizontal tab, `'\t'` + | U+0020 // Space, `' '` +"; diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/lib.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/lib.rs new file mode 100644 index 00000000..82abd128 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/lib.rs @@ -0,0 +1,355 @@ +//! Support for loading the grammar. + +use diagnostics::{Diagnostics, warn_or_err}; +use regex::Regex; +use std::collections::{HashMap, HashSet}; +use std::fmt::{Display, Formatter}; +use std::path::{Path, PathBuf}; +use std::sync::LazyLock; +use walkdir::WalkDir; + +mod display; +mod frontmatter; +mod parser; + +pub use frontmatter::load_grammar_with_frontmatter; + +#[derive(Debug, Default)] +pub struct Grammar { + pub productions: HashMap<String, Production>, + /// The order that the production names were discovered. + pub name_order: Vec<String>, + /// Counter for generating unique expression IDs. + pub next_id: u32, +} + +#[derive(Debug)] +pub struct Production { + pub name: String, + /// Comments and breaks that precede the production name. + pub comments: Vec<Expression>, + /// Category is from the markdown lang string, and defines how it is + /// grouped and organized on the summary page. + pub category: String, + pub expression: Expression, + /// The path to the chapter where this is defined, relative to the book's + /// `src` directory. + pub path: PathBuf, + pub is_root: bool, +} + +#[derive(Clone, Debug)] +pub struct Expression { + pub kind: ExpressionKind, + /// Suffix is the `_foo_` part that is shown as a subscript. + pub suffix: Option<String>, + /// A footnote is a markdown footnote link. + pub footnote: Option<String>, + /// Unique ID of the expression. + pub id: u32, +} + +#[derive(Clone, Debug)] +pub enum ExpressionKind { + /// `( A B C )` + Grouped(Box<Expression>), + /// `A | B | C` + Alt(Vec<Expression>), + /// `A B C` + Sequence(Vec<Expression>), + /// `A?` + Optional(Box<Expression>), + /// `!A` + NegativeLookahead(Box<Expression>), + /// `A*` + Repeat(Box<Expression>), + /// `A+` + RepeatPlus(Box<Expression>), + /// `A{2..4}` or `A{2..=4}` or `A{name:2..=4}` + RepeatRange { + expr: Box<Expression>, + name: Option<String>, + min: Option<u32>, + max: Option<u32>, + limit: RangeLimit, + }, + /// `A{name}` + RepeatRangeNamed(Box<Expression>, String), + /// `NonTerminal` + Nt(String), + /// `` `string` `` + Terminal(String), + /// `<english description>` + Prose(String), + /// An LF followed by the given number of spaces. + /// + /// Used by the renderer to help format and structure the grammar. + Break(usize), + /// `// Single line comment.` + Comment(String), + /// ``[`A`-`Z` `_` LF]`` + /// + /// This should only contain expressions that are valid inside brackets + /// (`Terminal`, `Nt`, and `CharacterRange`). + Charset(Vec<Expression>), + /// `` `A`-`Z` `` used in a character set. + /// + /// This should only appear inside a `Charset`. + CharacterRange(Character, Character), + /// ``~[` ` LF]`` + NegExpression(Box<Expression>), + /// `^ A B C` + Cut(Box<Expression>), + /// `U+0060` + /// + /// The `String` is the hex digits after `U+`. + Unicode((char, String)), +} + +#[derive(Copy, Clone, Debug)] +pub enum RangeLimit { + /// `..` + HalfOpen, + /// `..=` + Closed, +} + +impl Display for RangeLimit { + fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { + match self { + RangeLimit::HalfOpen => "..", + RangeLimit::Closed => "..=", + } + .fmt(f) + } +} + +#[derive(Clone, Debug)] +pub enum Character { + Char(char), + /// `U+0060` + /// + /// The `String` is the hex digits after `U+`. + Unicode((char, String)), +} + +impl Character { + pub fn get_ch(&self) -> char { + match self { + Character::Char(ch) => *ch, + Character::Unicode((ch, _)) => *ch, + } + } +} + +impl Display for Character { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { + match self { + Character::Char(ch) => write!(f, "`{ch}`"), + Character::Unicode((_, s)) => write!(f, "U+{s}"), + } + } +} + +impl Grammar { + pub fn grammar_from_str(input: &str, category: &str) -> Result<Grammar, parser::Error> { + let mut grammar = Grammar::default(); + parser::parse_grammar(input, &mut grammar, category, Path::new(""))?; + Ok(grammar) + } + + /// Generates a new unique expression ID. + pub fn next_id(&mut self) -> u32 { + let id = self.next_id; + self.next_id += 1; + id + } + + fn visit_nt(&self, callback: &mut dyn FnMut(&str)) { + for p in self.productions.values() { + p.expression.visit_nt(callback); + } + } +} + +impl Expression { + pub fn new_kind(kind: ExpressionKind, id: u32) -> Self { + Self { + kind, + suffix: None, + footnote: None, + id, + } + } + + fn visit_nt(&self, callback: &mut dyn FnMut(&str)) { + match &self.kind { + ExpressionKind::Grouped(e) + | ExpressionKind::Optional(e) + | ExpressionKind::NegativeLookahead(e) + | ExpressionKind::Repeat(e) + | ExpressionKind::RepeatPlus(e) + | ExpressionKind::RepeatRange { expr: e, .. } + | ExpressionKind::RepeatRangeNamed(e, _) + | ExpressionKind::NegExpression(e) + | ExpressionKind::Cut(e) => { + e.visit_nt(callback); + } + ExpressionKind::Alt(es) + | ExpressionKind::Sequence(es) + | ExpressionKind::Charset(es) => { + for e in es { + e.visit_nt(callback); + } + } + + ExpressionKind::Nt(nt) => { + callback(nt); + } + ExpressionKind::Terminal(_) + | ExpressionKind::Prose(_) + | ExpressionKind::Break(_) + | ExpressionKind::Comment(_) + | ExpressionKind::Unicode(_) + | ExpressionKind::CharacterRange(..) => {} + } + } + + pub fn is_break(&self) -> bool { + self.kind.is_break() + } + + /// Returns the last [`ExpressionKind`] of this expression. + pub fn last_expr(&self) -> &ExpressionKind { + match &self.kind { + ExpressionKind::Alt(es) | ExpressionKind::Sequence(es) => { + es.last().unwrap().last_expr() + } + ExpressionKind::Cut(e) => e.last_expr(), + ExpressionKind::Grouped(_) + | ExpressionKind::Optional(_) + | ExpressionKind::NegativeLookahead(_) + | ExpressionKind::Repeat(_) + | ExpressionKind::RepeatPlus(_) + | ExpressionKind::RepeatRange { .. } + | ExpressionKind::RepeatRangeNamed(_, _) + | ExpressionKind::Nt(_) + | ExpressionKind::Terminal(_) + | ExpressionKind::Prose(_) + | ExpressionKind::Break(_) + | ExpressionKind::Comment(_) + | ExpressionKind::Charset(_) + | ExpressionKind::CharacterRange(_, _) + | ExpressionKind::NegExpression(_) + | ExpressionKind::Unicode(_) => &self.kind, + } + } +} + +impl ExpressionKind { + pub fn is_break(&self) -> bool { + matches!(self, ExpressionKind::Break(_)) + } +} + +pub static GRAMMAR_RE: LazyLock<Regex> = + LazyLock::new(|| Regex::new(r"(?ms)^```grammar,([^\n]+)\n(.*?)^```").unwrap()); + +/// Loads the [`Grammar`] from the book. +pub fn load_grammar(diag: &mut Diagnostics) -> Grammar { + let mut grammar = Grammar::default(); + let base = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../src"); + for entry in WalkDir::new(&base).sort_by_file_name() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.extension().and_then(|s| s.to_str()) != Some("md") { + continue; + } + let content = std::fs::read_to_string(path).unwrap(); + let relative_path = pathdiff::diff_paths(path, &base).expect("one path must be absolute"); + for cap in GRAMMAR_RE.captures_iter(&content) { + let category = &cap[1]; + let input = &cap[2]; + if let Err(e) = parser::parse_grammar(input, &mut grammar, category, &relative_path) { + warn_or_err!(diag, "failed to parse grammar in {path:?}: {e}"); + } + } + } + + check_undefined_nt(&grammar, diag); + check_unexpected_roots(&grammar, diag); + grammar +} + +/// Checks for nonterminals that are used but not defined. +fn check_undefined_nt(grammar: &Grammar, diag: &mut Diagnostics) { + grammar.visit_nt(&mut |nt| { + if !grammar.productions.contains_key(nt) { + warn_or_err!(diag, "non-terminal `{nt}` is used but not defined"); + } + }); +} + +/// This checks that all the grammar roots are what we expect. +/// +/// This is intended to help catch any unexpected misspellings, orphaned +/// productions, or general mistakes. +fn check_unexpected_roots(grammar: &Grammar, diag: &mut Diagnostics) { + // `set` starts with every production name. + let mut set: HashSet<_> = grammar.name_order.iter().map(|s| s.as_str()).collect(); + fn remove(set: &mut HashSet<&str>, grammar: &Grammar, prod: &Production, root_name: &str) { + prod.expression.visit_nt(&mut |nt| { + // Leave the root name in the set if we find it recursively. + if nt == root_name { + return; + } + if !set.remove(nt) { + return; + } + if let Some(nt_prod) = grammar.productions.get(nt) { + remove(set, grammar, nt_prod, root_name); + } + }); + } + // Walk the productions starting from the root nodes, and remove every + // non-terminal from `set`. What's left must be the set of roots. + grammar + .productions + .values() + .filter(|prod| prod.is_root) + .for_each(|root| { + remove(&mut set, grammar, root, &root.name); + }); + let expected: HashSet<_> = grammar + .productions + .values() + .filter(|&p| p.is_root) + .map(|p| p.name.as_str()) + .collect(); + if set != expected { + let new: Vec<_> = set.difference(&expected).collect(); + let removed: Vec<_> = expected.difference(&set).collect(); + if !new.is_empty() { + warn_or_err!( + diag, + "New grammar production detected that is not used in any root-accessible\n\ + production. If this is expected, mark the production with\n\ + `@root`. If not, make sure it is spelled correctly and used in\n\ + another root-accessible production.\n\ + \n\ + The new names are: {new:?}\n" + ); + } else if !removed.is_empty() { + warn_or_err!( + diag, + "Old grammar production root seems to have been removed\n\ + (it is used in some other production that is root-accessible).\n\ + If this is expected, remove `@root` from the production.\n\ + \n\ + The removed names are: {removed:?}\n" + ); + } else { + unreachable!("unexpected"); + } + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/parser.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/parser.rs new file mode 100644 index 00000000..d7a2ccdd --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/grammar/src/parser.rs @@ -0,0 +1,1333 @@ +//! A parser of the ENBF-like grammar. + +use super::{Character, Expression, ExpressionKind, Grammar, Production, RangeLimit}; +use std::fmt; +use std::fmt::Display; +use std::path::Path; + +struct Parser<'a> { + input: &'a str, + index: usize, + grammar: &'a mut Grammar, +} + +#[derive(Debug)] +pub struct Error { + message: String, + line: String, + lineno: usize, + col: usize, +} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { + let lineno = format!("{}", self.lineno); + let space = " ".repeat(lineno.len() + 1); + let col = " ".repeat(self.col); + let line = &self.line; + let message = &self.message; + write!(f, "\n{space}|\n{lineno} | {line}\n{space}|{col}^ {message}") + } +} + +macro_rules! bail { + ($parser:expr, $($arg:tt)*) => {{ + let mut msg = String::new(); + fmt::write(&mut msg, format_args!($($arg)*)).unwrap(); + return Err($parser.error(msg)); + }}; +} + +type Result<T> = std::result::Result<T, Error>; + +/// Whether a character can start a grammar rule name. +/// +/// This includes ASCII alphabetic characters, underscores, and +/// non-ASCII Unicode symbols such as `⊥` (bottom) and `⊤` (top). +/// ASCII symbols are excluded because characters such as `+`, `|`, +/// `~`, and `^` are grammar syntax. +fn is_name_start(ch: char) -> bool { + ch.is_alphabetic() || ch == '_' || !ch.is_ascii() +} + +/// Whether a character can continue a grammar rule name. +/// +/// Accepts alphanumeric characters, underscores, and non-ASCII +/// characters. +fn is_name_continue(ch: char) -> bool { + ch.is_alphanumeric() || ch == '_' || !ch.is_ascii() +} + +pub fn parse_grammar( + input: &str, + grammar: &mut Grammar, + category: &str, + path: &Path, +) -> Result<()> { + let mut parser = Parser { + input, + index: 0, + grammar, + }; + loop { + let p = parser.parse_production(category, path)?; + parser.grammar.name_order.push(p.name.clone()); + if let Some(dupe) = parser.grammar.productions.insert(p.name.clone(), p) { + bail!(parser, "duplicate production {} in grammar", dupe.name); + } + parser.take_while(&|ch| ch == '\n'); + if parser.eof() { + break; + } + } + Ok(()) +} + +impl Parser<'_> { + /// Helper to create a new expression with a unique ID. + fn new_expr(&mut self, kind: ExpressionKind) -> Expression { + let id = self.grammar.next_id(); + Expression::new_kind(kind, id) + } + + fn take_while(&mut self, f: &dyn Fn(char) -> bool) -> &str { + let mut upper = 0; + let i = self.index; + for ch in self.input[i..].chars() { + if !f(ch) { + break; + } + upper += ch.len_utf8(); + } + self.index += upper; + &self.input[i..i + upper] + } + + /// Returns whether or not the given string is next, and advances the head if it is. + fn take_str(&mut self, s: &str) -> bool { + if self.input[self.index..].starts_with(s) { + self.index += s.len(); + true + } else { + false + } + } + + /// Returns the next byte, or None if eof. + fn peek(&mut self) -> Option<u8> { + if self.index >= self.input.len() { + None + } else { + Some(self.input.as_bytes()[self.index]) + } + } + + fn eof(&mut self) -> bool { + self.index >= self.input.len() + } + + /// Expects the next input to be the given string, and advances the head. + fn expect(&mut self, s: &str, err: &str) -> Result<()> { + if !self.input[self.index..].starts_with(s) { + bail!(self, "{err}"); + }; + self.index += s.len(); + Ok(()) + } + + fn error(&mut self, message: String) -> Error { + let (line, lineno, col) = translate_position(self.input, self.index); + Error { + message, + line: line.to_string(), + lineno, + col, + } + } + + /// Advances zero or more spaces. + fn space0(&mut self) -> &str { + self.take_while(&|ch| ch == ' ') + } + + fn parse_production(&mut self, category: &str, path: &Path) -> Result<Production> { + let mut comments = Vec::new(); + while let Ok(comment) = self.parse_comment() { + self.expect("\n", "expected newline")?; + comments.push(self.new_expr(comment)); + comments.push(self.new_expr(ExpressionKind::Break(0))); + } + let is_root = self.parse_is_root(); + self.space0(); + let name = self + .parse_name() + .ok_or_else(|| self.error("expected production name".to_string()))?; + self.expect(" ->", "expected -> arrow")?; + let Some(expression) = self.parse_expression()? else { + bail!(self, "expected an expression"); + }; + Ok(Production { + name, + comments, + category: category.to_string(), + expression, + path: path.to_owned(), + is_root, + }) + } + + fn parse_is_root(&mut self) -> bool { + self.take_str("@root") + } + + fn parse_name(&mut self) -> Option<String> { + let first = self.input[self.index..].chars().next()?; + if !is_name_start(first) { + return None; + } + Some(self.take_while(&|c| is_name_continue(c)).to_string()) + } + + fn parse_expression(&mut self) -> Result<Option<Expression>> { + let mut es = Vec::new(); + while let Some(e) = self.parse_seq()? { + es.push(e); + _ = self.space0(); + if !self.take_str("|") { + break; + } + } + match es.len() { + 0 => Ok(None), + 1 => Ok(Some(es.pop().unwrap())), + _ => Ok(Some(self.new_expr(ExpressionKind::Alt(es)))), + } + } + + fn parse_seq(&mut self) -> Result<Option<Expression>> { + let mut es = Vec::new(); + loop { + self.space0(); + if self.peek() == Some(b'^') { + let cut = self.parse_cut()?; + es.push(cut); + break; + } + let Some(e) = self.parse_expr1()? else { + break; + }; + es.push(e); + } + match es.len() { + 0 => Ok(None), + 1 => Ok(Some(es.pop().unwrap())), + _ => Ok(Some(self.new_expr(ExpressionKind::Sequence(es)))), + } + } + + /// Parse cut (`^`) operator. + fn parse_cut(&mut self) -> Result<Expression> { + self.expect("^", "expected `^`")?; + let Some(rhs) = self.parse_seq()? else { + bail!(self, "expected expression after cut operator"); + }; + Ok(self.new_expr(ExpressionKind::Cut(Box::new(rhs)))) + } + + fn parse_expr1(&mut self) -> Result<Option<Expression>> { + let Some(next) = self.peek() else { + return Ok(None); + }; + + let kind = if self.take_str("U+") { + ExpressionKind::Unicode(self.parse_unicode()?) + } else if self.input[self.index..] + .chars() + .next() + .map(|ch| is_name_start(ch)) + .unwrap_or(false) + { + self.parse_nonterminal() + .expect("first char already checked") + } else if self.take_str("\n") { + if self.eof() || self.take_str("\n") { + return Ok(None); + } + let space = self.take_while(&|ch| ch == ' '); + if space.len() == 0 { + bail!(self, "expected indentation on next line"); + } + ExpressionKind::Break(space.len()) + } else if next == b'/' { + self.parse_comment()? + } else if next == b'`' { + self.parse_terminal()? + } else if next == b'[' { + self.parse_charset()? + } else if next == b'<' { + self.parse_prose()? + } else if next == b'(' { + self.parse_grouped()? + } else if next == b'~' { + self.parse_neg_expression()? + } else if next == b'!' { + self.parse_negative_lookahead()? + } else { + return Ok(None); + }; + let kind = match self.peek() { + Some(b'?') => self.parse_optional(kind)?, + Some(b'*') => self.parse_repeat(kind)?, + Some(b'+') => self.parse_repeat_plus(kind)?, + Some(b'{') => self.parse_repeat_range(kind)?, + _ => kind, + }; + let suffix = self.parse_suffix()?; + let footnote = self.parse_footnote()?; + + let mut expr = self.new_expr(kind); + expr.suffix = suffix; + expr.footnote = footnote; + Ok(Some(expr)) + } + + fn parse_nonterminal(&mut self) -> Option<ExpressionKind> { + let nt = self.parse_name()?; + Some(ExpressionKind::Nt(nt)) + } + + /// Parse terminal within backticks. + fn parse_terminal(&mut self) -> Result<ExpressionKind> { + Ok(ExpressionKind::Terminal(self.parse_terminal_str()?)) + } + + /// Parse string within backticks. + fn parse_terminal_str(&mut self) -> Result<String> { + self.expect("`", "expected opening backtick")?; + let term = self.take_while(&|x| !['\n', '`'].contains(&x)).to_string(); + if term.is_empty() { + bail!(self, "expected terminal"); + } + self.expect("`", "expected closing backtick")?; + Ok(term) + } + + /// Parse e.g. `// Single line comment.`. + fn parse_comment(&mut self) -> Result<ExpressionKind> { + self.expect("//", "expected `//`")?; + let text = self.take_while(&|x| x != '\n').to_string(); + Ok(ExpressionKind::Comment(text)) + } + + fn parse_charset(&mut self) -> Result<ExpressionKind> { + self.expect("[", "expected opening [")?; + let mut characters = Vec::new(); + loop { + self.space0(); + let Some(ch) = self.parse_characters()? else { + break; + }; + characters.push(self.new_expr(ch)); + } + if characters.is_empty() { + bail!(self, "expected at least one character in character group"); + } + self.space0(); + self.expect("]", "expected closing ]")?; + Ok(ExpressionKind::Charset(characters)) + } + + /// Parse an element of a character class, e.g. + /// `` `a`-`b` `` | `` `term` `` | `` NonTerminal ``. + fn parse_characters(&mut self) -> Result<Option<ExpressionKind>> { + if let Some(a) = self.parse_character()? { + if self.take_str("-") { + let Some(b) = self.parse_character()? else { + bail!(self, "expected character in range"); + }; + Ok(Some(ExpressionKind::CharacterRange(a, b))) + } else { + //~^ Parse terminal in backticks. + let t = match a { + Character::Char(ch) => ch.to_string(), + Character::Unicode(_) => bail!(self, "unicode not supported"), + }; + Ok(Some(ExpressionKind::Terminal(t))) + } + } else if let Some(name) = self.parse_name() { + //~^ Parse nonterminal identifier. + Ok(Some(ExpressionKind::Nt(name))) + } else { + Ok(None) + } + } + + fn parse_character(&mut self) -> Result<Option<Character>> { + if let Some(b'`') = self.peek() { + let recov = self.index; + let term = self.parse_terminal_str()?; + if term.len() > 1 { + self.index = recov + 1; + bail!(self, "invalid start terminal in range"); + } + let ch = term.chars().next().unwrap(); + Ok(Some(Character::Char(ch))) + } else if self.take_str("U+") { + Ok(Some(Character::Unicode(self.parse_unicode()?))) + } else { + Ok(None) + } + } + + /// Parse e.g. `<prose text>`. + fn parse_prose(&mut self) -> Result<ExpressionKind> { + self.expect("<", "expected opening `<`")?; + let text = self.take_while(&|x| !['\n', '>'].contains(&x)).to_string(); + if text.is_empty() { + bail!(self, "expected prose text"); + } + self.expect(">", "expected closing `>`")?; + Ok(ExpressionKind::Prose(text)) + } + + fn parse_grouped(&mut self) -> Result<ExpressionKind> { + self.expect("(", "expected opening `(`")?; + self.space0(); + let Some(e) = self.parse_expression()? else { + bail!(self, "expected expression in parenthesized group"); + }; + self.space0(); + self.expect(")", "expected closing `)`")?; + Ok(ExpressionKind::Grouped(Box::new(e))) + } + + fn parse_neg_expression(&mut self) -> Result<ExpressionKind> { + self.expect("~", "expected ~")?; + let Some(next) = self.peek() else { + bail!(self, "expected expression after ~"); + }; + let kind = match next { + b'[' => self.parse_charset()?, + b'`' => self.parse_terminal()?, + _ => self.parse_nonterminal().ok_or_else(|| { + self.error("expected a charset, terminal, or name after ~ negation".to_string()) + })?, + }; + let inner_expr = self.new_expr(kind); + Ok(ExpressionKind::NegExpression(Box::new(inner_expr))) + } + + fn parse_negative_lookahead(&mut self) -> Result<ExpressionKind> { + self.expect("!", "expected !")?; + self.space0(); + let Some(e) = self.parse_expr1()? else { + bail!(self, "expected expression after !"); + }; + Ok(ExpressionKind::NegativeLookahead(Box::new(e))) + } + + /// Parse e.g. `F00F` after `U+`. + fn parse_unicode(&mut self) -> Result<(char, String)> { + let mut xs = Vec::with_capacity(6); + let mut push_next = || { + match self.peek() { + Some(x @ (b'0'..=b'9' | b'A'..=b'F')) => { + xs.push(x); + self.index += 1; + } + _ => bail!(self, "expected 4 uppercase hexadecimal digits after `U+`"), + } + Ok(()) + }; + for _ in 0..4 { + push_next()?; + } + for _ in 0..2 { + if push_next().is_err() { + break; + } + } + let s = String::from_utf8(xs).unwrap(); + let ch = char::from_u32(u32::from_str_radix(&s, 16).unwrap()).unwrap(); + Ok((ch, s)) + } + + /// Parse `?` after expression. + fn parse_optional(&mut self, kind: ExpressionKind) -> Result<ExpressionKind> { + self.expect("?", "expected `?`")?; + let inner_expr = self.new_expr(kind); + Ok(ExpressionKind::Optional(Box::new(inner_expr))) + } + + /// Parse `*` after expression. + fn parse_repeat(&mut self, kind: ExpressionKind) -> Result<ExpressionKind> { + self.expect("*", "expected `*`")?; + let inner_expr = self.new_expr(kind); + Ok(ExpressionKind::Repeat(Box::new(inner_expr))) + } + + /// Parse `+` after expression. + fn parse_repeat_plus(&mut self, kind: ExpressionKind) -> Result<ExpressionKind> { + self.expect("+", "expected `+`")?; + let inner_expr = self.new_expr(kind); + Ok(ExpressionKind::RepeatPlus(Box::new(inner_expr))) + } + + /// Parse `{a..b}` | `{a..=b}` | `{name:a..=b}` | `{name}` after expression. + // + // `name:` before the range is a named binding. `{name}` refers to that binding. + fn parse_repeat_range(&mut self, kind: ExpressionKind) -> Result<ExpressionKind> { + self.expect("{", "expected `{`")?; + let start = self.index; + let name = match (self.parse_name(), self.peek()) { + (Some(name), Some(b':')) => { + self.index += 1; + Some(name) + } + (Some(name), Some(b'}')) => { + self.index += 1; + let inner_expr = self.new_expr(kind); + return Ok(ExpressionKind::RepeatRangeNamed(Box::new(inner_expr), name)); + } + _ => { + self.index = start; + None + } + }; + let min = self.take_while(&|x| x.is_ascii_digit()); + let Ok(min) = (!min.is_empty()).then(|| min.parse::<u32>()).transpose() else { + bail!(self, "malformed range start"); + }; + self.expect("..", "expected `..` or `..=`")?; + let limit = if self.take_str("=") { + RangeLimit::Closed + } else { + RangeLimit::HalfOpen + }; + let max = self.take_while(&|x| x.is_ascii_digit()); + let Ok(max) = (!max.is_empty()).then(|| max.parse::<u32>()).transpose() else { + bail!(self, "malformed range end"); + }; + match (min, max, limit) { + (Some(min), Some(max), _) if max < min => { + bail!(self, "range {min}{limit}{max} is malformed") + } + (Some(min), Some(max), RangeLimit::HalfOpen) if max <= min => { + bail!(self, "half-open range maximum must be greater than minimum") + } + (None, Some(0), RangeLimit::HalfOpen) => { + bail!(self, "half-open range `..0` is empty") + } + (_, None, RangeLimit::Closed) => bail!(self, "closed range must have an upper bound"), + _ => {} + } + self.expect("}", "expected `}`")?; + let inner_expr = self.new_expr(kind); + Ok(ExpressionKind::RepeatRange { + expr: Box::new(inner_expr), + name, + min, + max, + limit, + }) + } + + fn parse_suffix(&mut self) -> Result<Option<String>> { + if !self.take_str(" _") { + return Ok(None); + } + let mut in_backtick = false; + let start = self.index; + loop { + let Some(next) = self.peek() else { + bail!(self, "failed to find end of _ suffixed text"); + }; + self.index += 1; + match next { + b'\n' => bail!(self, "failed to find end of _ suffixed text"), + b'`' => in_backtick = !in_backtick, + b'_' if !in_backtick => { + if self + .peek() + .map(|b| matches!(b, b'\n' | b' ')) + .unwrap_or(true) + { + break; + } + } + _ => {} + } + } + Ok(Some(self.input[start..self.index - 1].to_string())) + } + + /// Parse footnote reference, e.g. `[^id]`. + fn parse_footnote(&mut self) -> Result<Option<String>> { + if !self.take_str("[^") { + return Ok(None); + } + let id = self.take_while(&|x| !['\n', ']'].contains(&x)).to_string(); + if id.is_empty() { + bail!(self, "expected footnote id"); + } + self.expect("]", "expected closing `]`")?; + Ok(Some(id)) + } +} + +/// Helper to translate a byte index to a `(line, line_no, col_no)` (1-based). +fn translate_position(input: &str, index: usize) -> (&str, usize, usize) { + if input.is_empty() { + return ("", 0, 0); + } + let index = index.min(input.len()); + + let mut line_start = 0; + let mut line_number = 0; + for line in input.lines() { + let line_end = line_start + line.len(); + if index >= line_start && index <= line_end { + let column_number = index - line_start + 1; + return (line, line_number + 1, column_number); + } + line_start = line_end + 1; + line_number += 1; + } + ("", line_number + 1, 0) +} + +#[cfg(test)] +mod tests { + use crate::parser::{parse_grammar, translate_position}; + use crate::{Character, ExpressionKind, Grammar, RangeLimit}; + use std::path::Path; + + #[test] + fn test_translate() { + assert_eq!(translate_position("", 0), ("", 0, 0)); + assert_eq!(translate_position("test", 0), ("test", 1, 1)); + assert_eq!(translate_position("test", 3), ("test", 1, 4)); + assert_eq!(translate_position("test", 4), ("test", 1, 5)); + assert_eq!(translate_position("test\ntest2", 4), ("test", 1, 5)); + assert_eq!(translate_position("test\ntest2", 5), ("test2", 2, 1)); + assert_eq!(translate_position("test\ntest2\n", 11), ("", 3, 0)); + } + + fn parse(input: &str) -> Result<Grammar, String> { + let mut grammar = Grammar::default(); + parse_grammar(input, &mut grammar, "test", Path::new("test.md")) + .map_err(|e| e.to_string())?; + Ok(grammar) + } + + #[test] + fn test_cut() { + let input = "Rule -> A ^ B | C"; + let grammar = parse(input).unwrap(); + grammar.productions.get("Rule").unwrap(); + } + + #[test] + fn test_cut_captures() { + let input = "Rule -> A ^ B C | D"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + // The top-level expression is an alternation: (A ^ B C) | D. + let ExpressionKind::Alt(alts) = &rule.expression.kind else { + panic!("expected Alt, got {:?}", rule.expression.kind); + }; + assert_eq!(alts.len(), 2); + // First alternative is a sequence: A, Cut(Sequence(B, C)). + let ExpressionKind::Sequence(seq) = &alts[0].kind else { + panic!("expected Sequence, got {:?}", alts[0].kind); + }; + assert_eq!(seq.len(), 2); + assert!(matches!(&seq[0].kind, ExpressionKind::Nt(n) if n == "A")); + // The cut captures the rest of the sequence (B and C). + let ExpressionKind::Cut(cut_inner) = &seq[1].kind else { + panic!("expected Cut, got {:?}", seq[1].kind); + }; + let ExpressionKind::Sequence(cut_seq) = &cut_inner.kind else { + panic!("expected Sequence inside Cut, got {:?}", cut_inner.kind); + }; + assert_eq!(cut_seq.len(), 2); + assert!(matches!(&cut_seq[0].kind, ExpressionKind::Nt(n) if n == "B")); + assert!(matches!(&cut_seq[1].kind, ExpressionKind::Nt(n) if n == "C")); + // Second alternative is just D. + assert!(matches!(&alts[1].kind, ExpressionKind::Nt(n) if n == "D")); + } + + #[test] + fn test_cut_fail_trailing() { + let input = "Rule -> A ^"; + let err = parse(input).unwrap_err(); + assert!(err.contains("expected expression after cut operator")); + } + + /// Extract the `RepeatRange` fields from a single-production + /// grammar whose rule body is a repeat-range expression. + fn repeat_range(input: &str) -> (Option<u32>, Option<u32>, RangeLimit) { + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("A").unwrap(); + let ExpressionKind::RepeatRange { + min, max, limit, .. + } = rule.expression.kind + else { + panic!("expected RepeatRange, got {:?}", rule.expression.kind); + }; + (min, max, limit) + } + + // -- Valid ranges ----------------------------------------------- + + #[test] + fn test_range_half_open() { + let (min, max, limit) = repeat_range("A -> x{2..5}"); + assert_eq!(min, Some(2)); + assert_eq!(max, Some(5)); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn test_range_half_open_no_min() { + let (min, max, limit) = repeat_range("A -> x{..5}"); + assert_eq!(min, None); + assert_eq!(max, Some(5)); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn test_range_half_open_no_max() { + let (min, max, limit) = repeat_range("A -> x{2..}"); + assert_eq!(min, Some(2)); + assert_eq!(max, None); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn test_range_half_open_unbounded() { + let (min, max, limit) = repeat_range("A -> x{..}"); + assert_eq!(min, None); + assert_eq!(max, None); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn test_range_closed() { + let (min, max, limit) = repeat_range("A -> x{2..=5}"); + assert_eq!(min, Some(2)); + assert_eq!(max, Some(5)); + assert!(matches!(limit, RangeLimit::Closed)); + } + + #[test] + fn test_range_closed_no_min() { + let (min, max, limit) = repeat_range("A -> x{..=5}"); + assert_eq!(min, None); + assert_eq!(max, Some(5)); + assert!(matches!(limit, RangeLimit::Closed)); + } + + // -- Invalid ranges --------------------------------------------- + + #[test] + fn test_range_err_max_less_than_min() { + let err = parse("A -> x{3..2}").unwrap_err(); + assert!( + err.contains("malformed"), + "expected malformed error, got: {err}" + ); + } + + #[test] + fn test_range_err_empty_exclusive_equal() { + let err = parse("A -> x{2..2}").unwrap_err(); + assert!( + err.contains("half-open range maximum must be greater"), + "expected empty-exclusive error, got: {err}" + ); + } + + #[test] + fn test_range_err_empty_exclusive_zero() { + let err = parse("A -> x{0..0}").unwrap_err(); + assert!( + err.contains("half-open range maximum must be greater"), + "expected empty-exclusive error, got: {err}" + ); + } + + #[test] + fn test_range_err_closed_no_upper() { + let err = parse("A -> x{..=}").unwrap_err(); + assert!( + err.contains("closed range must have an upper bound"), + "expected closed-needs-upper error, got: {err}" + ); + } + + #[test] + fn test_range_err_closed_no_upper_with_min() { + let err = parse("A -> x{2..=}").unwrap_err(); + assert!( + err.contains("closed range must have an upper bound"), + "expected closed-needs-upper error, got: {err}" + ); + } + + #[test] + fn test_range_err_half_open_zero_max() { + let err = parse("A -> x{..0}").unwrap_err(); + assert!( + err.contains("half-open range `..0` is empty"), + "expected half-open-zero error, got: {err}" + ); + } + + // -- Valid edge cases ------------------------------------------- + + #[test] + fn test_range_closed_exact() { + // `x{2..=2}` means exactly 2 -- not empty. + let (min, max, limit) = repeat_range("A -> x{2..=2}"); + assert_eq!(min, Some(2)); + assert_eq!(max, Some(2)); + assert!(matches!(limit, RangeLimit::Closed)); + } + + #[test] + fn test_range_half_open_zero_to_one() { + // `x{0..1}` means exactly 0 repetitions (the half-open + // range contains only 0). + let (min, max, limit) = repeat_range("A -> x{0..1}"); + assert_eq!(min, Some(0)); + assert_eq!(max, Some(1)); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + // --- Negative lookahead tests --- + + #[test] + fn lookahead_simple_nonterminal() { + let input = "Rule -> !Foo"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::NegativeLookahead(inner) = &rule.expression.kind else { + panic!("expected NegativeLookahead, got {:?}", rule.expression.kind); + }; + assert!(matches!(&inner.kind, ExpressionKind::Nt(n) if n == "Foo")); + } + + #[test] + fn lookahead_terminal() { + let input = "Rule -> !`'` Foo"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Sequence(seq) = &rule.expression.kind else { + panic!("expected Sequence, got {:?}", rule.expression.kind); + }; + assert_eq!(seq.len(), 2); + let ExpressionKind::NegativeLookahead(inner) = &seq[0].kind else { + panic!("expected NegativeLookahead, got {:?}", seq[0].kind); + }; + assert!(matches!(&inner.kind, ExpressionKind::Terminal(t) if t == "'")); + assert!(matches!(&seq[1].kind, ExpressionKind::Nt(n) if n == "Foo")); + } + + #[test] + fn lookahead_charset() { + let input = "Rule -> ![`e` `E`] SUFFIX"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Sequence(seq) = &rule.expression.kind else { + panic!("expected Sequence, got {:?}", rule.expression.kind); + }; + assert_eq!(seq.len(), 2); + let ExpressionKind::NegativeLookahead(inner) = &seq[0].kind else { + panic!("expected NegativeLookahead, got {:?}", seq[0].kind); + }; + let ExpressionKind::Charset(chars) = &inner.kind else { + panic!("expected Charset inside lookahead, got {:?}", inner.kind); + }; + assert_eq!(chars.len(), 2); + assert!(matches!(&chars[0].kind, ExpressionKind::Terminal(t) if t == "e")); + assert!(matches!(&chars[1].kind, ExpressionKind::Terminal(t) if t == "E")); + } + + #[test] + fn lookahead_grouped() { + let input = "Rule -> !(`.` | `_` | XID_Start)"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::NegativeLookahead(inner) = &rule.expression.kind else { + panic!("expected NegativeLookahead, got {:?}", rule.expression.kind); + }; + let ExpressionKind::Grouped(grouped) = &inner.kind else { + panic!("expected Grouped inside lookahead, got {:?}", inner.kind); + }; + let ExpressionKind::Alt(alts) = &grouped.kind else { + panic!("expected Alt inside Grouped, got {:?}", grouped.kind); + }; + assert_eq!(alts.len(), 3); + assert!(matches!(&alts[0].kind, ExpressionKind::Terminal(t) if t == ".")); + assert!(matches!(&alts[1].kind, ExpressionKind::Terminal(t) if t == "_")); + assert!(matches!(&alts[2].kind, ExpressionKind::Nt(n) if n == "XID_Start")); + } + + #[test] + fn lookahead_in_sequence_middle() { + let input = "Rule -> A !B C"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Sequence(seq) = &rule.expression.kind else { + panic!("expected Sequence, got {:?}", rule.expression.kind); + }; + assert_eq!(seq.len(), 3); + assert!(matches!(&seq[0].kind, ExpressionKind::Nt(n) if n == "A")); + let ExpressionKind::NegativeLookahead(inner) = &seq[1].kind else { + panic!("expected NegativeLookahead, got {:?}", seq[1].kind); + }; + assert!(matches!(&inner.kind, ExpressionKind::Nt(n) if n == "B")); + assert!(matches!(&seq[2].kind, ExpressionKind::Nt(n) if n == "C")); + } + + #[test] + fn lookahead_in_repetition() { + let input = "Rule -> (!A B)*"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Repeat(rep) = &rule.expression.kind else { + panic!("expected Repeat, got {:?}", rule.expression.kind); + }; + let ExpressionKind::Grouped(grouped) = &rep.kind else { + panic!("expected Grouped inside Repeat, got {:?}", rep.kind); + }; + let ExpressionKind::Sequence(seq) = &grouped.kind else { + panic!("expected Sequence inside Grouped, got {:?}", grouped.kind); + }; + assert_eq!(seq.len(), 2); + assert!(matches!(&seq[0].kind, ExpressionKind::NegativeLookahead(_))); + assert!(matches!(&seq[1].kind, ExpressionKind::Nt(n) if n == "B")); + } + + #[test] + fn lookahead_in_alternation() { + let input = "Rule -> !A B | C"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Alt(alts) = &rule.expression.kind else { + panic!("expected Alt, got {:?}", rule.expression.kind); + }; + assert_eq!(alts.len(), 2); + let ExpressionKind::Sequence(seq) = &alts[0].kind else { + panic!("expected Sequence, got {:?}", alts[0].kind); + }; + assert_eq!(seq.len(), 2); + assert!(matches!(&seq[0].kind, ExpressionKind::NegativeLookahead(_))); + assert!(matches!(&seq[1].kind, ExpressionKind::Nt(n) if n == "B")); + assert!(matches!(&alts[1].kind, ExpressionKind::Nt(n) if n == "C")); + } + + #[test] + fn lookahead_fail_trailing() { + let input = "Rule -> !"; + let err = parse(input).unwrap_err(); + assert!(err.contains("expected expression after !")); + } + + // --- Unicode tests --- + + #[test] + fn unicode_4_digit() { + let input = "Rule -> U+0009"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Unicode((ch, s)) = &rule.expression.kind else { + panic!("expected Unicode, got {:?}", rule.expression.kind); + }; + assert_eq!(*ch, '\t'); + assert_eq!(s, "0009"); + } + + #[test] + fn unicode_5_digit() { + let input = "Rule -> U+E0000"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Unicode((ch, s)) = &rule.expression.kind else { + panic!("expected Unicode, got {:?}", rule.expression.kind); + }; + assert_eq!(*ch, '\u{E0000}'); + assert_eq!(s, "E0000"); + } + + #[test] + fn unicode_6_digit() { + let input = "Rule -> U+10FFFF"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Unicode((ch, s)) = &rule.expression.kind else { + panic!("expected Unicode, got {:?}", rule.expression.kind); + }; + assert_eq!(*ch, '\u{10FFFF}'); + assert_eq!(s, "10FFFF"); + } + + #[test] + fn unicode_in_alternation() { + let input = "Rule -> U+0009 | U+000A"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Alt(alts) = &rule.expression.kind else { + panic!("expected Alt, got {:?}", rule.expression.kind); + }; + assert_eq!(alts.len(), 2); + assert!(matches!( + &alts[0].kind, + ExpressionKind::Unicode((ch, _)) if *ch == '\t' + )); + assert!(matches!( + &alts[1].kind, + ExpressionKind::Unicode((ch, _)) if *ch == '\n' + )); + } + + // --- Character / charset range tests --- + + #[test] + fn charset_unicode_range() { + let input = "Rule -> [U+0000-U+007F]"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Charset(chars) = &rule.expression.kind else { + panic!("expected Charset, got {:?}", rule.expression.kind); + }; + assert_eq!(chars.len(), 1); + let ExpressionKind::CharacterRange(a, b) = &chars[0].kind else { + panic!("expected Range, got {:?}", chars[0]); + }; + assert!(matches!(a, Character::Unicode((ch, _)) if *ch == '\0')); + assert!(matches!( + b, + Character::Unicode((ch, _)) if *ch == '\u{7F}' + )); + } + + #[test] + fn charset_char_range() { + let input = "Rule -> [`a`-`z`]"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Charset(chars) = &rule.expression.kind else { + panic!("expected Charset, got {:?}", rule.expression.kind); + }; + assert_eq!(chars.len(), 1); + let ExpressionKind::CharacterRange(a, b) = &chars[0].kind else { + panic!("expected Range, got {:?}", chars[0]); + }; + assert!(matches!(a, Character::Char(ch) if *ch == 'a')); + assert!(matches!(b, Character::Char(ch) if *ch == 'z')); + } + + #[test] + fn charset_mixed_range() { + let input = "Rule -> [`a`-U+007A]"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Charset(chars) = &rule.expression.kind else { + panic!("expected Charset, got {:?}", rule.expression.kind); + }; + assert_eq!(chars.len(), 1); + let ExpressionKind::CharacterRange(a, b) = &chars[0].kind else { + panic!("expected Range, got {:?}", chars[0]); + }; + assert!(matches!(a, Character::Char(ch) if *ch == 'a')); + assert!(matches!( + b, + Character::Unicode((ch, _)) if *ch == 'z' + )); + } + + #[test] + fn charset_multiple_unicode_ranges() { + let input = "Rule -> [U+0000-U+D7FF U+E000-U+10FFFF]"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Charset(chars) = &rule.expression.kind else { + panic!("expected Charset, got {:?}", rule.expression.kind); + }; + assert_eq!(chars.len(), 2); + let ExpressionKind::CharacterRange(a1, b1) = &chars[0].kind else { + panic!("expected Range, got {:?}", chars[0]); + }; + assert!(matches!(a1, Character::Unicode((ch, _)) if *ch == '\0')); + assert!(matches!(b1, Character::Unicode((ch, _)) if *ch == '\u{D7FF}')); + let ExpressionKind::CharacterRange(a2, b2) = &chars[1].kind else { + panic!("expected Range, got {:?}", chars[1]); + }; + assert!(matches!(a2, Character::Unicode((ch, _)) if *ch == '\u{E000}')); + assert!(matches!(b2, Character::Unicode((ch, _)) if *ch == '\u{10FFFF}')); + } + + #[test] + fn charset_terminals_and_named() { + let input = "Rule -> [`a` `b` Foo]"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Charset(chars) = &rule.expression.kind else { + panic!("expected Charset, got {:?}", rule.expression.kind); + }; + assert_eq!(chars.len(), 3); + assert!(matches!(&chars[0].kind, ExpressionKind::Terminal(t) if t == "a")); + assert!(matches!(&chars[1].kind, ExpressionKind::Terminal(t) if t == "b")); + assert!(matches!(&chars[2].kind, ExpressionKind::Nt(n) if n == "Foo")); + } + + // --- Negative lookahead combined with charset --- + + #[test] + fn lookahead_charset_with_named_and_terminals() { + // Pattern from tokens.md: ![`'` `\` LF CR TAB] ASCII + let input = "Rule -> ![`x` `y` LF] Foo"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Sequence(seq) = &rule.expression.kind else { + panic!("expected Sequence, got {:?}", rule.expression.kind); + }; + assert_eq!(seq.len(), 2); + let ExpressionKind::NegativeLookahead(inner) = &seq[0].kind else { + panic!("expected NegativeLookahead, got {:?}", seq[0].kind); + }; + let ExpressionKind::Charset(chars) = &inner.kind else { + panic!("expected Charset, got {:?}", inner.kind); + }; + assert_eq!(chars.len(), 3); + assert!(matches!(&chars[0].kind, ExpressionKind::Terminal(t) if t == "x")); + assert!(matches!(&chars[1].kind, ExpressionKind::Terminal(t) if t == "y")); + assert!(matches!(&chars[2].kind, ExpressionKind::Nt(n) if n == "LF")); + } + + // --- Negative lookahead combined with Unicode --- + + #[test] + fn lookahead_charset_with_unicode_range() { + let input = "Rule -> ![U+0000-U+007F] Foo"; + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("Rule").unwrap(); + let ExpressionKind::Sequence(seq) = &rule.expression.kind else { + panic!("expected Sequence, got {:?}", rule.expression.kind); + }; + let ExpressionKind::NegativeLookahead(inner) = &seq[0].kind else { + panic!("expected NegativeLookahead, got {:?}", seq[0].kind); + }; + let ExpressionKind::Charset(chars) = &inner.kind else { + panic!("expected Charset, got {:?}", inner.kind); + }; + assert_eq!(chars.len(), 1); + let ExpressionKind::CharacterRange(a, b) = &chars[0].kind else { + panic!("expected Range, got {:?}", chars[0]); + }; + assert!(matches!(a, Character::Unicode((ch, _)) if *ch == '\0')); + assert!(matches!( + b, + Character::Unicode((ch, _)) if *ch == '\u{7F}' + )); + } + + // --- `parse_name` digit rejection tests --- + + #[test] + fn parse_name_rejects_leading_digits() { + // `{123}` should not parse as a named reference. The + // digits don't form a valid name and there is no `..` + // range operator, so the parser should reject this. + let err = parse("A -> x{123}").unwrap_err(); + assert!( + err.contains("expected `..`"), + "expected range-syntax error for {{123}}, got: {err}" + ); + } + + #[test] + fn parse_name_allows_letter_then_digit() { + // `n1` is a valid name (starts with a letter). + let grammar = parse("A -> x{n1:2..5}").unwrap(); + let rule = grammar.productions.get("A").unwrap(); + let ExpressionKind::RepeatRange { + name, + min, + max, + limit, + .. + } = &rule.expression.kind + else { + panic!("expected RepeatRange, got {:?}", rule.expression.kind); + }; + assert_eq!(name.as_deref(), Some("n1")); + assert_eq!(*min, Some(2)); + assert_eq!(*max, Some(5)); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn parse_name_allows_underscore_start() { + // `_n` is a valid name (starts with underscore). + let grammar = parse("A -> x{_n:2..5}").unwrap(); + let rule = grammar.productions.get("A").unwrap(); + let ExpressionKind::RepeatRange { + name, + min, + max, + limit, + .. + } = &rule.expression.kind + else { + panic!("expected RepeatRange, got {:?}", rule.expression.kind); + }; + assert_eq!(name.as_deref(), Some("_n")); + assert_eq!(*min, Some(2)); + assert_eq!(*max, Some(5)); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + // --- Named repeat range tests --- + + /// Extract full `RepeatRange` fields including the name. + fn named_repeat_range(input: &str) -> (Option<String>, Option<u32>, Option<u32>, RangeLimit) { + let grammar = parse(input).unwrap(); + let rule = grammar.productions.get("A").unwrap(); + let ExpressionKind::RepeatRange { + name, + min, + max, + limit, + .. + } = &rule.expression.kind + else { + panic!("expected RepeatRange, got {:?}", rule.expression.kind); + }; + (name.clone(), *min, *max, *limit) + } + + #[test] + fn named_range_closed() { + let (name, min, max, limit) = named_repeat_range("A -> x{n:1..=255}"); + assert_eq!(name.as_deref(), Some("n")); + assert_eq!(min, Some(1)); + assert_eq!(max, Some(255)); + assert!(matches!(limit, RangeLimit::Closed)); + } + + #[test] + fn named_range_half_open() { + let (name, min, max, limit) = named_repeat_range("A -> x{n:2..5}"); + assert_eq!(name.as_deref(), Some("n")); + assert_eq!(min, Some(2)); + assert_eq!(max, Some(5)); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn named_range_omitted_min() { + let (name, min, max, limit) = named_repeat_range("A -> x{n:..=5}"); + assert_eq!(name.as_deref(), Some("n")); + assert_eq!(min, None); + assert_eq!(max, Some(5)); + assert!(matches!(limit, RangeLimit::Closed)); + } + + #[test] + fn named_range_omitted_max() { + let (name, min, max, limit) = named_repeat_range("A -> x{n:2..}"); + assert_eq!(name.as_deref(), Some("n")); + assert_eq!(min, Some(2)); + assert_eq!(max, None); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn named_reference() { + // `{n}` without a colon or range produces a + // RepeatRangeNamed variant. + let grammar = parse("A -> x{n}").unwrap(); + let rule = grammar.productions.get("A").unwrap(); + let ExpressionKind::RepeatRangeNamed(_, name) = &rule.expression.kind else { + panic!("expected RepeatRangeNamed, got {:?}", rule.expression.kind); + }; + assert_eq!(name, "n"); + } + + #[test] + fn named_binding_and_reference_in_sequence() { + // A production with a named binding and a named reference. + let grammar = parse("A -> x{n:1..=255} y{n}").unwrap(); + let rule = grammar.productions.get("A").unwrap(); + let ExpressionKind::Sequence(seq) = &rule.expression.kind else { + panic!("expected Sequence, got {:?}", rule.expression.kind); + }; + assert_eq!(seq.len(), 2); + + // First element: x{n:1..=255} + let ExpressionKind::RepeatRange { + name, + min, + max, + limit, + .. + } = &seq[0].kind + else { + panic!("expected RepeatRange, got {:?}", seq[0].kind); + }; + assert_eq!(name.as_deref(), Some("n")); + assert_eq!(*min, Some(1)); + assert_eq!(*max, Some(255)); + assert!(matches!(limit, RangeLimit::Closed)); + + // Second element: y{n} + let ExpressionKind::RepeatRangeNamed(_, ref_name) = &seq[1].kind else { + panic!("expected RepeatRangeNamed, got {:?}", seq[1].kind); + }; + assert_eq!(ref_name, "n"); + } + + #[test] + fn named_range_backtrack_to_plain_range() { + // When parse_name() succeeds but the next byte is + // neither `:` nor `}`, the parser backtracks and + // falls through to plain range parsing. `{2..5}` is + // such a case after the parse_name fix (digits are + // rejected), but let's test a scenario where a name is + // parsed and then backtracked. + // + // There is no single-character token after a name that + // triggers backtrack in valid grammar (the match arms + // cover `:` and `}`), but the fallback resets the index + // and tries plain range parsing. We verify that + // `{2..5}` parses correctly as a plain range even + // though it starts with a digit. + let (min, max, limit) = repeat_range("A -> x{2..5}"); + assert_eq!(min, Some(2)); + assert_eq!(max, Some(5)); + assert!(matches!(limit, RangeLimit::HalfOpen)); + } + + #[test] + fn named_range_err_colon_missing_dots() { + // `{n:}` -- name followed by colon, then no `..`. + let err = parse("A -> x{n:}").unwrap_err(); + assert!( + err.contains("expected `..`"), + "expected `..` error for {{n:}}, got: {err}" + ); + } + + #[test] + fn named_range_err_empty_braces() { + // `{}` -- empty braces contain no name and no range. + let err = parse("A -> x{}").unwrap_err(); + assert!( + err.contains("expected `..`"), + "expected `..` error for {{}}, got: {err}" + ); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/Cargo.toml new file mode 100644 index 00000000..68b9aefa --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "mdbook-spec" +edition = "2024" +license = "MIT OR Apache-2.0" +description = "An mdBook preprocessor to help with the Rust specification." +repository = "https://github.com/rust-lang/spec/" +default-run = "mdbook-spec" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.79" +diagnostics = { path = "../diagnostics" } +grammar = { path = "../grammar" } +mdbook-markdown = "0.5.1" +mdbook-preprocessor = "0.5.1" +once_cell = "1.19.0" +pathdiff = "0.2.1" +railroad = { version = "0.3.9", default-features = false } +regex = "1.12.2" +semver = "1.0.21" +serde_json = "1.0.113" +tempfile = "3.10.1" +walkdir = "2.5.0" diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-APACHE b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-APACHE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-MIT b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-MIT new file mode 100644 index 00000000..1653b5c3 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2024 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/README.md b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/README.md new file mode 100644 index 00000000..e69f6e1f --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/README.md @@ -0,0 +1,3 @@ +# mdbook-spec + +This is an mdbook preprocessor to add some extensions for the Rust Reference. diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/admonitions.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/admonitions.rs new file mode 100644 index 00000000..da391838 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/admonitions.rs @@ -0,0 +1,106 @@ +//! Support for admonitions using markdown blockquotes. +//! +//! To add support for a new admonition: +//! +//! 1. Modify the [`admonitions`] function below to include an icon. +//! 2. Modify `theme/reference.css` to set the color for the different themes. +//! Look at one of the other admonitions as a guide. +//! 3. Update `src/introduction.md` and describe what this new block is for +//! with an example. +//! 4. Update `docs/authoring.md` to show an example of your new admonition. + +use crate::{Diagnostics, warn_or_err}; +use mdbook_preprocessor::book::Chapter; +use regex::{Captures, Regex}; +use std::sync::LazyLock; + +/// The Regex for the syntax for blockquotes that have a specific CSS class, +/// like `> [!WARNING]`. +static ADMONITION_RE: LazyLock<Regex> = LazyLock::new(|| { + Regex::new(r"(?m)^ *> \[!(?<admon>[^]]+)\]\n(?<blockquote>(?: *>.*\n)+)").unwrap() +}); + +// This icon is from GitHub, MIT License, see https://github.com/primer/octicons +const ICON_NOTE: &str = r#"<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path>"#; + +// This icon is from GitHub, MIT License, see https://github.com/primer/octicons +const ICON_WARNING: &str = r#"<path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>"#; + +// This icon is from GitHub, MIT License, see https://github.com/primer/octicons +const ICON_EXAMPLE: &str = r#"<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>"#; + +/// Converts blockquotes with special headers into admonitions. +/// +/// The blockquote should look something like: +/// +/// ```markdown +/// > [!WARNING] +/// > ... +/// ``` +/// +/// This will add a `<div class="alert alert-warning">` around the +/// blockquote so that it can be styled differently, and injects an icon. +/// The actual styling needs to be added in the `reference.css` CSS file. +pub fn admonitions(chapter: &Chapter, diag: &mut Diagnostics) -> String { + ADMONITION_RE + .replace_all(&chapter.content, |caps: &Captures<'_>| { + let lower = caps["admon"].to_lowercase(); + let term = to_initial_case(&caps["admon"]); + let blockquote = &caps["blockquote"]; + let initial_spaces = blockquote.chars().position(|ch| ch != ' ').unwrap_or(0); + let space = &blockquote[..initial_spaces]; + + let format_div = |class, content| { + format!( + "{space}<div class=\"alert alert-{class}\">\n\ + \n\ + {space}> <p class=\"alert-title\">\ + {content}</p>\n\ + {space} >\n\ + {blockquote}\n\ + \n\ + {space}</div>\n", + ) + }; + + if lower.starts_with("edition-") { + let edition = &lower[8..]; + return format_div( + "edition", + format!( + "<span class=\"alert-title-edition\">{edition}</span> Edition differences" + ), + ); + } + + let svg = match lower.as_str() { + "note" => ICON_NOTE, + "warning" => ICON_WARNING, + "example" => ICON_EXAMPLE, + _ => { + warn_or_err!( + diag, + "admonition `{lower}` in {:?} is incorrect or not yet supported", + chapter.path.as_ref().unwrap() + ); + "" + } + }; + format_div( + &lower, + format!( + "<svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\">\ + {svg}\ + </svg>{term}" + ), + ) + }) + .to_string() +} + +fn to_initial_case(s: &str) -> String { + let mut chars = s.chars(); + let first = chars.next().expect("not empty").to_uppercase(); + let rest = chars.as_str().to_lowercase(); + format!("{first}{rest}") +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar.rs new file mode 100644 index 00000000..de51f825 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar.rs @@ -0,0 +1,254 @@ +//! Support for rendering the grammar. + +use diagnostics::{Diagnostics, warn_or_err}; +use grammar::{GRAMMAR_RE, Grammar}; +use mdbook_preprocessor::book::Chapter; +use regex::{Captures, Regex}; +use std::collections::{HashMap, HashSet}; +use std::fmt::Write; +use std::sync::LazyLock; + +mod render_markdown; +mod render_railroad; + +static NAMES_RE: LazyLock<Regex> = LazyLock::new(|| { + // For match rule names, we support standard ASCII identifiers + // or non-ASCII characters (such as `⊥`). This must be + // kept in sync with `is_name_start` and `is_name_continue` in + // `tools/grammar/src/parser.rs`. + Regex::new(r"(?m)^(?:@root )?([A-Za-z0-9_]+|[^\x00-\x7F])(?: \([^)]+\))? ->").unwrap() +}); + +#[derive(Debug)] +pub struct RenderCtx { + md_link_map: HashMap<String, String>, + rr_link_map: HashMap<String, String>, + for_summary: bool, +} + +#[cfg(test)] +impl RenderCtx { + pub(crate) fn for_test() -> Self { + RenderCtx { + md_link_map: HashMap::new(), + rr_link_map: HashMap::new(), + for_summary: false, + } + } +} + +/// Replaces the text grammar in the given chapter with the rendered version. +pub fn insert_grammar(grammar: &Grammar, chapter: &Chapter, diag: &mut Diagnostics) -> String { + let link_map = make_relative_link_map(grammar, chapter); + + let mut content = GRAMMAR_RE + .replace_all(&chapter.content, |cap: &Captures<'_>| { + let names: Vec<_> = NAMES_RE + .captures_iter(&cap[2]) + .map(|cap| cap.get(1).unwrap().as_str()) + .collect(); + let for_lexer = &cap[1] == "lexer"; + render_names(grammar, &names, &link_map, for_lexer, chapter, diag) + }) + .to_string(); + + // Make all production names easily linkable. + let is_summary = is_summary(chapter); + for (name, path) in &link_map { + let id = render_markdown::markdown_id(name, is_summary); + if is_summary { + // On the summary page, link to the production on the summary page. + writeln!(content, "[{name}]: #{id}").unwrap(); + } else { + // This includes two variants, one for convenience (like + // `[ArrayExpression]`), and one with the `grammar-` prefix to + // disambiguate links that have the same name as a rule (rules + // take precedence). + writeln!( + content, + "[{name}]: {path}#{id}\n\ + [grammar-{name}]: {path}#{id}" + ) + .unwrap(); + } + } + + // Inject the stylesheets for railroad diagrams if necessary + if content.contains("class=\"railroad\"") { + format!( + "<style type=\"text/css\">\n{}\n</style>\n\n{content}", + render_railroad::themed_stylesheets() + ) + } else { + content + } +} + +/// Converts link reference definitions that point to a grammar rule +/// to the correct link. +/// +/// For example: +/// +/// ```markdown +/// We accept any [token]. +/// +/// [token]: grammar-Token +/// ``` +/// +/// This will convert the `[token]` definition to point +/// to the actual link. +/// +/// This supports both a `grammar-` prefixed form (e.g. +/// `grammar-Token`) and a bare rule name (e.g. `Token`). +pub fn grammar_link_references(chapter: &Chapter, grammar: &Grammar) -> String { + let current_path = chapter.path.as_ref().unwrap().parent().unwrap(); + let for_summary = is_summary(chapter); + crate::MD_LINK_REFERENCE_DEFINITION + .replace_all(&chapter.content, |caps: &Captures<'_>| { + let dest = &caps["dest"]; + let name = dest.strip_prefix("grammar-").unwrap_or(dest); + if let Some(production) = grammar.productions.get(name) { + let label = &caps["label"]; + let relative = pathdiff::diff_paths(&production.path, current_path).unwrap(); + // Adjust paths for Windows. + let relative = relative.display().to_string().replace('\\', "/"); + let id = render_markdown::markdown_id(name, for_summary); + if for_summary { + format!("[{label}]: #{id}") + } else { + format!("[{label}]: {relative}#{id}") + } + } else { + caps.get(0).unwrap().as_str().to_string() + } + }) + .to_string() +} + +/// Creates a map of production name -> relative link path. +fn make_relative_link_map(grammar: &Grammar, chapter: &Chapter) -> HashMap<String, String> { + let current_path = chapter.path.as_ref().unwrap().parent().unwrap(); + grammar + .productions + .values() + .map(|p| { + let relative = pathdiff::diff_paths(&p.path, current_path).unwrap(); + // Adjust paths for Windows. + let relative = relative.display().to_string().replace('\\', "/"); + (p.name.clone(), relative) + }) + .collect() +} + +/// Helper to take a list of production names and to render all of those to a +/// mixture of markdown and HTML. +fn render_names( + grammar: &Grammar, + names: &[&str], + link_map: &HashMap<String, String>, + for_lexer: bool, + chapter: &Chapter, + diag: &mut Diagnostics, +) -> String { + let for_summary = is_summary(chapter); + let mut output = String::new(); + output.push_str( + "<div class=\"grammar-container\">\n\ + \n", + ); + if for_lexer { + output.push_str("**<sup>Lexer</sup>**\n"); + } else { + output.push_str("**<sup>Syntax</sup>**\n"); + } + output.push_str("<br>\n"); + + // Convert the link map to add the id. + let update_link_map = |get_id: fn(&str, bool) -> String| -> HashMap<String, String> { + link_map + .iter() + .map(|(name, path)| { + let id = get_id(name, for_summary); + let path = if for_summary { + format!("#{id}") + } else { + format!("{path}#{id}") + }; + (name.clone(), path) + }) + .collect() + }; + + let render_ctx = RenderCtx { + md_link_map: update_link_map(render_markdown::markdown_id), + rr_link_map: update_link_map(render_railroad::railroad_id), + for_summary, + }; + + if let Err(e) = render_markdown::render_markdown(grammar, &render_ctx, &names, &mut output) { + warn_or_err!( + diag, + "grammar failed in chapter {:?}: {e}", + chapter.source_path.as_ref().unwrap() + ); + } + + output.push_str( + "\n\ + <button class=\"grammar-toggle-railroad\" type=\"button\" \ + title=\"Toggle railroad display\" \ + onclick=\"toggle_railroad()\">\ + Show Railroad\ + </button>\n\ + </div>\n\ + <div class=\"grammar-railroad grammar-hidden\">\n\ + \n", + ); + + if let Err(e) = render_railroad::render_railroad(grammar, &render_ctx, &names, &mut output) { + warn_or_err!( + diag, + "grammar failed in chapter {:?}: {e}", + chapter.source_path.as_ref().unwrap() + ); + } + + output.push_str("</div>\n"); + + output +} + +pub fn is_summary(chapter: &Chapter) -> bool { + chapter.name == "Grammar summary" +} + +/// Inserts the summary of all grammar rules into the grammar summary chapter. +pub fn insert_summary(grammar: &Grammar, chapter: &Chapter, diag: &mut Diagnostics) -> String { + let link_map = make_relative_link_map(grammar, chapter); + let mut seen = HashSet::new(); + let categories: Vec<_> = grammar + .name_order + .iter() + .map(|name| &grammar.productions[name].category) + .filter(|cat| seen.insert(*cat)) + .collect(); + let mut grammar_summary = String::new(); + for category in categories { + let mut chars = category.chars(); + let cap = chars.next().unwrap().to_uppercase().collect::<String>() + chars.as_str(); + write!(grammar_summary, "\n## {cap} summary\n\n").unwrap(); + let names: Vec<_> = grammar + .name_order + .iter() + .filter(|name| grammar.productions[*name].category == *category) + .map(|s| s.as_str()) + .collect(); + let for_lexer = category == "lexer"; + let s = render_names(grammar, &names, &link_map, for_lexer, chapter, diag); + grammar_summary.push_str(&s); + } + + chapter + .content + .replace("{{ grammar-summary }}", &grammar_summary) +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_markdown.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_markdown.rs new file mode 100644 index 00000000..458b992d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_markdown.rs @@ -0,0 +1,458 @@ +//! Renders the grammar to markdown. + +use super::RenderCtx; +use crate::grammar::Grammar; +use anyhow::bail; +use grammar::{Character, Expression, ExpressionKind, Production}; +use regex::Regex; +use std::borrow::Cow; +use std::fmt::Write; +use std::sync::LazyLock; + +pub fn render_markdown( + grammar: &Grammar, + cx: &RenderCtx, + names: &[&str], + output: &mut String, +) -> anyhow::Result<()> { + let mut iter = names.into_iter().peekable(); + while let Some(name) = iter.next() { + let Some(prod) = grammar.productions.get(*name) else { + bail!("could not find grammar production named `{name}`"); + }; + render_production(prod, cx, output); + if iter.peek().is_some() { + output.push_str("\n"); + } + } + Ok(()) +} + +/// The HTML id for the production. +pub fn markdown_id(name: &str, for_summary: bool) -> String { + if for_summary { + format!("grammar-summary-{}", name) + } else { + format!("grammar-{}", name) + } +} + +fn render_production(prod: &Production, cx: &RenderCtx, output: &mut String) { + let dest = cx + .rr_link_map + .get(&prod.name) + .map(|path| path.to_string()) + .unwrap_or_else(|| format!("missing")); + for expr in &prod.comments { + render_expression(expr, cx, output); + } + write!( + output, + "<span class=\"grammar-text grammar-production\" id=\"{id}\" \ + onclick=\"show_railroad()\"\ + >\ + [{name}]({dest})\ + </span> → ", + id = markdown_id(&prod.name, cx.for_summary), + name = prod.name, + ) + .unwrap(); + render_expression(&prod.expression, cx, output); + output.push('\n'); +} + +fn render_expression(expr: &Expression, cx: &RenderCtx, output: &mut String) { + match &expr.kind { + ExpressionKind::Grouped(e) => { + output.push_str("( "); + render_expression(e, cx, output); + if !e.last_expr().is_break() { + output.push(' '); + } + output.push(')'); + } + ExpressionKind::Alt(es) => { + let mut iter = es.iter().peekable(); + while let Some(e) = iter.next() { + render_expression(e, cx, output); + if iter.peek().is_some() { + if !e.last_expr().is_break() { + output.push(' '); + } + output.push_str("| "); + } + } + } + ExpressionKind::Sequence(es) => { + let mut iter = es.iter().peekable(); + while let Some(e) = iter.next() { + render_expression(e, cx, output); + if iter.peek().is_some() && !e.last_expr().is_break() { + output.push(' '); + } + } + } + ExpressionKind::Optional(e) => { + render_expression(e, cx, output); + output.push_str("<sup>?</sup>"); + } + ExpressionKind::NegativeLookahead(e) => { + output.push('!'); + render_expression(e, cx, output); + } + ExpressionKind::Repeat(e) => { + render_expression(e, cx, output); + output.push_str("<sup>\\*</sup>"); + } + ExpressionKind::RepeatPlus(e) => { + render_expression(e, cx, output); + output.push_str("<sup>+</sup>"); + } + ExpressionKind::RepeatRange { + expr, + name, + min, + max, + limit, + } => { + render_expression(expr, cx, output); + write!( + output, + "<sup>{name}{min}{limit}{max}</sup>", + name = name.as_ref().map(|n| format!("{n}:")).unwrap_or_default(), + min = min.map(|v| v.to_string()).unwrap_or_default(), + max = max.map(|v| v.to_string()).unwrap_or_default(), + ) + .unwrap(); + } + ExpressionKind::RepeatRangeNamed(e, name) => { + render_expression(e, cx, output); + write!(output, "<sup>{name}</sup>").unwrap(); + } + ExpressionKind::Nt(nt) => { + let dest = cx.md_link_map.get(nt).map_or("missing", |d| d.as_str()); + write!(output, "<span class=\"grammar-text\">[{nt}]({dest})</span>").unwrap(); + } + ExpressionKind::Terminal(t) => { + write!( + output, + "<span class=\"grammar-literal\">{}</span>", + markdown_escape(t) + ) + .unwrap(); + } + ExpressionKind::Prose(s) => { + write!(output, "<span class=\"grammar-text\">\\<{s}\\></span>").unwrap(); + } + ExpressionKind::Break(indent) => { + output.push_str("\\\n"); + output.push_str(&" ".repeat(*indent)); + } + ExpressionKind::Comment(s) => { + write!(output, "<span class=\"grammar-comment\">// {s}</span>").unwrap(); + } + ExpressionKind::Charset(set) => charset_render_markdown(cx, set, output), + ExpressionKind::CharacterRange(start, end) => { + let write_ch = |ch: &Character, output: &mut String| match ch { + Character::Char(ch) => write!( + output, + "<span class=\"grammar-literal\">{}</span>", + markdown_escape(&ch.to_string()) + ) + .unwrap(), + Character::Unicode((_, s)) => write!(output, "U+{s}").unwrap(), + }; + write_ch(start, output); + output.push('-'); + write_ch(end, output); + } + ExpressionKind::NegExpression(e) => { + output.push('~'); + render_expression(e, cx, output); + } + ExpressionKind::Cut(e) => { + output.push_str("^ "); + render_expression(e, cx, output); + } + ExpressionKind::Unicode((_, s)) => { + output.push_str("U+"); + output.push_str(s); + } + } + if let Some(suffix) = &expr.suffix { + write!(output, "<sub class=\"grammar-text\">{suffix}</sub>").unwrap(); + } + if !cx.for_summary { + if let Some(footnote) = &expr.footnote { + // The `ZeroWidthSpace` is to avoid conflicts with markdown link + // references. + write!(output, "​[^{footnote}]").unwrap(); + } + } +} + +fn charset_render_markdown(cx: &RenderCtx, set: &[Expression], output: &mut String) { + output.push_str("\\["); + let mut iter = set.iter().peekable(); + while let Some(expr) = iter.next() { + render_expression(expr, cx, output); + if iter.peek().is_some() { + output.push(' '); + } + } + output.push(']'); +} + +/// Escapes characters that markdown would otherwise interpret. +fn markdown_escape(s: &str) -> Cow<'_, str> { + static ESC_RE: LazyLock<Regex> = + LazyLock::new(|| Regex::new(r#"[\\`_*\[\](){}'".-]"#).unwrap()); + ESC_RE.replace_all(s, r"\$0") +} + +#[cfg(test)] +mod tests { + use super::*; + use grammar::RangeLimit; + use std::collections::HashMap; + + /// Creates a minimal `RenderCtx` for testing. + fn test_cx() -> RenderCtx { + RenderCtx { + md_link_map: HashMap::new(), + rr_link_map: HashMap::new(), + for_summary: false, + } + } + + /// Renders a single expression to a markdown string. + fn render(kind: ExpressionKind) -> String { + let cx = test_cx(); + let expr = Expression::new_kind(kind, 0); + let mut output = String::new(); + render_expression(&expr, &cx, &mut output); + output + } + + // -- Negative lookahead tests -- + + #[test] + fn lookahead_nonterminal() { + let result = render(ExpressionKind::NegativeLookahead(Box::new( + Expression::new_kind(ExpressionKind::Nt("CHAR".to_string()), 0), + ))); + assert!(result.contains("!"), "should contain `!` prefix"); + assert!( + result.contains("CHAR"), + "should contain the nonterminal name" + ); + } + + #[test] + fn lookahead_terminal() { + let result = render(ExpressionKind::NegativeLookahead(Box::new( + Expression::new_kind(ExpressionKind::Terminal("'".to_string()), 0), + ))); + assert!(result.starts_with("!"), "should start with `!`"); + assert!( + result.contains("grammar-literal"), + "should render inner terminal as a grammar literal" + ); + } + + #[test] + fn lookahead_charset() { + let result = render(ExpressionKind::NegativeLookahead(Box::new( + Expression::new_kind( + ExpressionKind::Charset(vec![ + Expression::new_kind(ExpressionKind::Terminal("e".to_string()), 0), + Expression::new_kind(ExpressionKind::Terminal("E".to_string()), 0), + ]), + 0, + ), + ))); + assert!(result.starts_with("!"), "should start with `!`"); + assert!( + result.contains("\\["), + "should contain escaped opening bracket for charset" + ); + } + + #[test] + fn lookahead_grouped() { + // !( `.` | `_` ) + let inner = ExpressionKind::Grouped(Box::new(Expression::new_kind( + ExpressionKind::Alt(vec![ + Expression::new_kind(ExpressionKind::Terminal(".".to_string()), 0), + Expression::new_kind(ExpressionKind::Terminal("_".to_string()), 0), + ]), + 0, + ))); + let result = render(ExpressionKind::NegativeLookahead(Box::new( + Expression::new_kind(inner, 0), + ))); + assert!(result.starts_with("!(")); + assert!(result.contains("|")); + } + + // -- Unicode tests -- + + #[test] + fn unicode_4_digit() { + let result = render(ExpressionKind::Unicode(('\t', "0009".to_string()))); + assert_eq!(result, "U+0009"); + } + + #[test] + fn unicode_6_digit() { + let result = render(ExpressionKind::Unicode(( + '\u{10FFFF}', + "10FFFF".to_string(), + ))); + assert_eq!(result, "U+10FFFF"); + } + + // -- Charset with Unicode range tests -- + + #[test] + fn charset_unicode_range() { + let result = render(ExpressionKind::Charset(vec![Expression::new_kind( + ExpressionKind::CharacterRange( + Character::Unicode(('\0', "0000".to_string())), + Character::Unicode(('\u{007F}', "007F".to_string())), + ), + 0, + )])); + assert!(result.contains("\\[")); + assert!(result.contains("U+0000")); + assert!(result.contains("U+007F")); + assert!(result.contains("-")); + } + + #[test] + fn charset_char_range() { + let result = render(ExpressionKind::Charset(vec![Expression::new_kind( + ExpressionKind::CharacterRange(Character::Char('a'), Character::Char('z')), + 0, + )])); + assert!(result.contains("\\[")); + assert!(result.contains("grammar-literal")); + assert!(result.contains("-")); + } + + #[test] + fn charset_mixed_range() { + // [`a`-U+007A] + let result = render(ExpressionKind::Charset(vec![Expression::new_kind( + ExpressionKind::CharacterRange( + Character::Char('a'), + Character::Unicode(('\u{007A}', "007A".to_string())), + ), + 0, + )])); + assert!(result.contains("grammar-literal")); + assert!(result.contains("U+007A")); + assert!(result.contains("-")); + } + + // -- Cut test -- + + #[test] + fn cut_rendering() { + let result = render(ExpressionKind::Cut(Box::new(Expression::new_kind( + ExpressionKind::Nt("Foo".to_string()), + 0, + )))); + assert!(result.starts_with("^ "), "cut should render as `^ ` prefix"); + assert!(result.contains("Foo")); + } + + // -- NegExpression test -- + + #[test] + fn neg_expression_rendering() { + let result = render(ExpressionKind::NegExpression(Box::new( + Expression::new_kind( + ExpressionKind::Charset(vec![Expression::new_kind( + ExpressionKind::Terminal("a".to_string()), + 0, + )]), + 0, + ), + ))); + assert!( + result.starts_with("~"), + "neg expression should render as `~` prefix" + ); + } + + // -- Markdown escape tests -- + + #[test] + fn markdown_escape_backtick() { + assert_eq!(markdown_escape("`"), "\\`"); + } + + #[test] + fn markdown_escape_brackets() { + assert_eq!(markdown_escape("["), "\\["); + assert_eq!(markdown_escape("]"), "\\]"); + } + + #[test] + fn markdown_escape_plain() { + assert_eq!(markdown_escape("abc"), "abc"); + } + + // -- Named repeat range tests -- + + #[test] + fn repeat_range_with_name() { + // A RepeatRange with a name renders as `<sup>n:1..=255</sup>`. + let result = render(ExpressionKind::RepeatRange { + expr: Box::new(Expression::new_kind(ExpressionKind::Nt("x".to_string()), 0)), + name: Some("n".to_string()), + min: Some(1), + max: Some(255), + limit: RangeLimit::Closed, + }); + assert!( + result.contains("<sup>n:1..=255</sup>"), + "expected <sup>n:1..=255</sup>, got: {result}" + ); + } + + #[test] + fn repeat_range_without_name() { + // A RepeatRange without a name renders with no spurious + // colon -- just `<sup>2..5</sup>`. + let result = render(ExpressionKind::RepeatRange { + expr: Box::new(Expression::new_kind(ExpressionKind::Nt("x".to_string()), 0)), + name: None, + min: Some(2), + max: Some(5), + limit: RangeLimit::HalfOpen, + }); + assert!( + result.contains("<sup>2..5</sup>"), + "expected <sup>2..5</sup>, got: {result}" + ); + assert!( + !result.contains(":"), + "unnamed range should not contain a colon" + ); + } + + #[test] + fn repeat_range_named_reference() { + // A RepeatRangeNamed renders as `<sup>n</sup>`. + let result = render(ExpressionKind::RepeatRangeNamed( + Box::new(Expression::new_kind(ExpressionKind::Nt("x".to_string()), 0)), + "n".to_string(), + )); + assert!( + result.contains("<sup>n</sup>"), + "expected <sup>n</sup>, got: {result}" + ); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_railroad.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_railroad.rs new file mode 100644 index 00000000..405e7e29 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/grammar/render_railroad.rs @@ -0,0 +1,809 @@ +//! Converts a [`Grammar`] to an SVG railroad diagram. + +use super::RenderCtx; +use crate::grammar::Grammar; +use anyhow::bail; +use grammar::{Character, Expression, ExpressionKind, Production, RangeLimit}; +use railroad::*; +use regex::Regex; +use std::fmt::Write; +use std::sync::LazyLock; + +/// Maximum number of rows per column in a `ExpressionKind::Alt`/`ExpressionKind::Charset` +const CHOICE_MAX_ROWS_PER_COLUMN: usize = 5; +/// Maximum number of columns in a `ExpressionKind::Alt`/`ExpressionKind::Charset`. Above that, we give up and +/// use as many rows as necessary +const CHOICE_MAX_COLUMNS: usize = 4; + +/// Returns the railroad stylesheets, scoped to their corresponding mdBook themes. +/// +/// mdBook selects a theme by placing its lowercase name on the root element. Scoping +/// each railroad stylesheet to that class lets the diagrams follow theme changes at +/// runtime without duplicating the styles in every SVG. +pub(super) fn themed_stylesheets() -> String { + const THEMES: [(&str, Stylesheet); 5] = [ + ("light", Stylesheet::Light), + ("rust", Stylesheet::Rust), + ("coal", Stylesheet::Coal), + ("navy", Stylesheet::Navy), + ("ayu", Stylesheet::Ayu), + ]; + + let mut css = String::new(); + for (theme, stylesheet) in THEMES { + let selector = format!(".{theme} svg.railroad"); + // Re-scope the selectors in each stylesheet, so they are scoped only to the selected theme + let scoped = stylesheet.stylesheet().replace("svg.railroad", &selector); + writeln!(css, "/* mdBook {theme} theme. */\n{scoped}").unwrap(); + } + css +} + +pub fn render_railroad( + grammar: &Grammar, + cx: &RenderCtx, + names: &[&str], + output: &mut String, +) -> anyhow::Result<()> { + for name in names { + let prod = match grammar.productions.get(*name) { + Some(p) => p, + None => bail!("could not find grammar production named `{name}`"), + }; + render_production(prod, cx, output); + } + Ok(()) +} + +/// The HTML id for the production. +pub fn railroad_id(name: &str, for_summary: bool) -> String { + if for_summary { + format!("railroad-summary-{}", name) + } else { + format!("railroad-{}", name) + } +} + +fn render_production(prod: &Production, cx: &RenderCtx, output: &mut String) { + let mut dia = make_diagram(prod, cx, false); + // If the diagram is very wide, try stacking it to reduce the width. + // This 900 is somewhat arbitrary based on looking at productions that + // looked too squished. If your diagram is still too squished, + // consider adding more rules to shorten it. + if dia.width() > 900 { + dia = make_diagram(prod, cx, true); + } + writeln!( + output, + "<div style=\"width: {width}px; height: auto; max-width: 100%; max-height: 100%\" \ + class=\"railroad-production\" \ + id=\"{id}\">{dia}</div>", + width = dia.width(), + id = railroad_id(&prod.name, cx.for_summary), + ) + .unwrap(); +} + +fn make_diagram(prod: &Production, cx: &RenderCtx, stack: bool) -> Diagram<Box<dyn Node>> { + let n = render_expression(&prod.expression, cx, stack); + let dest = cx + .md_link_map + .get(&prod.name) + .map(|path| path.to_string()) + .unwrap_or_else(|| format!("missing")); + let seq: Sequence<Box<dyn Node>> = + Sequence::new(vec![Box::new(SimpleStart), n.unwrap(), Box::new(SimpleEnd)]); + let vert = VerticalGrid::<Box<dyn Node>>::new(vec![ + Box::new(Link::new(Comment::new(prod.name.clone()), dest)), + Box::new(seq), + ]); + + Diagram::new(Box::new(vert)) +} + +fn render_expression(expr: &Expression, cx: &RenderCtx, stack: bool) -> Option<Box<dyn Node>> { + let mut state; + let mut state_ref = &expr.kind; + let n: Box<dyn Node> = 'l: loop { + state_ref = 'cont: { + break 'l match state_ref { + // Render grouped nodes and `e{1..1}` repeats directly. + ExpressionKind::Grouped(e) + | ExpressionKind::RepeatRange { + expr: e, + name: _, + min: Some(1), + max: Some(1), + limit: RangeLimit::Closed, + } => render_expression(e, cx, stack)?, + ExpressionKind::Alt(es) => { + let choices: Vec<_> = es + .iter() + .map(|e| render_expression(e, cx, stack)) + .filter_map(|n| n) + .collect(); + Box::new(bounded_multichoice(choices)) + } + ExpressionKind::Sequence(es) => { + let es: Vec<_> = es.iter().collect(); + let make_seq = |es: &[&Expression]| { + let seq: Vec<_> = es + .iter() + .map(|e| render_expression(e, cx, stack)) + .filter_map(|n| n) + .collect(); + if seq.is_empty() { + return None; + } + let seq: Sequence<Box<dyn Node>> = Sequence::new(seq); + Some(Box::new(seq)) + }; + + // If `stack` is true, split the sequence on Breaks and + // stack them vertically. + if stack { + // First, trim a Break from the front and back. + let es = if matches!( + es.first(), + Some(e) if e.is_break() + ) { + &es[1..] + } else { + &es[..] + }; + let es = if matches!( + es.last(), + Some(e) if e.is_break() + ) { + &es[..es.len() - 1] + } else { + &es[..] + }; + + let mut breaks: Vec<_> = es + .split(|e| e.is_break()) + .flat_map(|es| make_seq(es)) + .collect(); + // If there aren't any breaks, don't bother stacking. + match breaks.len() { + 0 => return None, + 1 => breaks.pop().unwrap(), + _ => Box::new(Stack::new(breaks)), + } + } else { + make_seq(&es)? + } + } + ExpressionKind::NegativeLookahead(e) => { + let forward = render_expression(e, cx, stack)?; + let lbox = + LabeledBox::new(forward, Comment::new("not followed by".to_string())); + Box::new(lbox) + } + // Treat `e?` and `e{..=1}` / `e{0..=1}` equally. + ExpressionKind::Optional(e) + | ExpressionKind::RepeatRange { + expr: e, + name: _, + min: None | Some(0), + max: Some(1), + limit: RangeLimit::Closed, + } => { + let n = render_expression(e, cx, stack)?; + Box::new(Optional::new(n)) + } + // Treat `e*` and `e{..}` / `e{0..}` equally. + ExpressionKind::Repeat(e) + | ExpressionKind::RepeatRange { + expr: e, + name: _, + min: None | Some(0), + max: None, + limit: RangeLimit::HalfOpen, + } => { + let n = render_expression(e, cx, stack)?; + Box::new(Optional::new(Repeat::new(n, railroad::Empty))) + } + // Treat `e+` and `e{1..}` equally. + ExpressionKind::RepeatPlus(e) + | ExpressionKind::RepeatRange { + expr: e, + name: _, + min: Some(1), + max: None, + limit: RangeLimit::HalfOpen, + } => { + let n = render_expression(e, cx, stack)?; + Box::new(Repeat::new(n, railroad::Empty)) + } + // For `e{..=0}` / `e{0..=0}` or `e{..1}` / `e{0..1}` render an empty node. + ExpressionKind::RepeatRange { max: Some(0), .. } + | ExpressionKind::RepeatRange { + max: Some(1), + limit: RangeLimit::HalfOpen, + .. + } => Box::new(railroad::Empty), + // Treat `e{..b}` / `e{0..b}` / `e{..=b}` / `e{0..=b}` as + // `(e{1..=b})?` (or `(e{1..b})?` for half-open). + ExpressionKind::RepeatRange { + expr: e, + name: _, + min: None | Some(0), + max: Some(b @ 2..), + limit, + } => { + state = ExpressionKind::Optional(Box::new(Expression::new_kind( + ExpressionKind::RepeatRange { + expr: e.clone(), + name: None, + min: Some(1), + max: Some(*b), + limit: *limit, + }, + 0, // Synthetic expression for rendering + ))); + break 'cont &state; + } + // Render `e{1..b}` / `e{1..=b}` directly. + ExpressionKind::RepeatRange { + expr: e, + name: _, + min: Some(1), + max: Some(b @ 2..), + limit, + } => { + let n = render_expression(e, cx, stack)?; + let more = match limit { + RangeLimit::HalfOpen => b - 2, + RangeLimit::Closed => b - 1, + }; + let cmt = format!("at most {more} more times"); + let r = Repeat::new(n, Comment::new(cmt)); + Box::new(r) + } + // A half-open range where min >= max is empty (e.g., + // `e{2..2}` means zero repetitions). + ExpressionKind::RepeatRange { + min: Some(a), + max: Some(b), + limit: RangeLimit::HalfOpen, + .. + } if b <= a => Box::new(railroad::Empty), + + // Decompose ranges with min >= 2 into a fixed prefix + // and a remainder: + // - `e{a..}` as `e{0..a-1} e{1..}` + // - `e{a..=b}` as `e{0..a-1} e{1..=b-(a-1)}` + // - `e{a..b}` as `e{0..a-1} e{1..b-(a-1)}` + ExpressionKind::RepeatRange { + expr: e, + name: _, + min: Some(a @ 2..), + max: b @ None, + limit, + } + | ExpressionKind::RepeatRange { + expr: e, + name: _, + min: Some(a @ 2..), + max: b @ Some(_), + limit, + } => { + let mut es = Vec::<Expression>::new(); + for _ in 0..(a - 1) { + es.push(*e.clone()); + } + es.push(Expression::new_kind( + ExpressionKind::RepeatRange { + expr: e.clone(), + name: None, + min: Some(1), + max: b.map(|x| x - (a - 1)), + limit: *limit, + }, + 0, + )); + state = ExpressionKind::Sequence(es); + break 'cont &state; + } + ExpressionKind::RepeatRange { + max: None, + limit: RangeLimit::Closed, + .. + } => unreachable!("closed range must have upper bound"), + ExpressionKind::RepeatRangeNamed(e, name) => { + let n = render_expression(e, cx, stack)?; + let cmt = format!("repeat exactly {name} times"); + let lbox = LabeledBox::new(n, Comment::new(cmt)); + Box::new(lbox) + } + ExpressionKind::Nt(nt) => node_for_nt(cx, nt), + ExpressionKind::Terminal(t) => Box::new(Terminal::new(t.clone())), + ExpressionKind::Prose(s) => Box::new(Terminal::new(s.clone())), + ExpressionKind::Break(_) => return None, + ExpressionKind::Comment(_) => return None, + ExpressionKind::Charset(set) => { + let choices: Vec<_> = set + .iter() + .map(|e| render_expression(e, cx, stack)) + .filter_map(|n| n) + .collect(); + Box::new(bounded_multichoice(choices)) + } + ExpressionKind::CharacterRange(start, end) => { + let mut s = String::new(); + let write_ch = |ch: &Character, output: &mut String| match ch { + Character::Char(ch) => output.push(*ch), + Character::Unicode((_, s)) => write!(output, "U+{s}").unwrap(), + }; + write_ch(start, &mut s); + s.push('-'); + write_ch(end, &mut s); + Box::new(Terminal::new(s)) + } + ExpressionKind::NegExpression(e) => { + let n = render_expression(e, cx, stack)?; + let ch = node_for_nt(cx, "CHAR"); + Box::new(Except::new(Box::new(ch), n)) + } + ExpressionKind::Cut(e) => { + let rhs = render_expression(e, cx, stack)?; + let lbox = LabeledBox::new(rhs, Comment::new("no backtracking".to_string())); + Box::new(lbox) + } + ExpressionKind::Unicode((_, s)) => Box::new(Terminal::new(format!("U+{}", s))), + }; + } + }; + // Wrap with a name label if this is a named RepeatRange. + let n = if let ExpressionKind::RepeatRange { + name: Some(ref name), + .. + } = expr.kind + { + let cmt = format!("repeat count {name}"); + let lbox = LabeledBox::new(n, Comment::new(cmt)); + Box::new(lbox) as Box<dyn Node> + } else { + n + }; + if let Some(suffix) = &expr.suffix { + let suffix = strip_markdown(suffix); + let lbox = LabeledBox::new(n, Comment::new(suffix)); + return Some(Box::new(lbox)); + } + // Note: Footnotes aren't supported. They could be added as a comment + // on a vertical stack or a LabeledBox or something like that, but I + // don't feel like bothering. + Some(n) +} + +fn bounded_multichoice(inp: Vec<Box<dyn Node>>) -> MultiChoice<Box<dyn Node>> { + let hard_max_columns = std::cmp::min( + CHOICE_MAX_COLUMNS, + inp.len().div_ceil(CHOICE_MAX_ROWS_PER_COLUMN), + ); + let soft_max_rows = inp.len().div_ceil(hard_max_columns); + let mut choices_iter = inp.into_iter(); + let groups = std::iter::from_fn(move || { + let group: Vec<_> = choices_iter.by_ref().take(soft_max_rows).collect(); + (!group.is_empty()).then_some(group) + }); + MultiChoice::new(groups.collect()) +} + +fn node_for_nt(cx: &RenderCtx, name: &str) -> Box<dyn Node> { + let dest = cx + .rr_link_map + .get(name) + .map(|path| path.to_string()) + .unwrap_or_else(|| format!("missing")); + let n = NonTerminal::new(name.to_string()); + Box::new(Link::new(n, dest)) +} + +/// Removes some markdown so it can be rendered as text. +fn strip_markdown(s: &str) -> String { + // Right now this just removes markdown linkifiers, but more can be added if needed. + static LINK_RE: LazyLock<Regex> = + LazyLock::new(|| Regex::new(r"(?s)\[([^\]]+)\](?:\[[^\]]*\]|\([^)]*\))?").unwrap()); + LINK_RE.replace_all(s, "$1").to_string() +} + +struct Except { + inner: LabeledBox<Box<dyn Node>, Box<dyn Node>>, +} + +impl Except { + fn new(inner: Box<dyn Node>, label: Box<dyn Node>) -> Self { + let grid = Box::new(VerticalGrid::new(vec![ + Box::new(Comment::new("⚠️ with the exception of".to_owned())) as Box<dyn Node>, + label, + ])) as Box<dyn Node>; + let mut this = Self { + inner: LabeledBox::new(inner, grid), + }; + this.inner + .attr("class".to_owned()) + .or_default() + .push_str(" exceptbox"); + this + } +} + +impl Node for Except { + fn entry_height(&self) -> i64 { + self.inner.entry_height() + } + + fn height(&self) -> i64 { + self.inner.height() + } + + fn width(&self) -> i64 { + self.inner.width() + } + + fn draw(&self, x: i64, y: i64, h_dir: svg::HDir) -> svg::Element { + self.inner.draw(x, y, h_dir) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use grammar::{Character, Expression, ExpressionKind, RangeLimit}; + + /// Render an expression to an SVG string fragment. + fn render_to_svg(expr: &Expression) -> Option<String> { + let cx = RenderCtx::for_test(); + let node = render_expression(expr, &cx, false)?; + let svg = node.draw(0, 0, svg::HDir::LTR); + Some(svg.to_string()) + } + + /// Build a `RepeatRange` expression wrapping a nonterminal `e`. + fn range_expr(min: Option<u32>, max: Option<u32>, limit: RangeLimit) -> Expression { + Expression::new_kind( + ExpressionKind::RepeatRange { + expr: Box::new(Expression::new_kind(ExpressionKind::Nt("e".to_string()), 0)), + name: None, + min, + max, + limit, + }, + 0, + ) + } + + #[test] + fn railroad_stylesheets_are_scoped_to_mdbook_themes() { + let css = themed_stylesheets(); + + for theme in ["light", "rust", "coal", "navy", "ayu"] { + assert!( + css.contains(&format!(".{theme} svg.railroad {{")), + "missing stylesheet for the {theme} theme" + ); + } + assert!( + css.lines() + .all(|line| !line.trim_start().starts_with("svg.railroad")), + "railroad styles must not leak into the other mdBook themes" + ); + } + + // -- RepeatRange tests -- + + #[test] + fn test_empty_exclusive_equal() { + // `e{2..2}` (half-open, min == max) renders as empty. + let expr = range_expr(Some(2), Some(2), RangeLimit::HalfOpen); + let svg = render_to_svg(&expr).unwrap(); + // An empty node produces a minimal SVG path with no + // nonterminal content. + assert!( + !svg.contains("nonterminal"), + "expected empty rendering for e{{2..2}}, got: {svg}" + ); + } + + #[test] + fn test_empty_inverted() { + // `e{3..1}` (half-open, max < min) renders as empty. + let expr = range_expr(Some(3), Some(1), RangeLimit::HalfOpen); + let svg = render_to_svg(&expr).unwrap(); + assert!( + !svg.contains("nonterminal"), + "expected empty rendering for e{{3..1}}, got: {svg}" + ); + } + + #[test] + fn test_closed_exact_one() { + // `e{1..=1}` renders as a single `e` (no repeat). + let expr = range_expr(Some(1), Some(1), RangeLimit::Closed); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("nonterminal"), + "expected nonterminal for e{{1..=1}}, got: {svg}" + ); + // Should not contain "more times" (no repeat comment). + assert!( + !svg.contains("more times"), + "e{{1..=1}} should not show a repeat comment" + ); + } + + #[test] + fn test_closed_range() { + // `e{2..=4}` renders with repeat indicators. + let expr = range_expr(Some(2), Some(4), RangeLimit::Closed); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("nonterminal"), + "expected nonterminal for e{{2..=4}}, got: {svg}" + ); + assert!( + svg.contains("more times"), + "e{{2..=4}} should show a repeat comment" + ); + } + + #[test] + fn test_closed_optional() { + // `e{..=1}` renders as optional. + let expr = range_expr(None, Some(1), RangeLimit::Closed); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("nonterminal"), + "expected nonterminal for e{{..=1}}, got: {svg}" + ); + } + + // -- Negative lookahead tests -- + + #[test] + fn lookahead_nonterminal() { + let expr = Expression::new_kind( + ExpressionKind::NegativeLookahead(Box::new(Expression::new_kind( + ExpressionKind::Nt("CHAR".to_string()), + 0, + ))), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("not followed by"), + "should contain the 'not followed by' label" + ); + assert!(svg.contains("CHAR"), "should contain the nonterminal name"); + } + + #[test] + fn lookahead_terminal() { + let expr = Expression::new_kind( + ExpressionKind::NegativeLookahead(Box::new(Expression::new_kind( + ExpressionKind::Terminal("CR".to_string()), + 0, + ))), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!(svg.contains("not followed by")); + assert!(svg.contains("CR")); + } + + #[test] + fn lookahead_charset() { + let expr = Expression::new_kind( + ExpressionKind::NegativeLookahead(Box::new(Expression::new_kind( + ExpressionKind::Charset(vec![ + Expression::new_kind(ExpressionKind::Terminal("e".to_string()), 0), + Expression::new_kind(ExpressionKind::Terminal("E".to_string()), 0), + ]), + 0, + ))), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!(svg.contains("not followed by")); + assert!(svg.contains("e")); + assert!(svg.contains("E")); + } + + // -- Unicode tests -- + + #[test] + fn unicode_4_digit() { + let expr = Expression::new_kind(ExpressionKind::Unicode(('\t', "0009".to_string())), 0); + let svg = render_to_svg(&expr).unwrap(); + assert!(svg.contains("U+0009"), "should render Unicode code point"); + } + + #[test] + fn unicode_6_digit() { + let expr = Expression::new_kind( + ExpressionKind::Unicode(('\u{10FFFF}', "10FFFF".to_string())), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!(svg.contains("U+10FFFF")); + } + + // -- Charset with ranges -- + + #[test] + fn charset_unicode_range() { + let expr = Expression::new_kind( + ExpressionKind::Charset(vec![Expression::new_kind( + ExpressionKind::CharacterRange( + Character::Unicode(('\0', "0000".to_string())), + Character::Unicode(('\u{007F}', "007F".to_string())), + ), + 0, + )]), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!(svg.contains("U+0000")); + assert!(svg.contains("U+007F")); + } + + #[test] + fn charset_char_range() { + let expr = Expression::new_kind( + ExpressionKind::Charset(vec![Expression::new_kind( + ExpressionKind::CharacterRange(Character::Char('a'), Character::Char('z')), + 0, + )]), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!(svg.contains("a")); + assert!(svg.contains("z")); + } + + // -- Cut test -- + + #[test] + fn cut_rendering() { + let expr = Expression::new_kind( + ExpressionKind::Cut(Box::new(Expression::new_kind( + ExpressionKind::Nt("Foo".to_string()), + 0, + ))), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("no backtracking"), + "cut should render with 'no backtracking' label" + ); + assert!(svg.contains("Foo")); + } + + // -- NegExpression test -- + + #[test] + fn neg_expression_rendering() { + let expr = Expression::new_kind( + ExpressionKind::NegExpression(Box::new(Expression::new_kind( + ExpressionKind::Charset(vec![Expression::new_kind( + ExpressionKind::Terminal("a".to_string()), + 0, + )]), + 0, + ))), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("with the exception of"), + "neg expression should have exception label" + ); + } + + // -- Named repeat range tests -- + + #[test] + fn repeat_range_named_reference() { + // RepeatRangeNamed renders with a "repeat exactly n times" + // label. + let expr = Expression::new_kind( + ExpressionKind::RepeatRangeNamed( + Box::new(Expression::new_kind(ExpressionKind::Nt("x".to_string()), 0)), + "n".to_string(), + ), + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("repeat exactly n times"), + "expected 'repeat exactly n times' label, got: {svg}" + ); + } + + #[test] + fn repeat_range_with_name_renders() { + // A named RepeatRange should display the name as a label. + let expr = Expression::new_kind( + ExpressionKind::RepeatRange { + expr: Box::new(Expression::new_kind(ExpressionKind::Nt("e".to_string()), 0)), + name: Some("n".to_string()), + min: Some(2), + max: Some(5), + limit: RangeLimit::Closed, + }, + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("repeat count n"), + "expected 'repeat count n' label, got: {svg}" + ); + } + + #[test] + fn repeat_range_with_name_optional() { + // `e{k:0..=5}` decomposes to Optional(RepeatRange). The + // name label should still appear on the outermost node. + let expr = Expression::new_kind( + ExpressionKind::RepeatRange { + expr: Box::new(Expression::new_kind(ExpressionKind::Nt("e".to_string()), 0)), + name: Some("k".to_string()), + min: Some(0), + max: Some(5), + limit: RangeLimit::Closed, + }, + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("repeat count k"), + "expected 'repeat count k' label, got: {svg}" + ); + } + + #[test] + fn repeat_range_without_name_no_label() { + // An unnamed RepeatRange should not have a "repeat count" + // label. + let expr = Expression::new_kind( + ExpressionKind::RepeatRange { + expr: Box::new(Expression::new_kind(ExpressionKind::Nt("e".to_string()), 0)), + name: None, + min: Some(2), + max: Some(5), + limit: RangeLimit::Closed, + }, + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + !svg.contains("repeat count"), + "unnamed range should not have a 'repeat count' label" + ); + } + + #[test] + fn repeat_range_with_name_identity() { + // `e{n:1..=1}` renders as plain `e` but should still + // display the name label. + let expr = Expression::new_kind( + ExpressionKind::RepeatRange { + expr: Box::new(Expression::new_kind(ExpressionKind::Nt("e".to_string()), 0)), + name: Some("n".to_string()), + min: Some(1), + max: Some(1), + limit: RangeLimit::Closed, + }, + 0, + ); + let svg = render_to_svg(&expr).unwrap(); + assert!( + svg.contains("repeat count n"), + "expected 'repeat count n' label on identity range" + ); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/lib.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/lib.rs new file mode 100644 index 00000000..b94d2969 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/lib.rs @@ -0,0 +1,211 @@ +#![deny(rust_2018_idioms, unused_lifetimes)] + +use crate::rules::Rules; +use anyhow::{Context, Result, bail}; +use diagnostics::{Diagnostics, warn_or_err}; +use mdbook_preprocessor::book::{Book, BookItem, Chapter}; +use mdbook_preprocessor::errors::Error; +use mdbook_preprocessor::{Preprocessor, PreprocessorContext}; +use once_cell::sync::Lazy; +use regex::{Captures, Regex}; +use semver::{Version, VersionReq}; +use std::io; +use std::ops::Range; +use std::path::PathBuf; + +mod admonitions; +mod grammar; +mod rules; +mod std_links; +mod test_links; + +/// A primitive regex to find link reference definitions. +static MD_LINK_REFERENCE_DEFINITION: Lazy<Regex> = + Lazy::new(|| Regex::new(r"(?m)^\[(?<label>[^]]+)]: +(?<dest>.*)").unwrap()); + +pub fn handle_preprocessing() -> Result<(), Error> { + let pre = Spec::new(None)?; + let (ctx, book) = mdbook_preprocessor::parse_input(io::stdin())?; + + let book_version = Version::parse(&ctx.mdbook_version)?; + let version_req = VersionReq::parse(mdbook_preprocessor::MDBOOK_VERSION)?; + + if !version_req.matches(&book_version) { + eprintln!( + "warning: The {} plugin was built against version {} of mdbook, \ + but we're being called from version {}", + pre.name(), + mdbook_preprocessor::MDBOOK_VERSION, + ctx.mdbook_version + ); + } + + let processed_book = pre.run(&ctx, book)?; + serde_json::to_writer(io::stdout(), &processed_book)?; + + Ok(()) +} + +pub struct Spec { + /// Path to the rust-lang/rust git repository (set by SPEC_RUST_ROOT + /// environment variable). + rust_root: Option<PathBuf>, +} + +impl Spec { + /// Creates a new `Spec` preprocessor. + /// + /// The `rust_root` parameter specifies an optional path to the root of + /// the rust git checkout. If `None`, it will use the `SPEC_RUST_ROOT` + /// environment variable. If the root is not specified, then no tests will + /// be linked unless `SPEC_DENY_WARNINGS` is set in which case this will + /// return an error. + pub fn new(rust_root: Option<PathBuf>) -> Result<Spec> { + let rust_root = rust_root.or_else(|| std::env::var_os("SPEC_RUST_ROOT").map(PathBuf::from)); + Ok(Spec { rust_root }) + } + + /// Converts link reference definitions that point to a rule to the correct link. + /// + /// For example: + /// ```markdown + /// See [this rule]. + /// + /// [this rule]: expr.array + /// ``` + /// + /// This will convert the `[this rule]` definition to point to the actual link. + fn rule_link_references(&self, chapter: &Chapter, rules: &Rules) -> String { + let current_path = chapter.path.as_ref().unwrap().parent().unwrap(); + MD_LINK_REFERENCE_DEFINITION + .replace_all(&chapter.content, |caps: &Captures<'_>| { + let dest = &caps["dest"]; + if let Some((_source_path, path)) = rules.def_paths.get(dest) { + let label = &caps["label"]; + let relative = pathdiff::diff_paths(path, current_path).unwrap(); + // Adjust paths for Windows. + let relative = relative.display().to_string().replace('\\', "/"); + format!("[{label}]: {relative}#r-{dest}") + } else { + caps.get(0).unwrap().as_str().to_string() + } + }) + .to_string() + } + + /// Generates link references to all rules on all pages, so you can easily + /// refer to rules anywhere in the book. + fn auto_link_references(&self, chapter: &Chapter, rules: &Rules) -> String { + let current_path = chapter.path.as_ref().unwrap().parent().unwrap(); + let definitions: String = rules + .def_paths + .iter() + .map(|(rule_id, (_, path))| { + let relative = pathdiff::diff_paths(path, current_path).unwrap(); + // Adjust paths for Windows. + let relative = relative.display().to_string().replace('\\', "/"); + format!("[{rule_id}]: {}#r-{rule_id}\n", relative) + }) + .collect(); + format!( + "{}\n\ + {definitions}", + chapter.content + ) + } +} + +/// Determines the git ref used for linking to a particular branch/tag in GitHub. +fn git_ref(rust_root: &Option<PathBuf>) -> Result<String> { + let Some(rust_root) = rust_root else { + return Ok("main".into()); + }; + let channel = std::fs::read_to_string(rust_root.join("src/ci/channel")) + .context("failed to read src/ci/channel")?; + let git_ref = match channel.trim() { + // nightly/beta are branches, not stable references. Should be ok + // because we're not expecting those channels to be long-lived. + "nightly" => "main".into(), + "beta" => "beta".into(), + "stable" => { + let version = std::fs::read_to_string(rust_root.join("src/version")) + .context("|| failed to read src/version")?; + version.trim().into() + } + ch => bail!("unknown channel {ch}"), + }; + Ok(git_ref) +} + +impl Preprocessor for Spec { + fn name(&self) -> &str { + "spec" + } + + fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<Book, Error> { + let mut diag = Diagnostics::new(); + if diag.deny_warnings && self.rust_root.is_none() { + bail!("error: SPEC_RUST_ROOT environment variable must be set"); + } + let grammar = ::grammar::load_grammar(&mut diag); + let rules = self.collect_rules(&book, &mut diag); + let tests = self.collect_tests(&rules); + let summary_table = test_links::make_summary_table(&book, &tests, &rules); + let git_ref = match git_ref(&self.rust_root) { + Ok(s) => s, + Err(e) => { + warn_or_err!(&mut diag, "{e:?}"); + "main".into() + } + }; + + book.for_each_mut(|item| { + let BookItem::Chapter(ch) = item else { + return; + }; + if ch.is_draft_chapter() { + return; + } + ch.content = admonitions::admonitions(&ch, &mut diag); + ch.content = self.rule_link_references(&ch, &rules); + ch.content = grammar::grammar_link_references(&ch, &grammar); + ch.content = self.auto_link_references(&ch, &rules); + ch.content = self.render_rule_definitions(&ch.content, &tests, &git_ref); + if ch.name == "Test summary" { + ch.content = ch.content.replace("{{summary-table}}", &summary_table); + } + if grammar::is_summary(ch) { + ch.content = grammar::insert_summary(&grammar, &ch, &mut diag); + } + ch.content = grammar::insert_grammar(&grammar, &ch, &mut diag); + }); + + // Final pass will resolve everything as a std link (or error if the + // link is unknown). + std_links::std_links(&mut book, &mut diag); + + if diag.count > 0 { + if diag.deny_warnings { + eprintln!("mdbook-spec exiting due to {} errors", diag.count); + std::process::exit(1); + } + eprintln!("mdbook-spec generated {} warnings", diag.count); + } + + Ok(book) + } +} + +fn line_from_range<'a>(contents: &'a str, range: &Range<usize>) -> &'a str { + assert!(range.start < contents.len()); + + let mut start_index = 0; + for line in contents.lines() { + let end_index = start_index + line.len(); + if range.start >= start_index && range.start <= end_index { + return line; + } + start_index = end_index + 1; + } + panic!("did not find line {range:?} in contents"); +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/main.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/main.rs new file mode 100644 index 00000000..83ac8304 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/main.rs @@ -0,0 +1,19 @@ +fn main() { + let mut args = std::env::args().skip(1); + match args.next().as_deref() { + Some("supports") => { + // Supports all renderers. + return; + } + Some(arg) => { + eprintln!("unknown argument: {arg}"); + std::process::exit(1); + } + None => {} + } + + if let Err(e) = mdbook_spec::handle_preprocessing() { + eprintln!("{}", e); + std::process::exit(1); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/rules.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/rules.rs new file mode 100644 index 00000000..4bfec06b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/rules.rs @@ -0,0 +1,118 @@ +//! Handling for rule identifiers. + +use crate::test_links::RuleToTests; +use crate::{Diagnostics, Spec, warn_or_err}; +use mdbook_preprocessor::book::{Book, BookItem}; +use once_cell::sync::Lazy; +use regex::{Captures, Regex}; +use std::collections::{BTreeMap, HashSet}; +use std::fmt::Write; +use std::path::PathBuf; + +/// The Regex for rules like `r[foo]`. +static RULE_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?m)^r\[([^]]+)]$").unwrap()); + +/// The set of rules defined in the reference. +#[derive(Default)] +pub struct Rules { + /// A mapping from a rule identifier to a tuple of `(source_path, path)`. + /// + /// `source_path` is the path to the markdown source file relative to the + /// `SUMMARY.md`. + /// + /// `path` is the same as `source_path`, except filenames like `README.md` + /// are translated to `index.md`. Which to use depends on if you are + /// trying to access the source files (`source_path`), or creating links + /// in the output (`path`). + pub def_paths: BTreeMap<String, (PathBuf, PathBuf)>, + /// Set of rule name prefixes that have more specific rules within. + /// + /// For example, `asm.ts-args` is an interior prefix of `asm.ts-args.syntax`. + pub interior_prefixes: HashSet<String>, +} + +impl Spec { + /// Collects all rule definitions in the book. + pub fn collect_rules(&self, book: &Book, diag: &mut Diagnostics) -> Rules { + let mut rules = Rules::default(); + for item in book.iter() { + let BookItem::Chapter(ch) = item else { + continue; + }; + if ch.is_draft_chapter() { + continue; + } + RULE_RE + .captures_iter(&ch.content) + .for_each(|caps: Captures<'_>| { + let rule_id = &caps[1]; + let source_path = ch.source_path.clone().unwrap_or_default(); + let path = ch.path.clone().unwrap_or_default(); + if let Some((old, _)) = rules + .def_paths + .insert(rule_id.to_string(), (source_path.clone(), path.clone())) + { + warn_or_err!( + diag, + "rule `{rule_id}` defined multiple times\n\ + First location: {old:?}\n\ + Second location: {source_path:?}" + ); + } + let mut parts: Vec<_> = rule_id.split('.').collect(); + while !parts.is_empty() { + parts.pop(); + let prefix = parts.join("."); + rules.interior_prefixes.insert(prefix); + } + }); + } + + rules + } + + /// Converts lines that start with `r[…]` into a "rule" which has special + /// styling and can be linked to. + pub fn render_rule_definitions( + &self, + content: &str, + tests: &RuleToTests, + git_ref: &str, + ) -> String { + RULE_RE + .replace_all(content, |caps: &Captures<'_>| { + let rule_id = &caps[1]; + let mut test_link = String::new(); + let mut test_popup = String::new(); + if let Some(tests) = tests.get(rule_id) { + test_link = format!( + "<br><div class=\"test-link\">\n\ + <a href=\"javascript:void(0)\" onclick=\"spec_toggle_tests('{rule_id}');\">\ + <span>Tests</span></a></div>\n"); + test_popup = format!( + "<div id=\"tests-{rule_id}\" class=\"tests-popup popup-hidden\">\n\ + Tests with this rule:\n\ + <ul>"); + for test in tests { + writeln!( + test_popup, + "<li><a href=\"https://github.com/rust-lang/rust/blob/{git_ref}/{test_path}\">{test_path}</a></li>", + test_path = test.path, + ) + .unwrap(); + } + + test_popup.push_str("</ul></div>"); + } + format!( + "<div class=\"rule\" id=\"r-{rule_id}\">\ + <a class=\"rule-link\" href=\"#r-{rule_id}\" title=\"{rule_id}\"><span>[{rule_id_broken}]</span></a>\n\ + {test_link}\ + </div>\n\ + {test_popup}\n", + rule_id_broken = rule_id.replace(".", "<wbr>."), + ) + }) + .to_string() + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/std_links.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/std_links.rs new file mode 100644 index 00000000..fca700cc --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/std_links.rs @@ -0,0 +1,358 @@ +//! Support for translating links to the standard library. + +use anyhow::{Result, bail}; +use diagnostics::{Diagnostics, bug, warn_or_err}; +use mdbook_markdown::pulldown_cmark::{BrokenLink, CowStr, Event, LinkType, Options, Parser, Tag}; +use mdbook_preprocessor::book::BookItem; +use mdbook_preprocessor::book::{Book, Chapter}; +use once_cell::sync::Lazy; +use regex::Regex; +use std::collections::HashMap; +use std::fmt::Write as _; +use std::fs; +use std::ops::Range; +use std::path::PathBuf; +use std::process::Command; +use tempfile::TempDir; + +/// The Regex used to extract the std links from the HTML generated by rustdoc. +static STD_LINK_EXTRACT_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r#"<li>LINK: (.*)</li>"#).unwrap()); + +/// The Regex used to extract the URL from an HTML link. +static ANCHOR_URL: Lazy<Regex> = Lazy::new(|| Regex::new("<a href=\"([^\"]+)\"").unwrap()); + +/// Regex for a markdown inline link, like `[foo](bar)`. +static MD_LINK_INLINE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?s)(\[.+\])(\(.+\))").unwrap()); +/// Regex for a markdown reference link, like `[foo][bar]`. +static MD_LINK_REFERENCE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?s)(\[.+\])(\[.*\])").unwrap()); +/// Regex for a markdown shortcut link, like `[foo]`. +static MD_LINK_SHORTCUT: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?s)(\[.+\])").unwrap()); + +/// Converts links to the standard library to the online documentation in a +/// fashion similar to rustdoc intra-doc links. +pub fn std_links(book: &mut Book, diag: &mut Diagnostics) { + // Collect all links in all chapters. + let mut chapter_links = HashMap::new(); + for item in book.iter() { + let BookItem::Chapter(ch) = item else { + continue; + }; + if ch.is_draft_chapter() { + continue; + } + let key = ch.source_path.as_ref().unwrap(); + chapter_links.insert(key, collect_markdown_links(&ch, diag)); + } + // Write a Rust source file to use with rustdoc to generate intra-doc links. + let tmp = TempDir::with_prefix("mdbook-spec-").unwrap(); + if let Err(e) = run_rustdoc(&tmp, &chapter_links, diag) { + warn_or_err!(diag, "{e:?}"); + return; + } + + // Extract the links from the generated html. + let generated = fs::read_to_string(tmp.path().join("doc/a/index.html")) + .expect("index.html failed to generate"); + let mut urls: Vec<_> = STD_LINK_EXTRACT_RE + .captures_iter(&generated) + .map(|cap| cap.get(1).unwrap().as_str()) + .collect(); + let mut urls = &mut urls[..]; + let expected_len: usize = chapter_links.values().map(|l| l.len()).sum(); + if urls.len() != expected_len { + bug!( + "expected rustdoc to generate {} links, but found {}", + expected_len, + urls.len(), + ); + } + // Unflatten the urls list so that it is split back by chapter. + let mut ch_urls: HashMap<&PathBuf, Vec<_>> = HashMap::new(); + for (ch_path, links) in &chapter_links { + let xs; + (xs, urls) = urls.split_at_mut(links.len()); + ch_urls.insert(ch_path, xs.into()); + } + + // Do this in two passes to deal with lifetimes. + let mut ch_contents = HashMap::new(); + for item in book.iter() { + let BookItem::Chapter(ch) = item else { + continue; + }; + if ch.is_draft_chapter() { + continue; + } + let key = ch.source_path.as_ref().unwrap(); + // Create a list of replacements to make in the raw markdown to point to the new url. + let replacements = compute_replacements(&ch, &chapter_links[key], &ch_urls[key], diag); + + let mut new_contents = ch.content.clone(); + for (md_link, url, range) in replacements { + // Convert links to be relative so that links work offline and + // with the linkchecker. + let url = relative_url(url, ch); + // Note that this may orphan reference link definitions. This should + // probably remove them, but pulldown_cmark doesn't give the span for + // the reference definition. + new_contents.replace_range(range, &format!("{md_link}({url})")); + } + ch_contents.insert(key.clone(), new_contents); + } + + // Replace the content with the new content. + book.for_each_mut(|item| { + let BookItem::Chapter(ch) = item else { + return; + }; + if ch.is_draft_chapter() { + return; + } + let key = ch.source_path.as_ref().unwrap(); + let content = ch_contents.remove(key).unwrap(); + ch.content = content; + }); +} + +#[derive(Debug)] +struct Link<'a> { + link_type: LinkType, + /// Where the link is going to, for example `std::ffi::OsString`. + dest_url: CowStr<'a>, + /// The span in the original markdown where the link is located. + /// + /// Note that this is the post-processed markdown (such as having rules + /// expanded), not the markdown on the disk. + /// + /// Note that during translation, all links will be converted to inline + /// links. That means that for reference-style links, the link reference + /// definition will end up being ignored in the final markdown. For + /// example, a link like ``[`OsString`]`` with a definition + /// ``[`OsString`]: std::ffi::OsString`` will convert the link to + /// ``[`OsString`](https://doc.rust-lang.org/std/ffi/struct.OsString.html)`. + range: Range<usize>, +} + +/// Collects all markdown links that look like they might be standard library links. +fn collect_markdown_links<'a>(chapter: &'a Chapter, diag: &mut Diagnostics) -> Vec<Link<'a>> { + let mut opts = Options::empty(); + opts.insert(Options::ENABLE_TABLES); + opts.insert(Options::ENABLE_FOOTNOTES); + opts.insert(Options::ENABLE_STRIKETHROUGH); + opts.insert(Options::ENABLE_TASKLISTS); + opts.insert(Options::ENABLE_HEADING_ATTRIBUTES); + opts.insert(Options::ENABLE_SMART_PUNCTUATION); + + let mut broken_links = Vec::new(); + let mut links = Vec::new(); + + // Broken links are collected so that you can write something like + // `[std::option::Option]` which in pulldown_cmark's eyes is a broken + // link. However, that is the normal syntax for rustdoc. + let broken_link = |broken_link: BrokenLink<'_>| { + broken_links.push(Link { + link_type: broken_link.link_type, + // Necessary due to lifetime issues. + dest_url: CowStr::Boxed(broken_link.reference.into_string().into()), + range: broken_link.span.clone(), + }); + None + }; + + let parser = Parser::new_with_broken_link_callback(&chapter.content, opts, Some(broken_link)) + .into_offset_iter(); + for (event, range) in parser { + match event { + Event::Start(Tag::Link { + link_type, + dest_url, + title, + id: _, + }) => { + // Only collect links that are for the standard library. + if matches!(link_type, LinkType::Autolink | LinkType::Email) { + continue; + } + if dest_url.starts_with("http") + || dest_url.contains(".md") + || dest_url.contains(".html") + || dest_url.starts_with('#') + { + continue; + } + if !title.is_empty() { + warn_or_err!( + diag, + "titles in links are not supported\n\ + Link {dest_url} has title `{title}` found in chapter {} ({:?})", + chapter.name, + chapter.source_path.as_ref().unwrap() + ); + } + links.push(Link { + link_type, + dest_url, + range: range.clone(), + }); + } + _ => {} + } + } + links.extend(broken_links); + links +} + +/// Generates links using rustdoc. +/// +/// This takes the given links and creates a temporary Rust source file +/// containing those links within doc-comments, and then runs rustdoc to +/// generate intra-doc links on them. +/// +/// The output will be in the given `tmp` directory. +fn run_rustdoc( + tmp: &TempDir, + chapter_links: &HashMap<&PathBuf, Vec<Link<'_>>>, + diag: &mut Diagnostics, +) -> Result<()> { + let src_path = tmp.path().join("a.rs"); + // Allow redundant since there could some in-scope things that are + // technically not necessary, but we don't care about (like + // [`Option`](std::option::Option)). + let mut src = format!( + "#![{}(rustdoc::broken_intra_doc_links)]\n\ + #![allow(rustdoc::redundant_explicit_links)]\n", + if diag.deny_warnings { "deny" } else { "warn" } + ); + // This uses a list to make easy to pull the links out of the generated HTML. + for (_ch_path, links) in chapter_links { + for link in links { + match link.link_type { + LinkType::Inline + | LinkType::Reference + | LinkType::Collapsed + | LinkType::Shortcut => { + writeln!(src, "//! - LINK: [{}]", link.dest_url).unwrap(); + } + LinkType::ReferenceUnknown + | LinkType::CollapsedUnknown + | LinkType::ShortcutUnknown => { + // These should only happen due to broken link replacements. + bug!("unexpected link type unknown {link:?}"); + } + LinkType::Autolink | LinkType::Email => { + bug!("link type should have been filtered {link:?}"); + } + LinkType::WikiLink { .. } => panic!("unsupported wikilink"), + } + } + } + // Put some common things into scope so that links to them work. + writeln!( + src, + "extern crate alloc;\n\ + extern crate proc_macro;\n\ + extern crate test;\n" + ) + .unwrap(); + fs::write(&src_path, &src).unwrap(); + let rustdoc = std::env::var("RUSTDOC").unwrap_or_else(|_| "rustdoc".into()); + let output = Command::new(rustdoc) + .arg("--edition=2024") + .arg(&src_path) + .current_dir(tmp.path()) + .output() + .expect("rustdoc installed"); + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + bail!( + "failed to extract std links ({:?})\n{stderr}", + output.status + ); + } + Ok(()) +} + +static DOC_URL: Lazy<Regex> = Lazy::new(|| { + Regex::new(r"^https://doc.rust-lang.org/(?:nightly|beta|stable|dev|1\.[0-9]+\.[0-9]+)").unwrap() +}); + +/// Converts a URL to doc.rust-lang.org to be relative. +fn relative_url(url: &str, chapter: &Chapter) -> String { + // Set SPEC_RELATIVE=0 to disable this, which can be useful for working locally. + if std::env::var("SPEC_RELATIVE").as_deref() != Ok("0") { + let Some(url_start) = DOC_URL.shortest_match(url) else { + bug!("expected rustdoc URL to start with {DOC_URL:?}, got {url}"); + }; + let url_path = &url[url_start..]; + let num_dots = chapter.path.as_ref().unwrap().components().count(); + let dots = vec![".."; num_dots].join("/"); + format!("{dots}{url_path}") + } else { + url.to_string() + } +} + +/// Computes the replacements to make in the markdown content. +/// +/// Returns a `Vec` of `(md_link, url, range)` where: +/// +/// - `md_link` is the markdown link string to show to the user (like `[foo]`). +/// - `url` is the URL to the standard library. +/// - `range` is the range in the original markdown to replace with the new link. +fn compute_replacements<'a>( + chapter: &'a Chapter, + links: &[Link<'_>], + urls: &[&'a str], + diag: &mut Diagnostics, +) -> Vec<(&'a str, &'a str, Range<usize>)> { + let mut replacements = Vec::new(); + + for (url, link) in urls.iter().zip(links) { + let Some(cap) = ANCHOR_URL.captures(url) else { + let line = super::line_from_range(&chapter.content, &link.range); + warn_or_err!( + diag, + "broken markdown link found in {}\n\ + Line is: {line}\n\ + Link to `{}` could not be resolved by rustdoc to a known URL (result was `{}`).\n", + chapter.source_path.as_ref().unwrap().display(), + link.dest_url, + url + ); + continue; + }; + let url = cap.get(1).unwrap().as_str(); + let md_link = &chapter.content[link.range.clone()]; + + let range = link.range.clone(); + let add_link = |re: &Regex| { + let Some(cap) = re.captures(md_link) else { + bug!( + "expected link `{md_link}` of type {:?} to match regex {re}", + link.link_type + ); + }; + let md_link = cap.get(1).unwrap().as_str(); + replacements.push((md_link, url, range)); + }; + + match link.link_type { + LinkType::Inline => { + add_link(&MD_LINK_INLINE); + } + LinkType::Reference | LinkType::Collapsed => { + add_link(&MD_LINK_REFERENCE); + } + LinkType::Shortcut => { + add_link(&MD_LINK_SHORTCUT); + } + _ => { + bug!("unexpected link type: {link:#?}"); + } + } + } + // Sort and reverse (so that it can replace bottom-up so ranges don't shift). + replacements.sort_by(|a, b| b.2.clone().partial_cmp(a.2.clone()).unwrap()); + replacements +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/test_links.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/test_links.rs new file mode 100644 index 00000000..3f105c3b --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/mdbook-spec/src/test_links.rs @@ -0,0 +1,203 @@ +//! Handling for linking tests in rust's testsuite to rule identifiers. + +use crate::{Rules, Spec}; +use mdbook_preprocessor::book::{Book, BookItem}; +use std::collections::HashMap; +use std::fmt::Write; +use std::path::PathBuf; +use walkdir::WalkDir; + +/// Mapping of rule identifier to the tests that include that identifier. +pub type RuleToTests = HashMap<String, Vec<Test>>; +/// A test in rustc's test suite. +pub struct Test { + pub path: String, +} + +const TABLE_START: &str = " +<table> +<tr> + <th></th> + <th>Rules</th> + <th>Tests</th> + <th>Uncovered Rules</th> + <th>Coverage</th> +</tr> +"; + +/// Generates an HTML table summarizing the coverage of the testsuite. +pub fn make_summary_table(book: &Book, tests: &RuleToTests, rules: &Rules) -> String { + let ch_to_rules = invert_rule_map(rules); + + let mut table = String::from(TABLE_START); + let mut total_rules = 0; + let mut total_tests = 0; + let mut total_uncovered = 0; + + for (item_index, item) in book.iter().enumerate() { + let BookItem::Chapter(ch) = item else { + continue; + }; + let Some(ch_path) = &ch.path else { + continue; + }; + let level = ch + .number + .as_ref() + .map(|ch| ch.len() - 1) + .unwrap_or_default() as u32; + // Note: This path assumes that the summary chapter is in the root of + // the book. If instead it is in a subdirectory, then this needs to + // include relative `../` as needed. + let html_path = ch_path + .with_extension("html") + .to_str() + .unwrap() + .replace('\\', "/"); + let number = ch + .number + .as_ref() + .map(|n| n.to_string()) + .unwrap_or_default(); + let mut num_rules = 0; + let mut num_tests_str = String::from(""); + let mut uncovered_str = String::from(""); + let mut coverage_str = String::from(""); + if let Some(rules) = ch_to_rules.get(ch_path) { + num_rules = rules.len(); + total_rules += num_rules; + let num_tests = rules + .iter() + .map(|rule| tests.get(rule).map(|ts| ts.len()).unwrap_or_default()) + .sum::<usize>(); + total_tests += num_tests; + num_tests_str = num_tests.to_string(); + let uncovered_rules: Vec<_> = rules + .iter() + .filter(|rule| !tests.contains_key(rule.as_str())) + .collect(); + let uncovered = uncovered_rules.len(); + total_uncovered += uncovered; + coverage_str = fmt_pct(uncovered, num_rules); + if uncovered == 0 { + uncovered_str = String::from("0"); + } else { + uncovered_str = format!( + "<div class=\"popup-container\">\n\ + <a href=\"javascript:void(0)\" onclick=\"spec_toggle_uncovered({item_index});\">\ + {uncovered}</a>\n\ + <div id=\"uncovered-{item_index}\" class=\"uncovered-rules-popup popup-hidden\">\n\ + Uncovered rules + <ul>"); + for uncovered_rule in uncovered_rules { + writeln!( + uncovered_str, + "<li><a href=\"{html_path}#r-{uncovered_rule}\">{uncovered_rule}</a></li>" + ) + .unwrap(); + } + uncovered_str.push_str("</ul></div></div>"); + } + } + let indent = " ".repeat(level as usize * 6); + + writeln!( + table, + "<tr>\n\ + <td><a href=\"{html_path}\">{indent}{number} {name}</a></td>\n\ + <td>{num_rules}</td>\n\ + <td>{num_tests_str}</td>\n\ + <td>{uncovered_str}</td>\n\ + <td>{coverage_str}</td>\n\ + </tr>", + name = ch.name, + ) + .unwrap(); + } + + let total_coverage = fmt_pct(total_uncovered, total_rules); + writeln!( + table, + "<tr>\n\ + <td><b>Total:</b></td>\n\ + <td>{total_rules}</td>\n\ + <td>{total_tests}</td>\n\ + <td>{total_uncovered}</td>\n\ + <td>{total_coverage}</td>\n\ + </tr>" + ) + .unwrap(); + table.push_str("</table>\n"); + table +} + +/// Formats a float as a percentage string. +fn fmt_pct(uncovered: usize, total: usize) -> String { + let pct = ((total - uncovered) as f32 / total as f32) * 100.0; + // Round up to tenths of a percent. + let x = (pct * 10.0).ceil() / 10.0; + format!("{x:.1}%") +} + +/// Inverts the rule map so that it is chapter path to set of rules in that +/// chapter. +fn invert_rule_map(rules: &Rules) -> HashMap<PathBuf, Vec<String>> { + let mut map: HashMap<PathBuf, Vec<String>> = HashMap::new(); + for (rule, (_, path)) in &rules.def_paths { + map.entry(path.clone()).or_default().push(rule.clone()); + } + for value in map.values_mut() { + value.sort(); + } + map +} + +impl Spec { + /// Scans all tests in rust-lang/rust, and creates a mapping of a rule + /// identifier to the set of tests that include that identifier. + pub fn collect_tests(&self, rules: &Rules) -> RuleToTests { + let mut map = HashMap::new(); + let Some(rust_root) = &self.rust_root else { + return map; + }; + for entry in WalkDir::new(rust_root.join("tests")) { + let entry = entry.unwrap(); + let path = entry.path(); + let relative = path.strip_prefix(rust_root).unwrap_or_else(|_| { + panic!("expected root {rust_root:?} to be a prefix of {path:?}") + }); + if path.extension().unwrap_or_default() == "rs" { + let contents = std::fs::read_to_string(path).unwrap(); + for line in contents.lines() { + if let Some(id) = line.strip_prefix("//@ reference: ") { + if rules.interior_prefixes.contains(id) { + let instead: Vec<_> = rules + .def_paths + .keys() + .filter(|key| key.starts_with(&format!("{id}."))) + .collect(); + eprintln!( + "info: Interior prefix rule {id} found in {path:?}\n \ + Tests should not be annotated with prefixed rule names.\n \ + Use the rules from {instead:?} instead." + ); + } else if !rules.def_paths.contains_key(id) { + eprintln!( + "info: Orphaned rule identifier {id} found in {path:?}\n \ + Please update the test to use an existing rule name." + ); + } + let test = Test { + path: relative.to_str().unwrap().replace('\\', "/"), + }; + map.entry(id.to_string()).or_default().push(test); + } + } + } + } + for tests in map.values_mut() { + tests.sort_by(|a, b| a.path.cmp(&b.path)); + } + map + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/Cargo.toml new file mode 100644 index 00000000..4d01e982 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "parser" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +diagnostics = { path = "../diagnostics" } +grammar = { path = "../grammar" } +tracing = "0.1.43" +tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } +tracing-tree = "0.4.1" +unicode-ident = "1.0.22" diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/README.md b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/README.md new file mode 100644 index 00000000..828ad183 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/README.md @@ -0,0 +1,25 @@ +# Reference grammar parser + +This is a primitive interpreter that parses an input using the Reference grammar and can generate tokens or a generic tree representation of that source. + +## Overview + +The parser itself is fairly straightforward as it uses the Reference productions to drive an interpreter to parse some input into a tree of nodes. + +There are some hard-coded handlers for some of the English-based rules such as the suffixes. Ideally the grammar should be changed to remove those and use parseable expressions (like negative lookahead). + +## To lex or not to lex + +The tooling is currently designed to keep lexing separate from parsing. I'm still uncertain if this is the right thing to do. It adds some complexity. For example, the parser has a `Source` abstraction so that its input can either be a string of bytes (which is used for lexing) or a sequence of tokens. An alternative is to drop the separate lexing phase, and instead somehow automatically insert "whitespace or comments" in between each expression in the non-lexer productions. However, this is not simple and itself would add its own complexity. It might be worth exploring, though. + +## Token splitting + +Token splitting is not implemented. That is, when the parser sees `Option<<Vec<i32>`, it will need to split the `<<` into two `<` tokens. + +This is a primary blocker for getting tree-based parsing working well enough to parse a typical Rust file. + +This is not an easy problem if we want to have parity with `rustc` because `rustc` does not always split tokens. It might be sufficient for a naive approach to split everything, and hope that there aren't any test cases where they diverge. Unfortunately this could cause problems with the permutation or fuzzing-based testing. Or, we could hard-code where `rustc` does split. + +An alternative approach to splitting would be to change the Reference grammar so that it uses the proc-macro model where tokens keep track of their "spacing" so that you know if you can join two tokens (like `:` `:` into `::`). I believe there is desire to move `rustc` itself to this model, but the work there hasn't been done. This in itself would add some complexity, though. The Reference would also probably need to be clearer about how tokens are translated between the two models (because `macro_rules` uses the joined model whereas proc-macros use the split model). I'm not sure which approach will be easier or better. + +See https://github.com/rust-lang/rust/issues/152398 for my analysis on this. diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/coverage.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/coverage.rs new file mode 100644 index 00000000..cb6d6759 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/coverage.rs @@ -0,0 +1,601 @@ +//! Support for recording and rendering coverage of the grammar. + +use grammar::{Character, Expression, ExpressionKind, Grammar}; + +#[derive(Default)] +pub struct Coverage { + /// Count of the repetitions for each expression. + /// + /// The index is the expression ID. The value is the number of times a + /// particular number of repetitions was found for that expression (index + /// N means it matched N repetitions of the given number of times). + pub match_count: Vec<Vec<u32>>, + + /// Count of how often an expression failed to match its input. + /// + /// The index is the expression ID, the count is the number of times it failed. + pub no_match_count: Vec<u32>, + + /// Count of how often the expression caused a `ParseError`. + /// + /// The index is the expression ID, the count is the number of times it caused an error. + pub parse_error: Vec<u32>, +} + +impl Coverage { + /// Marks a node as being matched. + pub fn cov_match(&mut self, id: u32, count: u32) { + if self.match_count.len() < (id + 1) as usize { + self.match_count.resize((id + 1) as usize, Vec::new()); + } + let ns = self.match_count.get_mut(id as usize).unwrap(); + if ns.len() < (count + 1) as usize { + ns.resize((count + 1) as usize, 0); + } + *ns.get_mut(count as usize).unwrap() += 1; + } + + /// Marks a node that failed to match its input. + pub fn cov_no_match(&mut self, id: u32) { + if self.no_match_count.len() < (id + 1) as usize { + self.no_match_count.resize((id + 1) as usize, 0); + } + *self.no_match_count.get_mut(id as usize).unwrap() += 1; + } + + /// Marks a node that caused a `ParseError`. + pub fn cov_parse_error(&mut self, id: u32) { + if self.parse_error.len() < (id + 1) as usize { + self.parse_error.resize((id + 1) as usize, 0); + } + *self.parse_error.get_mut(id as usize).unwrap() += 1; + } + + /// Merge one `Coverage` into this one. + pub fn merge(&mut self, other: Coverage) { + if self.match_count.len() < other.match_count.len() { + self.match_count.resize(other.match_count.len(), Vec::new()); + } + for (id, counts) in other.match_count.into_iter().enumerate() { + let this = self.match_count.get_mut(id).unwrap(); + if this.len() < counts.len() { + this.resize(counts.len(), 0); + } + for (count, value) in counts.into_iter().enumerate() { + this[count] += value; + } + } + + if self.no_match_count.len() < other.no_match_count.len() { + self.no_match_count.resize(other.no_match_count.len(), 0); + } + for (id, value) in other.no_match_count.into_iter().enumerate() { + self.no_match_count[id] += value; + } + + if self.parse_error.len() < other.parse_error.len() { + self.parse_error.resize(other.parse_error.len(), 0); + } + for (id, value) in other.parse_error.into_iter().enumerate() { + self.parse_error[id] += value; + } + } + + /// Saves the coverage data to a file called `coverage.html`. + pub fn save(&self, grammar: &Grammar) { + let mut html = String::new(); + let mut span_stack = Vec::new(); + self.render_html(&mut html, &mut span_stack, grammar); + std::fs::write("coverage.html", html).expect("failed to write coverage.html"); + } + + fn get_coverage_status(&self, id: u32, kind: &ExpressionKind) -> CoverageStatus { + let match_count = self.match_count.get(id as usize); + let no_match = self.no_match_count.get(id as usize).copied().unwrap_or(0); + let parse_error = self.parse_error.get(id as usize).copied().unwrap_or(0); + + let has_matches = match_count + .map(|counts| counts.iter().any(|&c| c > 0)) + .unwrap_or(false); + let has_no_match = no_match > 0; + + // Special case logic for specific expression kinds + match kind { + ExpressionKind::Optional(_) => { + // Green means match_count contains both 0 and 1 + if let Some(counts) = match_count { + let has_zero = counts.get(0).copied().unwrap_or(0) > 0; + let has_one = counts.get(1).copied().unwrap_or(0) > 0; + if has_zero && has_one { + return CoverageStatus::Green; + } else if has_zero || has_one { + return CoverageStatus::Yellow; + } + } + CoverageStatus::Red + } + ExpressionKind::Repeat(_) => { + // Green means match_count contains 0, 1, and more than 1 + if let Some(counts) = match_count { + let has_zero = counts.get(0).copied().unwrap_or(0) > 0; + let has_one = counts.get(1).copied().unwrap_or(0) > 0; + let has_more = counts.iter().skip(2).any(|&c| c > 0); + if has_zero && has_one && has_more { + return CoverageStatus::Green; + } else if has_zero || has_one || has_more { + return CoverageStatus::Yellow; + } + } + CoverageStatus::Red + } + ExpressionKind::RepeatPlus(_) => { + // Green means match_count contains 1 and more than 1 and no_match_count is not zero + if let Some(counts) = match_count { + let has_one = counts.get(1).copied().unwrap_or(0) > 0; + let has_more = counts.iter().skip(2).any(|&c| c > 0); + if has_one && has_more && has_no_match { + return CoverageStatus::Green; + } else if (has_one || has_more) || has_no_match { + return CoverageStatus::Yellow; + } + } + CoverageStatus::Red + } + ExpressionKind::RepeatRange { min, max, .. } => { + // Green means match_count contains the minimum and maximum values + if let Some(counts) = match_count { + let min_val = min.unwrap_or(0) as usize; + let has_min = counts.get(min_val).copied().unwrap_or(0) > 0; + + let has_max = if let Some(max_val) = max { + counts.get(*max_val as usize).copied().unwrap_or(0) > 0 + } else { + // If max is None, consider it green if there are matches for any count over min + counts.iter().skip(min_val + 1).any(|&c| c > 0) + }; + + if has_min && has_max { + return CoverageStatus::Green; + } else if has_min || has_max { + return CoverageStatus::Yellow; + } + } + CoverageStatus::Red + } + ExpressionKind::Cut(_) => { + // Green means match_count contains a nonzero value and parse_error contains a nonzero value + if has_matches && parse_error > 0 { + return CoverageStatus::Green; + } else if has_matches || parse_error > 0 { + return CoverageStatus::Yellow; + } + CoverageStatus::Red + } + _ => { + // Default logic for other expression kinds + if !has_matches && no_match == 0 && parse_error == 0 { + CoverageStatus::Red + } else if has_matches && !has_no_match { + CoverageStatus::Yellow + } else if has_matches && has_no_match { + CoverageStatus::Green + } else { + CoverageStatus::Red + } + } + } + } + + fn render_html(&self, output: &mut String, span_stack: &mut Vec<String>, grammar: &Grammar) { + output.push_str(HTML_HEADER); + + // Group productions by category, preserving first-appearance order. + let mut category_order: Vec<String> = Vec::new(); + let mut categories: std::collections::HashMap<String, Vec<&str>> = + std::collections::HashMap::new(); + for name in &grammar.name_order { + if let Some(prod) = grammar.productions.get(name) { + let cat = &prod.category; + if !categories.contains_key(cat) { + category_order.push(cat.clone()); + categories.insert(cat.clone(), Vec::new()); + } + categories.get_mut(cat).unwrap().push(name.as_str()); + } + } + + for category in &category_order { + output.push_str(&format!( + "<div class=\"category\"><h2 class=\"category-name\">{}</h2>\n", + html_escape(category) + )); + if let Some(names) = categories.get(category) { + for name in names { + if let Some(prod) = grammar.productions.get(*name) { + self.render_production(prod, output, span_stack); + } + } + } + output.push_str("</div>\n"); + } + + output.push_str(HTML_FOOTER); + } + + fn render_production( + &self, + prod: &grammar::Production, + output: &mut String, + span_stack: &mut Vec<String>, + ) { + output.push_str("<div class=\"production\">"); + output.push_str(&format!( + "<span class=\"production-name\">{}</span>", + html_escape(&prod.name) + )); + output.push_str(" → "); + self.render_expression(&prod.expression, output, span_stack); + output.push_str("</div>\n"); + } + + fn render_expression( + &self, + expr: &Expression, + output: &mut String, + span_stack: &mut Vec<String>, + ) { + if let ExpressionKind::Break(indent) = &expr.kind { + for _ in 0..span_stack.len() { + output.push_str("</span>"); + } + output.push_str("<br>\n"); + for span in span_stack { + output.push_str(span); + } + for _ in 0..*indent { + output.push_str(" "); + } + return; + } + + if let ExpressionKind::Comment(s) = &expr.kind { + output.push_str(&format!( + "<span class=\"comment\">// {}</span>", + html_escape(s) + )); + return; + } + + let status = self.get_coverage_status(expr.id, &expr.kind); + let bg_color = status.color(); + let has_error = self.parse_error.get(expr.id as usize).copied().unwrap_or(0) > 0; + + let tooltip = self.generate_tooltip(expr.id); + + let span = format!( + "<span class=\"expr\" style=\"background-color: {};\" \ + onmouseover=\"showTooltip(event, '{}')\" \ + onmouseout=\"hideTooltip()\">", + bg_color, + html_escape(&tooltip).replace("'", "'") + ); + output.push_str(&span); + span_stack.push(span); + + if has_error { + output.push_str("<span class=\"error-marker\">●</span>"); + } + + self.render_expression_kind(&expr.kind, output, span_stack); + + if let Some(suffix) = &expr.suffix { + output.push_str(&format!("<sub>{}</sub>", html_escape(suffix))); + } + + output.push_str("</span>"); + span_stack.pop(); + } + + fn render_expression_kind( + &self, + kind: &ExpressionKind, + output: &mut String, + span_stack: &mut Vec<String>, + ) { + match kind { + ExpressionKind::Grouped(e) => { + output.push_str("( "); + self.render_expression(e, output, span_stack); + output.push_str(" )"); + } + ExpressionKind::Alt(es) => { + let mut iter = es.iter().peekable(); + while let Some(e) = iter.next() { + self.render_expression(e, output, span_stack); + if iter.peek().is_some() { + if !e.last_expr().is_break() { + output.push(' '); + } + output.push_str("| "); + } + } + } + ExpressionKind::Sequence(es) => { + let mut iter = es.iter().peekable(); + while let Some(e) = iter.next() { + self.render_expression(e, output, span_stack); + if iter.peek().is_some() && !e.last_expr().is_break() { + output.push(' '); + } + } + } + ExpressionKind::Optional(e) => { + self.render_expression(e, output, span_stack); + output.push_str("<sup>?</sup>"); + } + ExpressionKind::NegativeLookahead(e) => { + output.push('!'); + self.render_expression(e, output, span_stack); + } + ExpressionKind::Repeat(e) => { + self.render_expression(e, output, span_stack); + output.push_str("<sup>*</sup>"); + } + ExpressionKind::RepeatPlus(e) => { + self.render_expression(e, output, span_stack); + output.push_str("<sup>+</sup>"); + } + ExpressionKind::RepeatRange { + expr, + name, + min, + max, + limit, + } => { + self.render_expression(expr, output, span_stack); + output.push_str("<sup>"); + if let Some(n) = name { + output.push_str(&html_escape(n)); + output.push(':'); + } + if let Some(m) = min { + output.push_str(&m.to_string()); + } + output.push_str(&format!("{}", limit)); + if let Some(m) = max { + output.push_str(&m.to_string()); + } + output.push_str("</sup>"); + } + ExpressionKind::RepeatRangeNamed(e, name) => { + self.render_expression(e, output, span_stack); + output.push_str(&format!("<sup>{}</sup>", html_escape(name))); + } + ExpressionKind::Nt(nt) => { + output.push_str(&format!( + "<span class=\"nonterminal\">{}</span>", + html_escape(nt) + )); + } + ExpressionKind::Terminal(t) => { + output.push_str(&format!( + "<span class=\"terminal\">`{}`</span>", + html_escape(t) + )); + } + ExpressionKind::Prose(s) => { + output.push_str(&format!( + "<span class=\"prose\"><{}></span>", + html_escape(s) + )); + } + ExpressionKind::Break(_) | ExpressionKind::Comment(_) => { + // These are handled in render_expression to avoid coverage spans + unreachable!("Break and Comment should be handled in render_expression") + } + ExpressionKind::Charset(set) => { + output.push('['); + for (i, chars) in set.iter().enumerate() { + if i > 0 { + output.push(' '); + } + self.render_expression(chars, output, span_stack); + } + output.push(']'); + } + ExpressionKind::CharacterRange(a, b) => { + // TODO: It would be nice if this showed more info about the + // actual range that was covered. + let render_ch = |ch: &Character| -> String { + match ch { + Character::Char(c) => format!("`{}`", html_escape(&c.to_string())), + Character::Unicode((_, s)) => format!("U+{}", html_escape(s)), + } + }; + output.push_str(&render_ch(a)); + output.push('-'); + output.push_str(&render_ch(b)); + } + ExpressionKind::NegExpression(e) => { + output.push('~'); + self.render_expression(e, output, span_stack); + } + ExpressionKind::Cut(e) => { + output.push_str("^ "); + self.render_expression(e, output, span_stack); + } + ExpressionKind::Unicode((_, s)) => { + output.push_str(&format!("U+{}", html_escape(s))); + } + } + } + + fn generate_tooltip(&self, id: u32) -> String { + let mut tooltip = String::new(); + + tooltip.push_str(&format!("ID: {}\\n", id)); + + if let Some(counts) = self.match_count.get(id as usize) { + if counts.iter().any(|&c| c > 0) { + tooltip.push_str("Match counts:\\n"); + for (n, &count) in counts.iter().enumerate() { + if count > 0 { + let bar = "█".repeat((count.min(50) / 5).max(1) as usize); + tooltip.push_str(&format!(" {}: {} {}\\n", n, count, bar)); + } + } + } + } + + let no_match = self.no_match_count.get(id as usize).copied().unwrap_or(0); + if no_match > 0 { + tooltip.push_str(&format!("No match: {}\\n", no_match)); + } + + let parse_error = self.parse_error.get(id as usize).copied().unwrap_or(0); + if parse_error > 0 { + tooltip.push_str(&format!("Parse errors: {}\\n", parse_error)); + } + + if tooltip.ends_with("\\n") { + tooltip.truncate(tooltip.len() - 2); + } + + tooltip + } +} + +/// An indication of how well a node was covered. +#[derive(Debug, Clone, Copy)] +enum CoverageStatus { + /// Indicates the node was not covered at all. + Red, + /// Indicates the node was only partially covered. + Yellow, + /// Indicates the node was completely covered. + Green, +} + +impl CoverageStatus { + fn color(&self) -> &'static str { + match self { + CoverageStatus::Red => "#ffcccc", + CoverageStatus::Yellow => "#ffffcc", + CoverageStatus::Green => "#ccffcc", + } + } +} + +fn html_escape(s: &str) -> String { + s.replace('&', "&") + .replace('<', "<") + .replace('>', ">") + .replace('"', """) +} + +const HTML_HEADER: &str = r#"<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Grammar Coverage Report + + + +

Grammar Coverage Report

+
+
+"#; + +const HTML_FOOTER: &str = r#"
+ + + +"#; diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lexer.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lexer.rs new file mode 100644 index 00000000..a12647bc --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lexer.rs @@ -0,0 +1,281 @@ +//! Parser that can take Rust source and generates a sequence of tokens. + +use super::{Node, ParseError}; +use crate::coverage::Coverage; +use crate::parser::{SourceIndex, parse_production}; +use grammar::{ExpressionKind, Grammar, Production}; +use tracing::debug; + +#[derive(Clone)] +pub struct Tokens { + pub tokens: Vec, + /// Byte range of the shebang. + /// + /// The reference lexer is the only tool that sets this. + pub shebang: Option, + /// Byte range of the frontmatter. + /// + /// The reference lexer is the only tool that sets this. + pub frontmatter: Option, +} + +pub fn tokenize( + grammar: &Grammar, + coverage: &mut Coverage, + original_src: &str, +) -> Result { + let (normalized_src, removed_indices) = normalize_crlf(original_src); + + tokenize_normalized(grammar, coverage, &normalized_src) + .map(|mut tokens| { + for token in &mut tokens.tokens { + adjust_node(&removed_indices, token); + } + if let Some(shebang) = &mut tokens.shebang { + adjust_node(&removed_indices, shebang); + } + if let Some(frontmatter) = &mut tokens.frontmatter { + adjust_node(&removed_indices, frontmatter); + } + tokens + }) + .map_err(|mut err| { + err.byte_offset = map_offset(&removed_indices, err.byte_offset); + err + }) +} + +fn normalize_crlf(src: &str) -> (String, Vec) { + let mut normalized_src = String::with_capacity(src.len()); + let mut removed_indices = Vec::new(); + let mut chars = src.chars().peekable(); + while let Some(ch) = chars.next() { + if ch == '\r' + && let Some(&'\n') = chars.peek() + { + removed_indices.push(normalized_src.len()); + continue; + } + normalized_src.push(ch); + } + (normalized_src, removed_indices) +} + +fn map_offset(removed_indices: &[usize], offset: usize) -> usize { + offset + removed_indices.partition_point(|&x| x < offset) +} + +/// Adjusts the node range for CRLF normalization so that the range matches +/// the original source with the carriage returns. +fn adjust_node(removed_indices: &[usize], node: &mut Node) { + node.range.start = map_offset(removed_indices, node.range.start); + node.range.end = map_offset(removed_indices, node.range.end); + for child in &mut node.children.0 { + adjust_node(removed_indices, child); + } +} + +/// Tokenize source after it has been normalized. +fn tokenize_normalized( + grammar: &Grammar, + coverage: &mut Coverage, + src: &str, +) -> Result { + let top_prods = get_top_prods(grammar); + + let mut index = SourceIndex(0); + // Remove BOM + if src.starts_with('\u{FEFF}') { + index.0 += 3; + } + + let shebang; + (shebang, index) = parse_shebang(grammar, coverage, src, index)?; + let frontmatter; + (frontmatter, index) = parse_frontmatter(grammar, coverage, src, index)?; + let tokens = parse_tokens(grammar, coverage, &top_prods, src, index)?; + validate_delimiters_balanced(&tokens, src)?; + + debug!("lexing complete"); + + let tokens = Tokens { + tokens, + shebang, + frontmatter, + }; + + Ok(tokens) +} + +/// Returns the [`Production`]s that correspond to top-level tokens. +fn get_top_prods(grammar: &Grammar) -> Vec<&Production> { + let mut top_prods = Vec::new(); + let mut collect = |name| { + let prod = grammar.productions.get(name).unwrap(); + let ExpressionKind::Alt(es) = &prod.expression.kind else { + panic!("expected alts"); + }; + for e in es { + let nt = match &e.kind { + ExpressionKind::Sequence(es) => { + let seq: Vec<_> = es + .iter() + .filter_map(|e| match &e.kind { + ExpressionKind::Nt(nt) => Some(nt), + ExpressionKind::Break(_) | ExpressionKind::Comment(_) => None, + kind => panic!("unexpected kind {kind:?}"), + }) + .collect(); + assert_eq!(seq.len(), 1); + seq[0] + } + ExpressionKind::Nt(nt) => nt, + kind => panic!("unexpected kind {kind:?}"), + }; + top_prods.push(grammar.productions.get(nt).unwrap()); + } + }; + collect("COMMENT"); + collect("Token"); + top_prods +} + +fn parse_shebang( + grammar: &Grammar, + coverage: &mut Coverage, + src: &str, + index: SourceIndex, +) -> Result<(Option, SourceIndex), ParseError> { + let shebang = grammar.productions.get("SHEBANG").unwrap(); + if let Some((node, next_index)) = parse_production(grammar, coverage, shebang, &src, index)? { + Ok((Some(node), next_index)) + } else { + Ok((None, index)) + } +} + +fn parse_frontmatter( + grammar: &Grammar, + coverage: &mut Coverage, + src: &str, + index: SourceIndex, +) -> Result<(Option, SourceIndex), ParseError> { + let frontmatter = grammar.productions.get("FRONTMATTER").unwrap(); + if let Some((node, next_index)) = parse_production(grammar, coverage, frontmatter, &src, index) + .map_err(|e| ParseError { + message: format!("invalid frontmatter: {}", e.message), + byte_offset: e.byte_offset, + })? + { + Ok((Some(node), next_index)) + } else { + Ok((None, index)) + } +} + +/// Performs the actual parsing of all the tokens in the source. +fn parse_tokens( + grammar: &Grammar, + coverage: &mut Coverage, + top_prods: &[&Production], + src: &str, + mut index: SourceIndex, +) -> Result, ParseError> { + let mut tokens = Vec::new(); + let whitespace = grammar.productions.get("WHITESPACE").unwrap(); + + while index.0 < src.len() { + if let Some((_node, next_index)) = + parse_production(grammar, coverage, whitespace, &src, index)? + { + index = next_index; + continue; + } + + let mut matched_token = None; + for token_prod in top_prods { + debug!("try top-level token `{}`", token_prod.name); + if let Some((node, next_index)) = + parse_production(grammar, coverage, token_prod, &src, index)? + && node.byte_len() > 0 + { + index = next_index; + matched_token = Some(node); + break; + } + } + + match matched_token { + Some(mut node) => { + normalize_line_doc(&mut node, src); + tokens.push(node); + } + None => { + return Err(ParseError { + byte_offset: index.0, + message: String::from("no tokens matched"), + }); + } + } + } + Ok(tokens) +} + +fn validate_delimiters_balanced(tokens: &[Node], src: &str) -> Result<(), ParseError> { + let mut stack = Vec::new(); + for token in tokens { + let text = &src[token.range.clone()]; + match text { + "(" | "[" | "{" => stack.push((text, token.range.start)), + ")" => { + if stack.pop().map(|(s, _)| s) != Some("(") { + return Err(ParseError { + byte_offset: token.range.start, + message: "unbalanced `)`".to_string(), + }); + } + } + "]" => { + if stack.pop().map(|(s, _)| s) != Some("[") { + return Err(ParseError { + byte_offset: token.range.start, + message: "unbalanced `]`".to_string(), + }); + } + } + "}" => { + if stack.pop().map(|(s, _)| s) != Some("{") { + return Err(ParseError { + byte_offset: token.range.start, + message: "unbalanced `}`".to_string(), + }); + } + } + _ => {} + } + } + if let Some((_, offset)) = stack.pop() { + return Err(ParseError { + byte_offset: offset, + message: "unclosed delimiter".to_string(), + }); + } + Ok(()) +} + +/// Fix line doc comment range. +/// +/// The Reference models line doc comments as *content* followed by a +/// linefeed. However, rustc and proc-macro2 model it as everything excluding +/// the linefeed. For convenience, this normalizes the range so that it +/// matches the other tools. +/// +/// A real implementation using the Reference lexer would extract the content +/// from `LINE_DOC_COMMENT_CONTENT`, which does not include the linefeed. +fn normalize_line_doc(node: &mut Node, src: &str) { + if matches!(node.name.as_str(), "INNER_LINE_DOC" | "OUTER_LINE_DOC") + && src[node.range.clone()].ends_with('\n') + { + node.range.end -= 1; + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lib.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lib.rs new file mode 100644 index 00000000..e8e1c9da --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/lib.rs @@ -0,0 +1,119 @@ +//! Rust parser based on the Reference grammar. + +use std::ops::Range; +use std::str::FromStr; + +pub mod coverage; +pub mod lexer; +mod parser; +pub mod tree; + +#[derive(Clone, Debug)] +pub struct ParseError { + pub byte_offset: usize, + pub message: String, +} + +impl ParseError { + pub fn display(&self, src: &str) -> String { + let s = &src[self.byte_offset..]; + match s.char_indices().nth(100) { + Some((i, _)) => format!("{} at `{}…`", self.message, &s[..i]), + None => format!("{} at `{s}`", self.message), + } + } +} + +#[derive(Clone, Copy, PartialEq, PartialOrd, Debug, Eq)] +pub enum Edition { + Edition2015, + Edition2018, + Edition2021, + Edition2024, +} + +impl FromStr for Edition { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "2015" => Ok(Edition::Edition2015), + "2018" => Ok(Edition::Edition2018), + "2021" => Ok(Edition::Edition2021), + "2024" => Ok(Edition::Edition2024), + _ => Err(()), + } + } +} + +/// A parsed section of source corresponding to some grammar expression. +#[derive(Clone, Debug, Default)] +pub struct Node { + pub name: String, + /// Range in bytes of the original source that this node covers. + pub range: Range, + pub children: Nodes, +} + +impl Node { + pub fn new(name: String, range: Range) -> Node { + Node { + name, + range, + children: Nodes::default(), + } + } + + /// Returns a new `Node` with the given children. + fn with_children(name: String, start: usize, children: Nodes) -> Node { + let range = if children.0.is_empty() { + Range { start, end: start } + } else { + Range { + start: children.0.first().unwrap().range.start, + end: children.0.last().unwrap().range.end, + } + }; + Node { + name, + range, + children, + } + } + + /// Length in bytes of this node. + fn byte_len(&self) -> usize { + self.range.end - self.range.start + } +} + +/// Abstraction over a sequence of nodes. +#[derive(Clone, Debug, Default)] +pub struct Nodes(pub Vec); + +impl Nodes { + fn new(name: String, range: Range) -> Nodes { + let node = Node { + name, + range, + children: Nodes::default(), + }; + Nodes(vec![node]) + } + + /// Converts this `Nodes` to one with a single `Node`. + fn wrap(self, name: String, start: usize) -> Nodes { + Nodes(vec![Node::with_children(name.to_string(), start, self)]) + } + + fn extend(&mut self, other: Nodes) { + self.0.extend(other.0) + } + + fn byte_len(&self) -> usize { + if self.0.is_empty() { + 0 + } else { + self.0.last().unwrap().range.end - self.0.first().unwrap().range.start + } + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/main.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/main.rs new file mode 100644 index 00000000..46ad77b9 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/main.rs @@ -0,0 +1,41 @@ +use diagnostics::Diagnostics; +use parser::coverage::Coverage; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; + +fn main() { + let filter = tracing_subscriber::EnvFilter::builder() + .with_env_var("GRAMMAR_LOG") + .with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into()) + .from_env_lossy(); + + tracing_subscriber::registry() + .with(filter) + .with( + tracing_tree::HierarchicalLayer::new(2) + .with_writer(std::io::stderr) + .with_ansi(std::io::IsTerminal::is_terminal(&std::io::stderr())), + ) + .init(); + + let src = r###"r"test""###; + + let mut diag = Diagnostics::new(); + let grammar = grammar::load_grammar(&mut diag); + let mut coverage = Coverage::default(); + let ts = match parser::lexer::tokenize(&grammar, &mut coverage, src) { + Ok(ts) => ts, + Err(e) => { + eprintln!("error: {}", e.display(src)); + std::process::exit(1); + } + }; + for token in ts.tokens { + eprintln!( + "{} {:?}: `{}`", + token.name, + token.range.clone(), + &src[token.range] + ); + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/parser.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/parser.rs new file mode 100644 index 00000000..16e9be3d --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/parser.rs @@ -0,0 +1,630 @@ +//! The generic interpreter of the Reference grammar. + +use super::{Node, Nodes, ParseError}; +use crate::coverage::Coverage; +use grammar::{Expression, ExpressionKind, Grammar, Production, RangeLimit}; +use std::collections::HashMap; +use std::ops::Range; +use tracing::instrument; + +/// This stores named repetitions. +/// +/// The key is the name, and the value is the number of repetitions that +/// happened. +#[derive(Debug, Default)] +struct Environment { + map: HashMap, +} + +/// A wrapper around an index for referring to elements in a [`Source`]. +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone)] +pub(crate) struct SourceIndex(pub(crate) usize); + +/// Abstracts different kinds of sources for the parser. +/// +/// This allows the parser to be used for both string sources and tokenized +/// sources. String sources work in elements of bytes of a string, whereas +/// token sources work in elements of tokens. The offsets are based on +/// elements in the sequence represented with [`SourceIndex`]. +pub(crate) trait Source { + /// Returns a substring from the given offset of the given length in bytes. + /// + /// If this does not match an entire token, it returns None. + fn get_substring(&self, offset: SourceIndex, bytes: usize) -> Option<(&str, Range)>; + + /// Returns the element at the given offset. + fn get_element(&self, offset: SourceIndex) -> Option<(&str, Range)>; + + /// Returns the number of elements in the source. + fn len(&self) -> SourceIndex; + + /// Returns what the next index should be when advanced from the current + /// index with the given number of bytes. + fn advance(&self, index: SourceIndex, bytes: usize) -> SourceIndex; + + /// If this is a token source, returns the node at the given index. + /// + /// Returns `None` if past the end of the input. + /// + /// This is essentially a hack to create a boundary between the lexer and + /// the tree parser. + fn get_node(&self, index: SourceIndex) -> Option<&Node>; + + /// Returns the byte offset of the start of the given element. + /// + /// When the index is at the end, returns the offset of the last element. + fn index_to_bytes(&self, index: SourceIndex) -> usize; +} + +impl Source for &str { + fn get_substring(&self, offset: SourceIndex, bytes: usize) -> Option<(&str, Range)> { + let end = offset.0.checked_add(bytes)?; + if end > (*self).len() { + return None; + } + if !self.is_char_boundary(offset.0) || !self.is_char_boundary(end) { + return None; + } + let s = &self[offset.0..end]; + let range = Range { + start: offset.0, + end, + }; + Some((s, range)) + } + + fn get_element(&self, offset: SourceIndex) -> Option<(&str, Range)> { + let ch = self[offset.0..].chars().next()?; + let len = ch.len_utf8(); + let s = &self[offset.0..offset.0 + len]; + let range = Range { + start: offset.0, + end: offset.0 + len, + }; + Some((s, range)) + } + + fn len(&self) -> SourceIndex { + SourceIndex((*self).len()) + } + + fn advance(&self, index: SourceIndex, bytes: usize) -> SourceIndex { + SourceIndex(index.0 + bytes) + } + + fn get_node(&self, _index: SourceIndex) -> Option<&Node> { + None + } + + fn index_to_bytes(&self, index: SourceIndex) -> usize { + index.0 + } +} + +/// Parse a production and return the Node with name from the production. +pub(crate) fn parse_production( + grammar: &Grammar, + coverage: &mut Coverage, + prod: &Production, + src: &dyn Source, + index: SourceIndex, +) -> Result, ParseError> { + let r = parse( + grammar, + coverage, + &prod.expression, + src, + index, + &mut Environment::default(), + )? + .map(|(children, next_index)| { + let children = Node::with_children(prod.name.clone(), src.index_to_bytes(index), children); + (children, next_index) + }); + Ok(r) +} + +/// Parse an expression. +/// +/// Returns `Ok(None)` if the expression does not match. Otherwise, it +/// returns the [`Nodes`] that match, along with the new index pointing +/// just after the matched nodes. +/// +/// Note that some expressions match zero elements (like `e*` when `e` doesn't +/// match), and those are treated as a successful match where `Nodes` is +/// empty. +/// +/// Returns `Err` if there is some kind of syntax error. +#[instrument(level = "debug", skip(grammar, e, src, coverage), ret)] +fn parse( + grammar: &Grammar, + coverage: &mut Coverage, + e: &Expression, + src: &dyn Source, + index: SourceIndex, + env: &mut Environment, +) -> Result, ParseError> { + tracing::debug!("e={e}"); + if index < src.len() { + tracing::debug!("next={:?}", src.get_element(index)); + } else { + tracing::debug!("eof"); + } + let cov_match = |coverage: &mut Coverage, count| coverage.cov_match(e.id, count as u32); + let cov_no_match = |coverage: &mut Coverage| coverage.cov_no_match(e.id); + let cov_parse_error = |coverage: &mut Coverage| coverage.cov_parse_error(e.id); + match &e.kind { + ExpressionKind::Grouped(group) => { + assert_eq!(e.suffix, None); + match parse(grammar, coverage, group, src, index, env)? { + Some((nodes, i)) => { + cov_match(coverage, 1); + Ok(Some(( + nodes.wrap(format!("Group({group})"), src.index_to_bytes(index)), + i, + ))) + } + None => { + cov_no_match(coverage); + Ok(None) + } + } + } + ExpressionKind::Alt(es) => { + assert_eq!(e.suffix, None); + for e in es { + if let Some(r) = parse(grammar, coverage, e, src, index, env)? { + cov_match(coverage, 1); + return Ok(Some(r)); + } + } + cov_no_match(coverage); + Ok(None) + } + ExpressionKind::Sequence(es) => { + assert_eq!(e.suffix, None); + let mut current = index; + let mut children = Vec::new(); + for e in es { + if matches!( + e.kind, + ExpressionKind::Break(_) | ExpressionKind::Comment(_) + ) { + continue; + } + match parse(grammar, coverage, e, src, current, env)? { + Some((nodes, next_index)) => { + current = next_index; + children.extend(nodes.0); + } + None => { + cov_no_match(coverage); + return Ok(None); + } + } + } + cov_match(coverage, 1); + Ok(Some((Nodes(children), current))) + } + ExpressionKind::Optional(opt) => { + assert_eq!(e.suffix, None); + match parse(grammar, coverage, opt, src, index, env)? { + Some((children, next_index)) => { + cov_match(coverage, 1); + Ok(Some(( + children.wrap(format!("Optional({opt})"), src.index_to_bytes(index)), + next_index, + ))) + } + None => { + cov_match(coverage, 0); + Ok(Some((Nodes::default(), index))) + } + } + } + ExpressionKind::NegativeLookahead(n) => { + assert_eq!(e.suffix, None); + match parse(grammar, coverage, n, src, index, env)? { + Some(_) => { + cov_match(coverage, 1); + Ok(None) + } + None => { + cov_no_match(coverage); + Ok(Some((Nodes::default(), index))) + } + } + } + ExpressionKind::Repeat(r) => { + assert_eq!(e.suffix, None); + let mut current = index; + let mut children = Nodes::default(); + while current < src.len() { + match parse(grammar, coverage, r, src, current, env)? { + Some((nodes, next_index)) => { + current = next_index; + children.extend(nodes); + } + None => break, + } + } + cov_match(coverage, children.0.len()); + Ok(Some(( + children.wrap(format!("Repeat({r})"), src.index_to_bytes(index)), + current, + ))) + } + ExpressionKind::RepeatPlus(r) => { + assert_eq!(e.suffix, None); + let mut current = index; + let mut children = Nodes::default(); + while current < src.len() { + match parse(grammar, coverage, r, src, current, env)? { + Some((nodes, next_index)) => { + current = next_index; + children.extend(nodes); + } + None => break, + } + } + if current == index { + cov_no_match(coverage); + Ok(None) + } else { + cov_match(coverage, children.0.len()); + Ok(Some(( + children.wrap(format!("RepeatPlus({r})"), src.index_to_bytes(index)), + current, + ))) + } + } + ExpressionKind::RepeatRange { + expr: r, + name, + min, + max, + limit, + } => { + let max = max.map(|max| match limit { + RangeLimit::HalfOpen => max - 1, + RangeLimit::Closed => max, + }); + let mut current = index; + let mut children = Nodes::default(); + let mut count = 0; + while current < src.len() { + match parse(grammar, coverage, r, src, current, env)? { + Some((nodes, next_index)) => { + current = next_index; + children.extend(nodes); + count += 1; + if let Some(max) = max + && count == max + { + break; + } + } + None => break, + } + } + if let Some(min) = min + && count < *min + { + cov_no_match(coverage); + return Ok(None); + } + if let Some(name) = name { + assert!(env.map.insert(name.clone(), count).is_none()); + } + + let start_byte_offset = src.index_to_bytes(index); + match e.suffix.as_deref() { + Some("valid hex char value") => { + let end = src.index_to_bytes(current); + let len = end - start_byte_offset; + let (hex, _) = src.get_substring(index, len).unwrap(); + let hex_no_underscores = hex.replace('_', ""); + let value = u32::from_str_radix(&hex_no_underscores, 16).map_err(|_| { + cov_parse_error(coverage); + ParseError { + byte_offset: start_byte_offset, + message: format!("invalid hex value: {hex}"), + } + })?; + if char::from_u32(value).is_none() { + cov_parse_error(coverage); + return Err(ParseError { + byte_offset: start_byte_offset, + message: format!("invalid Unicode scalar value: {hex}"), + }); + } + } + Some(s) => panic!("unknown suffix {s:?}"), + None => {} + } + + cov_match(coverage, children.0.len()); + Ok(Some(( + children.wrap(format!("RepatRange({r})"), start_byte_offset), + current, + ))) + } + ExpressionKind::RepeatRangeNamed(r, name) => { + assert_eq!(e.suffix, None); + let Some(count) = env.map.get(name) else { + panic!("expected {name} in environment for {r}"); + }; + let mut current = index; + let mut children = Nodes::default(); + for _ in 0..*count { + match parse(grammar, coverage, r, src, current, env)? { + Some((nodes, next_index)) => { + current = next_index; + children.extend(nodes); + } + None => { + cov_no_match(coverage); + return Ok(None); + } + } + } + cov_match(coverage, children.0.len()); + Ok(Some(( + children.wrap( + format!("RepeatRangeNamed({r}, {name})"), + src.index_to_bytes(index), + ), + current, + ))) + } + ExpressionKind::Nt(s) => { + let Some((nodes, next_index)) = parse_nt(grammar, s, src, index, env, coverage)? else { + cov_no_match(coverage); + return Ok(None); + }; + let len = nodes.byte_len(); + let (matched, _) = src.get_substring(index, len).unwrap(); + match e.suffix.as_deref() { + Some("except `b` or `c` or `r` or `br` or `cr`") => { + if matches!(matched, "b" | "c" | "r" | "br" | "cr") { + cov_no_match(coverage); + return Ok(None); + } + } + Some("except `b`") => { + if matched == "b" { + cov_no_match(coverage); + return Ok(None); + } + } + Some("except `r` or `br` or `cr`") => { + if matches!(matched, "r" | "br" | "cr") { + cov_no_match(coverage); + return Ok(None); + } + } + Some("except `r`") => { + if matched == "r" { + cov_no_match(coverage); + return Ok(None); + } + } + Some( + "except a [strict][lex.keywords.strict] or [reserved][lex.keywords.reserved] keyword", + ) => { + let strict = grammar.productions.get("STRICT_KEYWORDS").unwrap(); + let reserved = grammar.productions.get("RESERVED_KEYWORDS").unwrap(); + for e in [&strict.expression, &reserved.expression] { + if let Ok(Some((nodes, _))) = parse(grammar, coverage, e, src, index, env) + && nodes.byte_len() > 0 + { + cov_no_match(coverage); + return Ok(None); + } + } + } + Some("except [delimiters][lex.token.delim]") => { + if matches!(matched, "{" | "}" | "[" | "]" | "(" | ")") { + cov_no_match(coverage); + return Ok(None); + } + } + Some(suffix) => panic!("unknown suffix {suffix:?}"), + None => {} + } + cov_match(coverage, 1); + Ok(Some((nodes, next_index))) + } + ExpressionKind::Terminal(s) => { + let Some((next_s, range)) = src.get_substring(index, s.len()) else { + cov_no_match(coverage); + return Ok(None); + }; + if next_s != s { + cov_no_match(coverage); + return Ok(None); + } + let next_index = src.advance(index, s.len()); + match e.suffix.as_deref() { + Some("immediately followed by LF") => { + if let Some((next_s, _)) = src.get_element(next_index) + && next_s != "\n" + { + cov_no_match(coverage); + return Ok(None); + } + } + Some(suffix) => panic!("unknown suffix {suffix:?}"), + None => {} + } + let nodes = Nodes::new(format!("Terminal {s:?}"), range); + cov_match(coverage, 1); + Ok(Some((nodes, next_index))) + } + ExpressionKind::Prose(s) => { + assert_eq!(e.suffix, None); + match match_prose(s, src, index) { + Some(r) => { + cov_match(coverage, 1); + Ok(Some(r)) + } + None => { + cov_no_match(coverage); + Ok(None) + } + } + } + ExpressionKind::Break(_) => unreachable!(), + ExpressionKind::Comment(_) => unreachable!(), + ExpressionKind::Charset(chars) => { + assert_eq!(e.suffix, None); + for ch in chars { + if let Some(r) = parse(grammar, coverage, ch, src, index, env)? { + cov_match(coverage, 1); + return Ok(Some(r)); + } + } + cov_no_match(coverage); + Ok(None) + } + ExpressionKind::CharacterRange(a, b) => { + let Some((next, range)) = src.get_element(index) else { + cov_no_match(coverage); + return Ok(None); + }; + if next.chars().count() == 1 { + let ch = next.chars().next().unwrap(); + if ch >= a.get_ch() && ch <= b.get_ch() { + let next_index = src.advance(index, ch.len_utf8()); + let nodes = Nodes::new(format!("Range {a:?} to {b:?}"), range); + // TODO: Would be nice to record coverage of how much of the range is covered. + cov_match(coverage, 1); + return Ok(Some((nodes, next_index))); + } + } + cov_no_match(coverage); + Ok(None) + } + ExpressionKind::NegExpression(neg) => { + assert_eq!(e.suffix, None); + match parse(grammar, coverage, neg, src, index, env)? { + Some(_) => { + cov_no_match(coverage); + Ok(None) + } + None => { + if let Some((s, range)) = src.get_element(index) { + let next_index = src.advance(index, s.len()); + let nodes = Nodes::new(format!("NegExpression {neg}"), range); + cov_match(coverage, 1); + Ok(Some((nodes, next_index))) + } else { + cov_no_match(coverage); + Ok(None) + } + } + } + } + ExpressionKind::Cut(inner) => { + assert_eq!(e.suffix, None); + match parse(grammar, coverage, inner, src, index, env)? { + Some(r) => { + cov_match(coverage, 1); + Ok(Some(r)) + } + None => { + cov_parse_error(coverage); + Err(ParseError { + byte_offset: src.index_to_bytes(index), + message: format!("expected {}", inner), + }) + } + } + } + ExpressionKind::Unicode((ch, s)) => { + assert_eq!(e.suffix, None); + let mut buf = [0u8; 4]; + let c_str = ch.encode_utf8(&mut buf); + if let Some((next_s, range)) = src.get_element(index) + && next_s == c_str + { + let next_index = src.advance(index, ch.len_utf8()); + cov_match(coverage, 1); + Ok(Some(( + Nodes::new(format!("Unicode {s}"), range), + next_index, + ))) + } else { + cov_no_match(coverage); + Ok(None) + } + } + } +} + +fn parse_nt( + grammar: &Grammar, + prod_name: &str, + src: &dyn Source, + index: SourceIndex, + env: &mut Environment, + coverage: &mut Coverage, +) -> Result, ParseError> { + let prod = grammar.productions.get(prod_name).unwrap(); + // If this matches a lexer token, don't parse it and use the token + // directly. The lexer rules are incompatible when reading tokens. + let (nodes, next_index) = if let Some(node) = src.get_node(index) + && node.name == prod.name + { + (Nodes(vec![node.clone()]), SourceIndex(index.0 + 1)) + } else { + let nodes = parse(grammar, coverage, &prod.expression, src, index, env)?; + let Some((nodes, next_index)) = nodes else { + return Ok(None); + }; + ( + nodes.wrap(prod.name.clone(), src.index_to_bytes(index)), + next_index, + ) + }; + Ok(Some((nodes, next_index))) +} + +fn match_prose(prose: &str, src: &dyn Source, index: SourceIndex) -> Option<(Nodes, SourceIndex)> { + let next_as_ch = || { + src.get_element(index).and_then(|(next, range)| { + let mut chars = next.chars(); + let ch = chars.next().unwrap(); + if chars.next().is_some() { + None + } else { + Some((ch, range)) + } + }) + }; + + match prose { + "`XID_Start` defined by Unicode" => { + if let Some((ch, range)) = next_as_ch() { + unicode_ident::is_xid_start(ch).then(|| { + let nodes = Nodes::new(format!("Prose: {prose}"), range); + (nodes, src.advance(index, ch.len_utf8())) + }) + } else { + None + } + } + "`XID_Continue` defined by Unicode" => { + if let Some((ch, range)) = next_as_ch() { + unicode_ident::is_xid_continue(ch).then(|| { + let nodes = Nodes::new(format!("Prose: {prose}"), range); + (nodes, src.advance(index, ch.len_utf8())) + }) + } else { + None + } + } + + p => panic!("unknown prose {p}"), + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/tree.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/tree.rs new file mode 100644 index 00000000..75bfc7be --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/parser/src/tree.rs @@ -0,0 +1,89 @@ +//! Parser that can take Rust source and generate a parse tree. + +use super::{Node, ParseError}; +use crate::coverage::Coverage; +use crate::lexer::tokenize; +use crate::parser::parse_production; +use crate::parser::{Source, SourceIndex}; +use grammar::Grammar; +use std::ops::Range; + +struct TokenSource<'src> { + src: &'src str, + tokens: Vec, +} + +impl Source for TokenSource<'_> { + fn get_substring(&self, offset: SourceIndex, bytes: usize) -> Option<(&str, Range)> { + self.tokens.get(offset.0).and_then(|t| { + let s = &self.src[t.range.clone()]; + if !s.len() == bytes { + None + } else { + Some((s, t.range.clone())) + } + }) + } + + fn get_element(&self, offset: SourceIndex) -> Option<(&str, Range)> { + self.tokens.get(offset.0).map(|t| { + let s = &self.src[t.range.clone()]; + (s, t.range.clone()) + }) + } + + fn len(&self) -> SourceIndex { + SourceIndex(self.tokens.len()) + } + + fn advance(&self, index: SourceIndex, bytes: usize) -> SourceIndex { + let token = &self.tokens[index.0]; + if token.byte_len() != bytes { + panic!("advancing {bytes} at {index:?} is not equal to {token:?}"); + } + SourceIndex(index.0 + 1) + } + + fn get_node(&self, index: SourceIndex) -> Option<&Node> { + self.tokens.get(index.0) + } + + fn index_to_bytes(&self, index: SourceIndex) -> usize { + if index.0 == self.tokens.len() { + self.tokens[index.0 - 1].range.end + } else { + self.tokens[index.0].range.start + } + } +} + +/// Parse Rust source for the given named production, and return a [`Node`] tree. +pub fn parse(grammar: &Grammar, src: &str, production: &str) -> Result { + let mut coverage = Coverage::default(); + + let krate = grammar.productions.get(production).unwrap(); + + let tokens = tokenize(grammar, &mut coverage, src)?; + + // Strip comments. + let tokens = tokens + .tokens + .into_iter() + .filter(|token| !matches!(token.name.as_str(), "LINE_COMMENT" | "BLOCK_COMMENT")) + .collect(); + + let token_source = TokenSource { src, tokens }; + + match parse_production(grammar, &mut coverage, krate, &token_source, SourceIndex(0))? { + Some((node, next_index)) => { + if next_index < token_source.len() { + return Err(ParseError { + message: format!("{production} production failed to parse all tokens"), + byte_offset: token_source.index_to_bytes(next_index), + }); + } + Ok(node) + } + None => panic!("input did not match {production}"), + } +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/Cargo.toml new file mode 100644 index 00000000..d34d2394 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "style-check" +edition = "2024" +license = "MIT OR Apache-2.0" +authors = ["steveklabnik "] + +[dependencies] +pulldown-cmark = "0.10.0" diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/README.md b/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/README.md new file mode 100644 index 00000000..26204da3 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/README.md @@ -0,0 +1,3 @@ +# Style check + +This tool checks some style and formatting rules of the Reference. This is normally run with `cargo xtask style-check`. diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/src/main.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/src/main.rs new file mode 100644 index 00000000..b046cdf7 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/style-check/src/main.rs @@ -0,0 +1,130 @@ +use std::env; +use std::error::Error; +use std::fs; +use std::path::Path; + +macro_rules! style_error { + ($bad:expr, $path:expr, $($arg:tt)*) => { + *$bad = true; + eprint!("error in {}: ", $path.display()); + eprintln!("{}", format_args!($($arg)*)); + }; +} + +fn main() { + let arg = env::args().nth(1).unwrap_or_else(|| { + eprintln!("Please pass a src directory as the first argument"); + std::process::exit(1); + }); + + let mut bad = false; + if let Err(e) = check_directory(&Path::new(&arg), &mut bad) { + eprintln!("error: {}", e); + std::process::exit(1); + } + if bad { + eprintln!("some style checks failed"); + std::process::exit(1); + } + eprintln!("passed!"); +} + +fn check_directory(dir: &Path, bad: &mut bool) -> Result<(), Box> { + for entry in fs::read_dir(dir)? { + let entry = entry?; + let path = entry.path(); + + if path.is_dir() { + check_directory(&path, bad)?; + continue; + } + + if !matches!( + path.extension().and_then(|p| p.to_str()), + Some("md") | Some("html") + ) { + // This may be extended in the future if other file types are needed. + style_error!(bad, path, "expected only md or html in src"); + } + + let contents = fs::read_to_string(&path)?; + if contents.contains("#![feature") { + style_error!(bad, path, "#![feature] attributes are not allowed"); + } + if !cfg!(windows) && contents.contains('\r') { + style_error!( + bad, + path, + "CR characters not allowed, must use LF line endings" + ); + } + if contents.contains('\t') { + style_error!(bad, path, "tab characters not allowed, use spaces"); + } + if !contents.ends_with('\n') { + style_error!(bad, path, "file must end with a newline"); + } + if contents.contains('\u{2013}') { + style_error!(bad, path, "en-dash not allowed, use two dashes like --"); + } + if contents.contains('\u{2014}') { + style_error!(bad, path, "em-dash not allowed, use three dashes like ---"); + } + if contents.contains('\u{a0}') { + style_error!( + bad, + path, + "don't use 0xa0 no-break-space, use   instead" + ); + } + for line in contents.lines() { + if line.ends_with(' ') { + style_error!(bad, path, "lines must not end with spaces"); + } + } + cmark_check(&path, bad, &contents)?; + } + Ok(()) +} + +fn cmark_check(path: &Path, bad: &mut bool, contents: &str) -> Result<(), Box> { + use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag}; + + macro_rules! cmark_error { + ($bad:expr, $path:expr, $range:expr, $($arg:tt)*) => { + *$bad = true; + let lineno = contents[..$range.start].chars().filter(|&ch| ch == '\n').count() + 1; + eprint!("error in {} (line {}): ", $path.display(), lineno); + eprintln!("{}", format_args!($($arg)*)); + } + } + + let options = Options::all(); + let parser = Parser::new_ext(contents, options); + + for (event, range) in parser.into_offset_iter() { + match event { + Event::Start(Tag::CodeBlock(CodeBlockKind::Indented)) => { + cmark_error!( + bad, + path, + range, + "indented code blocks should use triple backtick-style \ + with a language identifier" + ); + } + Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(languages))) => { + if languages.is_empty() { + cmark_error!( + bad, + path, + range, + "code block should include an explicit language", + ); + } + } + _ => {} + } + } + Ok(()) +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/Cargo.toml b/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/Cargo.toml new file mode 100644 index 00000000..ec0a3633 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "xtask" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/README.md b/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/README.md new file mode 100644 index 00000000..1dc4eab9 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/README.md @@ -0,0 +1,3 @@ +# Reference xtask + +This is a CLI tool to make it easier to run the tools found here in the Reference. Run `cargo xtask` to see the list of subcommands it supports. diff --git a/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/src/main.rs b/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/src/main.rs new file mode 100644 index 00000000..5d4b3b65 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/tools/xtask/src/main.rs @@ -0,0 +1,115 @@ +use std::error::Error; +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::process::exit; + +type Result = std::result::Result>; + +fn main() -> Result<()> { + let mut args = std::env::args().skip(1); + let cmd = args.next(); + const OPTIONS: &str = "mdbook-test, linkcheck, style-check, test-all"; + match cmd.as_deref() { + Some("test-all") => { + mdbook_test()?; + style_check()?; + fmt()?; + linkcheck(args)?; + cargo_test()?; + eprintln!("all tests passed!"); + } + Some("mdbook-test") => mdbook_test()?, + Some("linkcheck") => linkcheck(args)?, + Some("style-check") => style_check()?, + Some("-h" | "--help") => eprintln!("valid options: {OPTIONS}"), + Some(x) => { + eprintln!("error: unknown command `{x}` (valid options: {OPTIONS})"); + exit(1); + } + None => { + eprintln!("error: specify a command (valid options: {OPTIONS})"); + exit(1); + } + } + Ok(()) +} + +fn root_dir() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")).join("../..") +} + +fn mdbook_test() -> Result<()> { + eprintln!("Testing inline code tests..."); + let status = Command::new("mdbook") + .arg("test") + .current_dir(root_dir()) + .status() + .expect("mdbook should be installed"); + if !status.success() { + return Err("inline code tests failed".into()); + } + Ok(()) +} + +fn style_check() -> Result<()> { + eprintln!("Running style checks..."); + let status = Command::new("cargo") + .args(["run", "--package=style-check", "--", "src"]) + .current_dir(root_dir()) + .status() + .expect("cargo should be installed"); + if !status.success() { + return Err("style check failed".into()); + } + Ok(()) +} + +fn fmt() -> Result<()> { + eprintln!("Checking code formatting..."); + let status = Command::new("cargo") + .args(["fmt", "--check"]) + .current_dir(root_dir()) + .status() + .expect("cargo should be installed"); + if !status.success() { + return Err("fmt check failed".into()); + } + Ok(()) +} + +fn cargo_test() -> Result<()> { + eprintln!("Running cargo tests..."); + let status = Command::new("cargo") + .arg("test") + .current_dir(root_dir()) + .status() + .expect("cargo should be installed"); + if !status.success() { + return Err("cargo tests failed".into()); + } + Ok(()) +} + +fn linkcheck(args: impl Iterator) -> Result<()> { + eprintln!("Running linkcheck..."); + let root = root_dir(); + let status = Command::new("curl") + .args(["-sSLo", "linkcheck.sh", "https://raw.githubusercontent.com/rust-lang/rust/main/src/tools/linkchecker/linkcheck.sh"]) + .current_dir(&root) + .status() + .expect("curl should be installed"); + if !status.success() { + return Err("failed to fetch script from GitHub".into()); + } + + let status = Command::new("sh") + .args(["linkcheck.sh", "--all", "reference"]) + .args(args) + .current_dir(&root) + .status() + .expect("sh should be installed"); + if !status.success() { + return Err("linkcheck failed".into()); + } + Ok(()) +} diff --git a/stdlib/kvlang/reference/rust/reference-repo/triagebot.toml b/stdlib/kvlang/reference/rust/reference-repo/triagebot.toml new file mode 100644 index 00000000..041f8433 --- /dev/null +++ b/stdlib/kvlang/reference/rust/reference-repo/triagebot.toml @@ -0,0 +1,30 @@ +[relabel] +allow-unauthenticated = [ + "S-*", "A-*", "New Content", "Language Cleanup", "Easy", "Formatting", "Enhancement", "Bug", +] + +[assign] + +[shortcut] + +# When rebasing, this will add a diff link in a comment. +[range-diff] + +[issue-links] +check-commits = false + +[merge-conflicts] +remove = [] +add = ["S-waiting-on-author"] +unless = ["S-blocked", "S-waiting-on-team", "S-waiting-on-review"] + +[autolabel."S-waiting-on-review"] +new_pr = true + +[review-submitted] +reviewed_label = "S-waiting-on-author" +review_labels = ["S-waiting-on-review"] + +[review-requested] +remove_labels = ["S-waiting-on-author"] +add_labels = ["S-waiting-on-review"] diff --git a/stdlib/kvlang/reference/typescript/typescript-1.8-spec.md b/stdlib/kvlang/reference/typescript/typescript-1.8-spec.md new file mode 100644 index 00000000..fa69d321 --- /dev/null +++ b/stdlib/kvlang/reference/typescript/typescript-1.8-spec.md @@ -0,0 +1,6738 @@ +# TypeScript Language Specification + +Version 1.8 + +January, 2016 + +
+ +Microsoft is making this Specification available under the Open Web Foundation Final Specification Agreement Version 1.0 ("OWF 1.0") as of October 1, 2012. The OWF 1.0 is available at [http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0](http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0). + +TypeScript is a trademark of Microsoft Corporation. + +
+ +## Table of Contents + +* [1 Introduction](#1) + * [1.1 Ambient Declarations](#1.1) + * [1.2 Function Types](#1.2) + * [1.3 Object Types](#1.3) + * [1.4 Structural Subtyping](#1.4) + * [1.5 Contextual Typing](#1.5) + * [1.6 Classes](#1.6) + * [1.7 Enum Types](#1.7) + * [1.8 Overloading on String Parameters](#1.8) + * [1.9 Generic Types and Functions](#1.9) + * [1.10 Namespaces](#1.10) + * [1.11 Modules](#1.11) +* [2 Basic Concepts](#2) + * [2.1 Grammar Conventions](#2.1) + * [2.2 Names](#2.2) + * [2.2.1 Reserved Words](#2.2.1) + * [2.2.2 Property Names](#2.2.2) + * [2.2.3 Computed Property Names](#2.2.3) + * [2.3 Declarations](#2.3) + * [2.4 Scopes](#2.4) +* [3 Types](#3) + * [3.1 The Any Type](#3.1) + * [3.2 Primitive Types](#3.2) + * [3.2.1 The Number Type](#3.2.1) + * [3.2.2 The Boolean Type](#3.2.2) + * [3.2.3 The String Type](#3.2.3) + * [3.2.4 The Symbol Type](#3.2.4) + * [3.2.5 The Void Type](#3.2.5) + * [3.2.6 The Null Type](#3.2.6) + * [3.2.7 The Undefined Type](#3.2.7) + * [3.2.8 Enum Types](#3.2.8) + * [3.2.9 String Literal Types](#3.2.9) + * [3.3 Object Types](#3.3) + * [3.3.1 Named Type References](#3.3.1) + * [3.3.2 Array Types](#3.3.2) + * [3.3.3 Tuple Types](#3.3.3) + * [3.3.4 Function Types](#3.3.4) + * [3.3.5 Constructor Types](#3.3.5) + * [3.3.6 Members](#3.3.6) + * [3.4 Union Types](#3.4) + * [3.5 Intersection Types](#3.5) + * [3.6 Type Parameters](#3.6) + * [3.6.1 Type Parameter Lists](#3.6.1) + * [3.6.2 Type Argument Lists](#3.6.2) + * [3.6.3 This-types](#3.6.3) + * [3.7 Named Types](#3.7) + * [3.8 Specifying Types](#3.8) + * [3.8.1 Predefined Types](#3.8.1) + * [3.8.2 Type References](#3.8.2) + * [3.8.3 Object Type Literals](#3.8.3) + * [3.8.4 Array Type Literals](#3.8.4) + * [3.8.5 Tuple Type Literals](#3.8.5) + * [3.8.6 Union Type Literals](#3.8.6) + * [3.8.7 Intersection Type Literals](#3.8.7) + * [3.8.8 Function Type Literals](#3.8.8) + * [3.8.9 Constructor Type Literals](#3.8.9) + * [3.8.10 Type Queries](#3.8.10) + * [3.8.11 This-Type References](#3.8.11) + * [3.9 Specifying Members](#3.9) + * [3.9.1 Property Signatures](#3.9.1) + * [3.9.2 Call Signatures](#3.9.2) + * [3.9.3 Construct Signatures](#3.9.3) + * [3.9.4 Index Signatures](#3.9.4) + * [3.9.5 Method Signatures](#3.9.5) + * [3.10 Type Aliases](#3.10) + * [3.11 Type Relationships](#3.11) + * [3.11.1 Apparent Members](#3.11.1) + * [3.11.2 Type and Member Identity](#3.11.2) + * [3.11.3 Subtypes and Supertypes](#3.11.3) + * [3.11.4 Assignment Compatibility](#3.11.4) + * [3.11.5 Excess Properties](#3.11.5) + * [3.11.6 Contextual Signature Instantiation](#3.11.6) + * [3.11.7 Type Inference](#3.11.7) + * [3.11.8 Recursive Types](#3.11.8) + * [3.12 Widened Types](#3.12) +* [4 Expressions](#4) + * [4.1 Values and References](#4.1) + * [4.2 The this Keyword](#4.2) + * [4.3 Identifiers](#4.3) + * [4.4 Literals](#4.4) + * [4.5 Object Literals](#4.5) + * [4.6 Array Literals](#4.6) + * [4.7 Template Literals](#4.7) + * [4.8 Parentheses](#4.8) + * [4.9 The super Keyword](#4.9) + * [4.9.1 Super Calls](#4.9.1) + * [4.9.2 Super Property Access](#4.9.2) + * [4.10 Function Expressions](#4.10) + * [4.11 Arrow Functions](#4.11) + * [4.12 Class Expressions](#4.12) + * [4.13 Property Access](#4.13) + * [4.14 The new Operator](#4.14) + * [4.15 Function Calls](#4.15) + * [4.15.1 Overload Resolution](#4.15.1) + * [4.15.2 Type Argument Inference](#4.15.2) + * [4.15.3 Grammar Ambiguities](#4.15.3) + * [4.16 Type Assertions](#4.16) + * [4.17 JSX Expressions](#4.17) + * [4.18 Unary Operators](#4.18) + * [4.18.1 The ++ and -- operators](#4.18.1) + * [4.18.2 The +, –, and ~ operators](#4.18.2) + * [4.18.3 The ! operator](#4.18.3) + * [4.18.4 The delete Operator](#4.18.4) + * [4.18.5 The void Operator](#4.18.5) + * [4.18.6 The typeof Operator](#4.18.6) + * [4.19 Binary Operators](#4.19) + * [4.19.1 The *, /, %, –, <<, >>, >>>, &, ^, and | operators](#4.19.1) + * [4.19.2 The + operator](#4.19.2) + * [4.19.3 The <, >, <=, >=, ==, !=, ===, and !== operators](#4.19.3) + * [4.19.4 The instanceof operator](#4.19.4) + * [4.19.5 The in operator](#4.19.5) + * [4.19.6 The && operator](#4.19.6) + * [4.19.7 The || operator](#4.19.7) + * [4.20 The Conditional Operator](#4.20) + * [4.21 Assignment Operators](#4.21) + * [4.21.1 Destructuring Assignment](#4.21.1) + * [4.22 The Comma Operator](#4.22) + * [4.23 Contextually Typed Expressions](#4.23) + * [4.24 Type Guards](#4.24) +* [5 Statements](#5) + * [5.1 Blocks](#5.1) + * [5.2 Variable Statements](#5.2) + * [5.2.1 Simple Variable Declarations](#5.2.1) + * [5.2.2 Destructuring Variable Declarations](#5.2.2) + * [5.2.3 Implied Type](#5.2.3) + * [5.3 Let and Const Declarations](#5.3) + * [5.4 If, Do, and While Statements](#5.4) + * [5.5 For Statements](#5.5) + * [5.6 For-In Statements](#5.6) + * [5.7 For-Of Statements](#5.7) + * [5.8 Continue Statements](#5.8) + * [5.9 Break Statements](#5.9) + * [5.10 Return Statements](#5.10) + * [5.11 With Statements](#5.11) + * [5.12 Switch Statements](#5.12) + * [5.13 Throw Statements](#5.13) + * [5.14 Try Statements](#5.14) +* [6 Functions](#6) + * [6.1 Function Declarations](#6.1) + * [6.2 Function Overloads](#6.2) + * [6.3 Function Implementations](#6.3) + * [6.4 Destructuring Parameter Declarations](#6.4) + * [6.5 Generic Functions](#6.5) + * [6.6 Code Generation](#6.6) + * [6.7 Generator Functions](#6.7) + * [6.8 Asynchronous Functions](#6.8) + * [6.9 Type Guard Functions](#6.9) +* [7 Interfaces](#7) + * [7.1 Interface Declarations](#7.1) + * [7.2 Declaration Merging](#7.2) + * [7.3 Interfaces Extending Classes](#7.3) + * [7.4 Dynamic Type Checks](#7.4) +* [8 Classes](#8) + * [8.1 Class Declarations](#8.1) + * [8.1.1 Class Heritage Specification](#8.1.1) + * [8.1.2 Class Body](#8.1.2) + * [8.2 Members](#8.2) + * [8.2.1 Instance and Static Members](#8.2.1) + * [8.2.2 Accessibility](#8.2.2) + * [8.2.3 Inheritance and Overriding](#8.2.3) + * [8.2.4 Class Types](#8.2.4) + * [8.2.5 Constructor Function Types](#8.2.5) + * [8.3 Constructor Declarations](#8.3) + * [8.3.1 Constructor Parameters](#8.3.1) + * [8.3.2 Super Calls](#8.3.2) + * [8.3.3 Automatic Constructors](#8.3.3) + * [8.4 Property Member Declarations](#8.4) + * [8.4.1 Member Variable Declarations](#8.4.1) + * [8.4.2 Member Function Declarations](#8.4.2) + * [8.4.3 Member Accessor Declarations](#8.4.3) + * [8.4.4 Dynamic Property Declarations](#8.4.4) + * [8.5 Index Member Declarations](#8.5) + * [8.6 Decorators](#8.6) + * [8.7 Code Generation](#8.7) + * [8.7.1 Classes Without Extends Clauses](#8.7.1) + * [8.7.2 Classes With Extends Clauses](#8.7.2) +* [9 Enums](#9) + * [9.1 Enum Declarations](#9.1) + * [9.2 Enum Members](#9.2) + * [9.3 Declaration Merging](#9.3) + * [9.4 Constant Enum Declarations](#9.4) + * [9.5 Code Generation](#9.5) +* [10 Namespaces](#10) + * [10.1 Namespace Declarations](#10.1) + * [10.2 Namespace Body](#10.2) + * [10.3 Import Alias Declarations](#10.3) + * [10.4 Export Declarations](#10.4) + * [10.5 Declaration Merging](#10.5) + * [10.6 Code Generation](#10.6) +* [11 Scripts and Modules](#11) + * [11.1 Programs and Source Files](#11.1) + * [11.1.1 Source Files Dependencies](#11.1.1) + * [11.2 Scripts](#11.2) + * [11.3 Modules](#11.3) + * [11.3.1 Module Names](#11.3.1) + * [11.3.2 Import Declarations](#11.3.2) + * [11.3.3 Import Require Declarations](#11.3.3) + * [11.3.4 Export Declarations](#11.3.4) + * [11.3.5 Export Assignments](#11.3.5) + * [11.3.6 CommonJS Modules](#11.3.6) + * [11.3.7 AMD Modules](#11.3.7) +* [12 Ambients](#12) + * [12.1 Ambient Declarations](#12.1) + * [12.1.1 Ambient Variable Declarations](#12.1.1) + * [12.1.2 Ambient Function Declarations](#12.1.2) + * [12.1.3 Ambient Class Declarations](#12.1.3) + * [12.1.4 Ambient Enum Declarations](#12.1.4) + * [12.1.5 Ambient Namespace Declarations](#12.1.5) + * [12.2 Ambient Module Declarations](#12.2) +* [A Grammar](#A) + * [A.1 Types](#A.1) + * [A.2 Expressions](#A.2) + * [A.3 Statements](#A.3) + * [A.4 Functions](#A.4) + * [A.5 Interfaces](#A.5) + * [A.6 Classes](#A.6) + * [A.7 Enums](#A.7) + * [A.8 Namespaces](#A.8) + * [A.9 Scripts and Modules](#A.9) + * [A.10 Ambients](#A.10) + +
+ +# 1 Introduction + +JavaScript applications such as web e-mail, maps, document editing, and collaboration tools are becoming an increasingly important part of the everyday computing. We designed TypeScript to meet the needs of the JavaScript programming teams that build and maintain large JavaScript programs. TypeScript helps programming teams to define interfaces between software components and to gain insight into the behavior of existing JavaScript libraries. TypeScript also enables teams to reduce naming conflicts by organizing their code into dynamically-loadable modules. TypeScript's optional type system enables JavaScript programmers to use highly-productive development tools and practices: static checking, symbol-based navigation, statement completion, and code re-factoring. + +TypeScript is a syntactic sugar for JavaScript. TypeScript syntax is a superset of ECMAScript 2015 (ES2015) syntax. Every JavaScript program is also a TypeScript program. The TypeScript compiler performs only file-local transformations on TypeScript programs and does not re-order variables declared in TypeScript. This leads to JavaScript output that closely matches the TypeScript input. TypeScript does not transform variable names, making tractable the direct debugging of emitted JavaScript. TypeScript optionally provides source maps, enabling source-level debugging. TypeScript tools typically emit JavaScript upon file save, preserving the test, edit, refresh cycle commonly used in JavaScript development. + +TypeScript syntax includes all features of ECMAScript 2015, including classes and modules, and provides the ability to translate these features into ECMAScript 3 or 5 compliant code. + +Classes enable programmers to express common object-oriented patterns in a standard way, making features like inheritance more readable and interoperable. Modules enable programmers to organize their code into components while avoiding naming conflicts. The TypeScript compiler provides module code generation options that support either static or dynamic loading of module contents. + +TypeScript also provides to JavaScript programmers a system of optional type annotations. These type annotations are like the JSDoc comments found in the Closure system, but in TypeScript they are integrated directly into the language syntax. This integration makes the code more readable and reduces the maintenance cost of synchronizing type annotations with their corresponding variables. + +The TypeScript type system enables programmers to express limits on the capabilities of JavaScript objects, and to use tools that enforce these limits. To minimize the number of annotations needed for tools to become useful, the TypeScript type system makes extensive use of type inference. For example, from the following statement, TypeScript will infer that the variable 'i' has the type number. + +```TypeScript +var i = 0; +``` + +TypeScript will infer from the following function definition that the function f has return type string. + +```TypeScript +function f() { + return "hello"; +} +``` + +To benefit from this inference, a programmer can use the TypeScript language service. For example, a code editor can incorporate the TypeScript language service and use the service to find the members of a string object as in the following screen shot. + +  ![](images/image1.png) + +In this example, the programmer benefits from type inference without providing type annotations. Some beneficial tools, however, do require the programmer to provide type annotations. In TypeScript, we can express a parameter requirement as in the following code fragment. + +```TypeScript +function f(s: string) { + return s; +} + +f({}); // Error +f("hello"); // Ok +``` + +This optional type annotation on the parameter 's' lets the TypeScript type checker know that the programmer expects parameter 's' to be of type 'string'. Within the body of function 'f', tools can assume 's' is of type 'string' and provide operator type checking and member completion consistent with this assumption. Tools can also signal an error on the first call to 'f', because 'f' expects a string, not an object, as its parameter. For the function 'f', the TypeScript compiler will emit the following JavaScript code: + +```TypeScript +function f(s) { + return s; +} +``` + +In the JavaScript output, all type annotations have been erased. In general, TypeScript erases all type information before emiting JavaScript. + +## 1.1 Ambient Declarations + +An ambient declaration introduces a variable into a TypeScript scope, but has zero impact on the emitted JavaScript program. Programmers can use ambient declarations to tell the TypeScript compiler that some other component will supply a variable. For example, by default the TypeScript compiler will print an error for uses of undefined variables. To add some of the common variables defined by browsers, a TypeScript programmer can use ambient declarations. The following example declares the 'document' object supplied by browsers. Because the declaration does not specify a type, the type 'any' is inferred. The type 'any' means that a tool can assume nothing about the shape or behavior of the document object. Some of the examples below will illustrate how programmers can use types to further characterize the expected behavior of an object. + +```TypeScript +declare var document; +document.title = "Hello"; // Ok because document has been declared +``` + +In the case of 'document', the TypeScript compiler automatically supplies a declaration, because TypeScript by default includes a file 'lib.d.ts' that provides interface declarations for the built-in JavaScript library as well as the Document Object Model. + +The TypeScript compiler does not include by default an interface for jQuery, so to use jQuery, a programmer could supply a declaration such as: + +```TypeScript +declare var $; +``` + +Section [1.3](#1.3) provides a more extensive example of how a programmer can add type information for jQuery and other libraries. + +## 1.2 Function Types + +Function expressions are a powerful feature of JavaScript. They enable function definitions to create closures: functions that capture information from the lexical scope surrounding the function's definition. Closures are currently JavaScript's only way of enforcing data encapsulation. By capturing and using environment variables, a closure can retain information that cannot be accessed from outside the closure. JavaScript programmers often use closures to express event handlers and other asynchronous callbacks, in which another software component, such as the DOM, will call back into JavaScript through a handler function. + +TypeScript function types make it possible for programmers to express the expected *signature* of a function. A function signature is a sequence of parameter types plus a return type. The following example uses function types to express the callback signature requirements of an asynchronous voting mechanism. + +```TypeScript +function vote(candidate: string, callback: (result: string) => any) { + // ... +} + +vote("BigPig", + function(result: string) { + if (result === "BigPig") { + // ... + } + } +); +``` + +In this example, the second parameter to 'vote' has the function type + +```TypeScript +(result: string) => any +``` + +which means the second parameter is a function returning type 'any' that has a single parameter of type 'string' named 'result'. + +Section [3.9.2](#3.9.2) provides additional information about function types. + +## 1.3 Object Types + +TypeScript programmers use *object types* to declare their expectations of object behavior. The following code uses an *object type literal* to specify the return type of the 'MakePoint' function. + +```TypeScript +var MakePoint: () => { + x: number; y: number; +}; +``` + +Programmers can give names to object types; we call named object types *interfaces*. For example, in the following code, an interface declares one required field (name) and one optional field (favoriteColor). + +```TypeScript +interface Friend { + name: string; + favoriteColor?: string; +} + +function add(friend: Friend) { + var name = friend.name; +} + +add({ name: "Fred" }); // Ok +add({ favoriteColor: "blue" }); // Error, name required +add({ name: "Jill", favoriteColor: "green" }); // Ok +``` + +TypeScript object types model the diversity of behaviors that a JavaScript object can exhibit. For example, the jQuery library defines an object, '$', that has methods, such as 'get' (which sends an Ajax message), and fields, such as 'browser' (which gives browser vendor information). However, jQuery clients can also call '$' as a function. The behavior of this function depends on the type of parameters passed to the function. + +The following code fragment captures a small subset of jQuery behavior, just enough to use jQuery in a simple way. + +```TypeScript +interface JQuery { + text(content: string); +} + +interface JQueryStatic { + get(url: string, callback: (data: string) => any); + (query: string): JQuery; +} + +declare var $: JQueryStatic; + +$.get("http://mysite.org/divContent", + function (data: string) { + $("div").text(data); + } +); +``` + +The 'JQueryStatic' interface references another interface: 'JQuery'. This interface represents a collection of one or more DOM elements. The jQuery library can perform many operations on such a collection, but in this example the jQuery client only needs to know that it can set the text content of each jQuery element in a collection by passing a string to the 'text' method. The 'JQueryStatic' interface also contains a method, 'get', that performs an Ajax get operation on the provided URL and arranges to invoke the provided callback upon receipt of a response. + +Finally, the 'JQueryStatic' interface contains a bare function signature + +```TypeScript +(query: string): JQuery; +``` + +The bare signature indicates that instances of the interface are callable. This example illustrates that TypeScript function types are just special cases of TypeScript object types. Specifically, function types are object types that contain one or more call signatures. For this reason we can write any function type as an object type literal. The following example uses both forms to describe the same type. + +```TypeScript +var f: { (): string; }; +var sameType: () => string = f; // Ok +var nope: () => number = sameType; // Error: type mismatch +``` + +We mentioned above that the '$' function behaves differently depending on the type of its parameter. So far, our jQuery typing only captures one of these behaviors: return an object of type 'JQuery' when passed a string. To specify multiple behaviors, TypeScript supports *overloading* of function signatures in object types. For example, we can add an additional call signature to the 'JQueryStatic' interface. + +```TypeScript +(ready: () => any): any; +``` + +This signature denotes that a function may be passed as the parameter of the '$' function. When a function is passed to '$', the jQuery library will invoke that function when a DOM document is ready. Because TypeScript supports overloading, tools can use TypeScript to show all available function signatures with their documentation tips and to give the correct documentation once a function has been called with a particular signature. + +A typical client would not need to add any additional typing but could just use a community-supplied typing to discover (through statement completion with documentation tips) and verify (through static checking) correct use of the library, as in the following screen shot. + +  ![](images/image2.png) + +Section [3.3](#3.3) provides additional information about object types. + +## 1.4 Structural Subtyping + +Object types are compared *structurally*. For example, in the code fragment below, class 'CPoint' matches interface 'Point' because 'CPoint' has all of the required members of 'Point'. A class may optionally declare that it implements an interface, so that the compiler will check the declaration for structural compatibility. The example also illustrates that an object type can match the type inferred from an object literal, as long as the object literal supplies all of the required members. + +```TypeScript +interface Point { + x: number; + y: number; +} + +function getX(p: Point) { + return p.x; +} + +class CPoint { + x: number; + y: number; + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } +} + +getX(new CPoint(0, 0)); // Ok, fields match + +getX({ x: 0, y: 0, color: "red" }); // Extra fields Ok + +getX({ x: 0 }); // Error: supplied parameter does not match +``` + +See section [3.11](#3.11) for more information about type comparisons. + +## 1.5 Contextual Typing + +Ordinarily, TypeScript type inference proceeds "bottom-up": from the leaves of an expression tree to its root. In the following example, TypeScript infers 'number' as the return type of the function 'mul' by flowing type information bottom up in the return expression. + +```TypeScript +function mul(a: number, b: number) { + return a * b; +} +``` + +For variables and parameters without a type annotation or a default value, TypeScript infers type 'any', ensuring that compilers do not need non-local information about a function's call sites to infer the function's return type. Generally, this bottom-up approach provides programmers with a clear intuition about the flow of type information. + +However, in some limited contexts, inference proceeds "top-down" from the context of an expression. Where this happens, it is called contextual typing. Contextual typing helps tools provide excellent information when a programmer is using a type but may not know all of the details of the type. For example, in the jQuery example, above, the programmer supplies a function expression as the second parameter to the 'get' method. During typing of that expression, tools can assume that the type of the function expression is as given in the 'get' signature and can provide a template that includes parameter names and types. + +```TypeScript +$.get("http://mysite.org/divContent", + function (data) { + $("div").text(data); // TypeScript infers data is a string + } +); +``` + +Contextual typing is also useful for writing out object literals. As the programmer types the object literal, the contextual type provides information that enables tools to provide completion for object member names. + +Section [4.23](#4.23) provides additional information about contextually typed expressions. + +## 1.6 Classes + +JavaScript practice has two very common design patterns: the module pattern and the class pattern. Roughly speaking, the module pattern uses closures to hide names and to encapsulate private data, while the class pattern uses prototype chains to implement many variations on object-oriented inheritance mechanisms. Libraries such as 'prototype.js' are typical of this practice. TypeScript's namespaces are a formalization of the module pattern. (The term "module pattern" is somewhat unfortunate now that ECMAScript 2015 formally supports modules in a manner different from what the module pattern prescribes. For this reason, TypeScript uses the term "namespace" for its formalization of the module pattern.) + +This section and the namespace section below will show how TypeScript emits consistent, idiomatic JavaScript when emitting ECMAScript 3 or 5 compliant code for classes and namespaces. The goal of TypeScript's translation is to emit exactly what a programmer would type when implementing a class or namespace unaided by a tool. This section will also describe how TypeScript infers a type for each class declaration. We'll start with a simple BankAccount class. + +```TypeScript +class BankAccount { + balance = 0; + deposit(credit: number) { + this.balance += credit; + return this.balance; + } +} +``` + +This class generates the following JavaScript code. + +```TypeScript +var BankAccount = (function () { + function BankAccount() { + this.balance = 0; + } + BankAccount.prototype.deposit = function(credit) { + this.balance += credit; + return this.balance; + }; + return BankAccount; +})(); +``` + +This TypeScript class declaration creates a variable named 'BankAccount' whose value is the constructor function for 'BankAccount' instances. This declaration also creates an instance type of the same name. If we were to write this type as an interface it would look like the following. + +```TypeScript +interface BankAccount { + balance: number; + deposit(credit: number): number; +} +``` + +If we were to write out the function type declaration for the 'BankAccount' constructor variable, it would have the following form. + +```TypeScript +var BankAccount: new() => BankAccount; +``` + +The function signature is prefixed with the keyword 'new' indicating that the 'BankAccount' function must be called as a constructor. It is possible for a function's type to have both call and constructor signatures. For example, the type of the built-in JavaScript Date object includes both kinds of signatures. + +If we want to start our bank account with an initial balance, we can add to the 'BankAccount' class a constructor declaration. + +```TypeScript +class BankAccount { + balance: number; + constructor(initially: number) { + this.balance = initially; + } + deposit(credit: number) { + this.balance += credit; + return this.balance; + } +} +``` + +This version of the 'BankAccount' class requires us to introduce a constructor parameter and then assign it to the 'balance' field. To simplify this common case, TypeScript accepts the following shorthand syntax. + +```TypeScript +class BankAccount { + constructor(public balance: number) { + } + deposit(credit: number) { + this.balance += credit; + return this.balance; + } +} +``` + +The 'public' keyword denotes that the constructor parameter is to be retained as a field. Public is the default accessibility for class members, but a programmer can also specify private or protected accessibility for a class member. Accessibility is a design-time construct; it is enforced during static type checking but does not imply any runtime enforcement. + +TypeScript classes also support inheritance, as in the following example.* * + +```TypeScript +class CheckingAccount extends BankAccount { + constructor(balance: number) { + super(balance); + } + writeCheck(debit: number) { + this.balance -= debit; + } +} +``` + +In this example, the class 'CheckingAccount' *derives* from class 'BankAccount'. The constructor for 'CheckingAccount' calls the constructor for class 'BankAccount' using the 'super' keyword. In the emitted JavaScript code, the prototype of 'CheckingAccount' will chain to the prototype of 'BankAccount'. + +TypeScript classes may also specify static members. Static class members become properties of the class constructor. + +Section [8](#8) provides additional information about classes. + +## 1.7 Enum Types + +TypeScript enables programmers to summarize a set of numeric constants as an *enum type*. The example below creates an enum type to represent operators in a calculator application. + +```TypeScript +const enum Operator { + ADD, + DIV, + MUL, + SUB +} + +function compute(op: Operator, a: number, b: number) { + console.log("the operator is" + Operator[op]); + // ... +} +``` + +In this example, the compute function logs the operator 'op' using a feature of enum types: reverse mapping from the enum value ('op') to the string corresponding to that value. For example, the declaration of 'Operator' automatically assigns integers, starting from zero, to the listed enum members. Section [9](#9) describes how programmers can also explicitly assign integers to enum members, and can use any string to name an enum member. + +When enums are declared with the `const` modifier, the TypeScript compiler will emit for an enum member a JavaScript constant corresponding to that member's assigned value (annotated with a comment). This improves performance on many JavaScript engines. + +For example, the 'compute' function could contain a switch statement like the following. + +```TypeScript +switch (op) { + case Operator.ADD: + // execute add + break; + case Operator.DIV: + // execute div + break; + // ... +} +``` + +For this switch statement, the compiler will generate the following code. + +```TypeScript +switch (op) { + case 0 /* Operator.ADD */: + // execute add + break; + case 1 /* Operator.DIV */: + // execute div + break; + // ... +} +``` + +JavaScript implementations can use these explicit constants to generate efficient code for this switch statement, for example by building a jump table indexed by case value. + +## 1.8 Overloading on String Parameters + +An important goal of TypeScript is to provide accurate and straightforward types for existing JavaScript programming patterns. To that end, TypeScript includes generic types, discussed in the next section, and *overloading on string parameters*, the topic of this section. + +JavaScript programming interfaces often include functions whose behavior is discriminated by a string constant passed to the function. The Document Object Model makes heavy use of this pattern. For example, the following screen shot shows that the 'createElement' method of the 'document' object has multiple signatures, some of which identify the types returned when specific strings are passed into the method. + +  ![](images/image3.png) + +The following code fragment uses this feature. Because the 'span' variable is inferred to have the type 'HTMLSpanElement', the code can reference without static error the 'isMultiline' property of 'span'. + +```TypeScript +var span = document.createElement("span"); +span.isMultiLine = false; // OK: HTMLSpanElement has isMultiline property +``` + +In the following screen shot, a programming tool combines information from overloading on string parameters with contextual typing to infer that the type of the variable 'e' is 'MouseEvent' and that therefore 'e' has a 'clientX' property. + +  ![](images/image4.png) + +Section [3.9.2.4](#3.9.2.4) provides details on how to use string literals in function signatures. + +## 1.9 Generic Types and Functions + +Like overloading on string parameters, *generic types* make it easier for TypeScript to accurately capture the behavior of JavaScript libraries. Because they enable type information to flow from client code, through library code, and back into client code, generic types may do more than any other TypeScript feature to support detailed API descriptions. + +To illustrate this, let's take a look at part of the TypeScript interface for the built-in JavaScript array type. You can find this interface in the 'lib.d.ts' file that accompanies a TypeScript distribution. + +```TypeScript +interface Array { + reverse(): T[]; + sort(compareFn?: (a: T, b: T) => number): T[]; + // ... +} +``` + +Interface definitions, like the one above, can have one or more *type parameters*. In this case the 'Array' interface has a single parameter, 'T', that defines the element type for the array. The 'reverse' method returns an array with the same element type. The sort method takes an optional parameter, 'compareFn', whose type is a function that takes two parameters of type 'T' and returns a number. Finally, sort returns an array with element type 'T'. + +Functions can also have generic parameters. For example, the array interface contains a 'map' method, defined as follows: + +```TypeScript +map(func: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; +``` + +The map method, invoked on an array 'a' with element type 'T', will apply function 'func' to each element of 'a', returning a value of type 'U'. + +The TypeScript compiler can often infer generic method parameters, making it unnecessary for the programmer to explicitly provide them. In the following example, the compiler infers that parameter 'U' of the map method has type 'string', because the function passed to map returns a string. + +```TypeScript +function numberToString(a: number[]) { + var stringArray = a.map(v => v.toString()); + return stringArray; +} +``` + +The compiler infers in this example that the 'numberToString' function returns an array of strings. + +In TypeScript, classes can also have type parameters. The following code declares a class that implements a linked list of items of type 'T'. This code illustrates how programmers can *constrain* type parameters to extend a specific type. In this case, the items on the list must extend the type 'NamedItem'. This enables the programmer to implement the 'log' function, which logs the name of the item. + +```TypeScript +interface NamedItem { + name: string; +} + +class List { + next: List = null; + + constructor(public item: T) { + } + + insertAfter(item: T) { + var temp = this.next; + this.next = new List(item); + this.next.next = temp; + } + + log() { + console.log(this.item.name); + } + + // ... +} +``` + +Section [3.7](#3.7) provides further information about generic types. + +## 1.10 Namespaces + +Classes and interfaces support large-scale JavaScript development by providing a mechanism for describing how to use a software component that can be separated from that component's implementation. TypeScript enforces *encapsulation* of implementation in classes at design time (by restricting use of private and protected members), but cannot enforce encapsulation at runtime because all object properties are accessible at runtime. Future versions of JavaScript may provide *private names* which would enable runtime enforcement of private and protected members. + +In JavaScript, a very common way to enforce encapsulation at runtime is to use the module pattern: encapsulate private fields and methods using closure variables. The module pattern is a natural way to provide organizational structure and dynamic loading options by drawing a boundary around a software component. The module pattern can also provide the ability to introduce namespaces, avoiding use of the global namespace for most software components. + +The following example illustrates the JavaScript module pattern. + +```TypeScript +(function(exports) { + var key = generateSecretKey(); + function sendMessage(message) { + sendSecureMessage(message, key); + } + exports.sendMessage = sendMessage; +})(MessageModule); +``` + +This example illustrates the two essential elements of the module pattern: a *module closure* and a *module* *object*. The module closure is a function that encapsulates the module's implementation, in this case the variable 'key' and the function 'sendMessage'. The module object contains the exported variables and functions of the module. Simple modules may create and return the module object. The module above takes the module object as a parameter, 'exports', and adds the 'sendMessage' property to the module object. This *augmentation* approach simplifies dynamic loading of modules and also supports separation of module code into multiple files. + +The example assumes that an outer lexical scope defines the functions 'generateSecretKey' and 'sendSecureMessage'; it also assumes that the outer scope has assigned the module object to the variable 'MessageModule'. + +TypeScript namespaces provide a mechanism for succinctly expressing the module pattern. In TypeScript, programmers can combine the module pattern with the class pattern by nesting namespaces and classes within an outer namespace. + +The following example shows the definition and use of a simple namespace. + +```TypeScript +namespace M { + var s = "hello"; + export function f() { + return s; + } +} + +M.f(); +M.s; // Error, s is not exported +``` + +In this example, variable 's' is a private feature of the namespace, but function 'f' is exported from the namespace and accessible to code outside of the namespace. If we were to describe the effect of namespace 'M' in terms of interfaces and variables, we would write + +```TypeScript +interface M { + f(): string; +} + +var M: M; +``` + +The interface 'M' summarizes the externally visible behavior of namespace 'M'. In this example, we can use the same name for the interface as for the initialized variable because in TypeScript type names and variable names do not conflict: each lexical scope contains a variable declaration space and type declaration space (see section [2.3](#2.3) for more details). + +The TypeScript compiler emits the following JavaScript code for the namespace: + +```TypeScript +var M; +(function(M) { + var s = "hello"; + function f() { + return s; + } + M.f = f; +})(M || (M = {})); +``` + +In this case, the compiler assumes that the namespace object resides in global variable 'M', which may or may not have been initialized to the desired namespace object. + +## 1.11 Modules + +TypeScript also supports ECMAScript 2015 modules, which are files that contain top-level *export* and *import* directives. For this type of module the TypeScript compiler can emit both ECMAScript 2015 compliant code and down-level ECMAScript 3 or 5 compliant code for a variety of module loading systems, including CommonJS, Asynchronous Module Definition (AMD), and Universal Module Definition (UMD). + +
+ +#
2 Basic Concepts + +The remainder of this document is the formal specification of the TypeScript programming language and is intended to be read as an adjunct to the [ECMAScript 2015 Language Specification](http://www.ecma-international.org/ecma-262/6.0/) (specifically, the ECMA-262 Standard, 6th Edition). This document describes the syntactic grammar added by TypeScript along with the compile-time processing and type checking performed by the TypeScript compiler, but it only minimally discusses the run-time behavior of programs since that is covered by the ECMAScript specification. + +## 2.1 Grammar Conventions + +The syntactic grammar added by TypeScript language is specified throughout this document using the existing conventions and production names of the ECMAScript grammar. In places where TypeScript augments an existing grammar production it is so noted. For example: + +  *Declaration:* *( Modified )* +   … +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *EnumDeclaration* + +The '*( Modified )*' annotation indicates that an existing grammar production is being replaced, and the '…' references the contents of the original grammar production. + +Similar to the ECMAScript grammar, if the phrase "*[no LineTerminator here]*" appears in the right-hand side of a production of the syntactic grammar, it indicates that the production is not a match if a *LineTerminator* occurs in the input stream at the indicated position. + +## 2.2 Names + +A core purpose of the TypeScript compiler is to track the named entities in a program and validate that they are used according to their designated meaning. Names in TypeScript can be written in several ways, depending on context. Specifically, a name can be written as + +* an *IdentifierName*, +* a *StringLiteral* in a property name, +* a *NumericLiteral* in a property name, or +* a *ComputedPropertyName* that denotes a well-known symbol ([2.2.3](#2.2.3)). + +Most commonly, names are written to conform with the *Identifier* production, which is any *IdentifierName* that isn't a reserved word. + +### 2.2.1 Reserved Words + +The following keywords are reserved and cannot be used as an *Identifier*: + +```TypeScript +break case catch class +const continue debugger default +delete do else enum +export extends false finally +for function if import +in instanceof new null +return super switch this +throw true try typeof +var void while with +``` + +The following keywords cannot be used as identifiers in strict mode code, but are otherwise not restricted: + +```TypeScript +implements interface let package +private protected public static +yield +``` + +The following keywords cannot be used as user defined type names, but are otherwise not restricted: + +```TypeScript +any boolean number string +symbol +``` + +The following keywords have special meaning in certain contexts, but are valid identifiers: + +```TypeScript +abstract as async await +constructor declare from get +is module namespace of +require set type +``` + +### 2.2.2 Property Names + +The *PropertyName* production from the ECMAScript grammar is reproduced below: + +  *PropertyName:* +   *LiteralPropertyName* +   *ComputedPropertyName* + +  *LiteralPropertyName:* +   *IdentifierName* +   *StringLiteral* +   *NumericLiteral* + +  *ComputedPropertyName:* +   `[` *AssignmentExpression* `]` + +A property name can be any identifier (including a reserved word), a string literal, a numeric literal, or a computed property name. String literals may be used to give properties names that are not valid identifiers, such as names containing blanks. Numeric literal property names are equivalent to string literal property names with the string representation of the numeric literal, as defined in the ECMAScript specification. + +### 2.2.3 Computed Property Names + +ECMAScript 2015 permits object literals and classes to declare members with computed property names. A computed property name specifies an expression that computes the actual property name at run-time. Because the final property name isn't known at compile-time, TypeScript can only perform limited checks for entities declared with computed property names. However, a subset of computed property names known as ***well-known symbols*** can be used anywhere a *PropertyName* is expected, including property names within types. A computed property name is a well-known symbol if it is of the form + +```TypeScript +[ Symbol . xxx ] +``` + +In a well-known symbol, the identifier to the right of the dot must denote a property of the primitive type `symbol` in the type of the global variable 'Symbol', or otherwise an error occurs. + +In a *PropertyName* that specifies a *ComputedPropertyName*, the computed property name is required to denote a well-known symbol unless the property name occurs in a property assignment of an object literal ([4.5](#4.5)) or a property member declaration in a non-ambient class ([8.4](#8.4)). + +Below is an example of an interface that declares a property with a well-known symbol name: + +```TypeScript +interface Iterable { + [Symbol.iterator](): Iterator; +} +``` + +*TODO: Update to reflect treatment of [computed property names with literal expressions](https://github.com/Microsoft/TypeScript/pull/5535)*. + +## 2.3 Declarations + +Declarations introduce names in their associated ***declaration spaces***. A name must be unique in its declaration space and can denote a ***value***, a ***type***, or a ***namespace***, or some combination thereof. Effectively, a single name can have as many as three distinct meanings. For example: + +```TypeScript +var X: string; // Value named X + +type X = number; // Type named X + +namespace X { // Namespace named X + type Y = string; +} +``` + +A name that denotes a value has an associated type (section [3](#3)) and can be referenced in expressions (section [4.3](#4.3)). A name that denotes a type can be used by itself in a type reference or on the right hand side of a dot in a type reference ([3.8.2](#3.8.2)). A name that denotes a namespace can be used one the left hand side of a dot in a type reference. + +When a name with multiple meanings is referenced, the context in which the reference occurs determines the meaning. For example: + +```TypeScript +var n: X; // X references type +var s: X.Y = X; // First X references namespace, second X references value +``` + +In the first line, X references the type X because it occurs in a type position. In the second line, the first X references the namespace X because it occurs before a dot in a type name, and the second X references the variable X because it occurs in an expression. + +Declarations introduce the following meanings for the name they declare: + +* A variable, parameter, function, generator, member variable, member function, member accessor, or enum member declaration introduces a value meaning. +* An interface, type alias, or type parameter declaration introduces a type meaning. +* A class declaration introduces a value meaning (the constructor function) and a type meaning (the class type). +* An enum declaration introduces a value meaning (the enum instance) and a type meaning (the enum type). +* A namespace declaration introduces a namespace meaning (the type and namespace container) and, if the namespace is instantiated (section [10.1](#10.1)), a value meaning (the namespace instance). +* An import or export declaration introduces the meaning(s) of the imported or exported entity. + +Below are some examples of declarations that introduce multiple meanings for a name: + +```TypeScript +class C { // Value and type named C + x: string; +} + +namespace N { // Value and namespace named N + export var x: string; +} +``` + +Declaration spaces exist as follows: + +* The global namespace, each module, and each declared namespace has a declaration space for its contained entities (whether local or exported). +* Each module has a declaration space for its exported entities. All export declarations in the module contribute to this declaration space. +* Each declared namespace has a declaration space for its exported entities. All export declarations in the namespace contribute to this declaration space. A declared namespace’s declaration space is shared with other declared namespaces that have the same root container and the same qualified name starting from that root container. +* Each class declaration has a declaration space for instance members and type parameters, and a declaration space for static members. +* Each interface declaration has a declaration space for members and type parameters. An interface's declaration space is shared with other interfaces that have the same root container and the same qualified name starting from that root container. +* Each enum declaration has a declaration space for its enum members. An enum's declaration space is shared with other enums that have the same root container and the same qualified name starting from that root container. +* Each type alias declaration has a declaration space for its type parameters. +* Each function-like declaration (including function declarations, constructor declarations, member function declarations, member accessor declarations, function expressions, and arrow functions) has a declaration space for locals and type parameters. This declaration space includes parameter declarations, all local var and function declarations, and local let, const, class, interface, type alias, and enum declarations that occur immediately within the function body and are not further nested in blocks. +* Each statement block has a declaration space for local let, const, class, interface, type alias, and enum declarations that occur immediately within that block. +* Each object literal has a declaration space for its properties. +* Each object type literal has a declaration space for its members. + +Top-level declarations in a source file with no top-level import or export declarations belong to the ***global namespace***. Top-level declarations in a source file with one or more top-level import or export declarations belong to the ***module*** represented by that source file. + +The ***container*** of an entity is defined as follows: + +* The container of an entity declared in a namespace declaration is that namespace declaration. +* The container of an entity declared in a module is that module. +* The container of an entity declared in the global namespace is the global namespace. +* The container of a module is the global namespace. + +The ***root container*** of an entity is defined as follows: + +* The root container of a non-exported entity is the entity’s container. +* The root container of an exported entity is the root container of the entity's container. + +Intuitively, the root container of an entity is the outermost module or namespace body from within which the entity is reachable. + +Interfaces, enums, and namespaces are "open ended," meaning that interface, enum, and namespace declarations with the same qualified name relative to a common root are automatically merged. For further details, see sections [7.2](#7.2), [9.3](#9.3), and [10.5](#10.5). + +Instance and static members in a class are in separate declaration spaces. Thus the following is permitted: + +```TypeScript +class C { + x: number; // Instance member + static x: string; // Static member +} +``` + +## 2.4 Scopes + +The ***scope*** of a name is the region of program text within which it is possible to refer to the entity declared by that name without qualification of the name. The scope of a name depends on the context in which the name is declared. The contexts are listed below in order from outermost to innermost: + +* The scope of a name declared in the global namespace is the entire program text. +* The scope of a name declared in a module is the source file of that module. +* The scope of an exported name declared within a namespace declaration is the body of that namespace declaration and every namespace declaration with the same root and the same qualified name relative to that root. +* The scope of a non-exported name declared within a namespace declaration is the body of that namespace declaration. +* The scope of a type parameter name declared in a class or interface declaration is that entire declaration, including constraints, extends clause, implements clause, and declaration body, but not including static member declarations. +* The scope of a type parameter name declared in a type alias declaration is that entire type alias declaration. +* The scope of a member name declared in an enum declaration is the body of that declaration and every enum declaration with the same root and the same qualified name relative to that root. +* The scope of a type parameter name declared in a call or construct signature is that entire signature declaration, including constraints, parameter list, and return type. If the signature is part of a function implementation, the scope includes the function body. +* The scope of a parameter name declared in a call or construct signature is the remainder of the signature declaration. If the signature is part of a function-like declaration with a body (including a function declaration, constructor declaration, member function declaration, member accessor declaration, function expression, or arrow function), the scope includes the body of that function-like declaration. +* The scope of a local var or function name declared anywhere in the body of a function-like declaration is the body of that function-like declaration. +* The scope of a local let, const, class, interface, type alias, or enum declaration declared immediately within the body of a function-like declaration is the body of that function-like declaration. +* The scope of a local let, const, class, interface, type alias, or enum declaration declared immediately within a statement block is the body of that statement block. + +Scopes may overlap, for example through nesting of namespaces and functions. When the scopes of two names overlap, the name with the innermost declaration takes precedence and access to the outer name is either not possible or only possible by qualification. + +When an identifier is resolved as a *PrimaryExpression* (section [4.3](#4.3)), only names in scope with a value meaning are considered and other names are ignored. + +When an identifier is resolved as a *TypeName* (section [3.8.2](#3.8.2)), only names in scope with a type meaning are considered and other names are ignored. + +When an identifier is resolved as a *NamespaceName* (section [3.8.2](#3.8.2)), only names in scope with a namespace meaning are considered and other names are ignored. + +*TODO: [Include specific rules for alias resolution](https://github.com/Microsoft/TypeScript/issues/3158)*. + +Note that class and interface members are never directly in scope—they can only be accessed by applying the dot ('.') operator to a class or interface instance. This even includes members of the current instance in a constructor or member function, which are accessed by applying the dot operator to `this`. + +As the rules above imply, locally declared entities in a namespace are closer in scope than exported entities declared in other namespace declarations for the same namespace. For example: + +```TypeScript +var x = 1; +namespace M { + export var x = 2; + console.log(x); // 2 +} +namespace M { + console.log(x); // 2 +} +namespace M { + var x = 3; + console.log(x); // 3 +} +``` + +
+ +#
3 Types + +TypeScript adds optional static types to JavaScript. Types are used to place static constraints on program entities such as functions, variables, and properties so that compilers and development tools can offer better verification and assistance during software development. TypeScript's *static* compile-time type system closely models the *dynamic* run-time type system of JavaScript, allowing programmers to accurately express the type relationships that are expected to exist when their programs run and have those assumptions pre-validated by the TypeScript compiler. TypeScript's type analysis occurs entirely at compile-time and adds no run-time overhead to program execution. + +All types in TypeScript are subtypes of a single top type called the Any type. The `any` keyword references this type. The Any type is the one type that can represent *any* JavaScript value with no constraints. All other types are categorized as ***primitive types***, ***object types***, ***union types***, ***intersection types***, or ***type parameters***. These types introduce various static constraints on their values. + +The primitive types are the Number, Boolean, String, Symbol, Void, Null, and Undefined types along with user defined enum types. The `number`, `boolean`, `string`, `symbol`, and `void` keywords reference the Number, Boolean, String, Symbol, and Void primitive types respectively. The Void type exists purely to indicate the absence of a value, such as in a function with no return value. It is not possible to explicitly reference the Null and Undefined types—only *values* of those types can be referenced, using the `null` and `undefined` literals. + +The object types are all class, interface, array, tuple, function, and constructor types. Class and interface types are introduced through class and interface declarations and are referenced by the name given to them in their declarations. Class and interface types may be ***generic types*** which have one or more type parameters. + +Union types represent values that have one of multiple types, and intersection types represent values that simultaneously have more than one type. + +Declarations of classes, properties, functions, variables and other language entities associate types with those entities. The mechanism by which a type is formed and associated with a language entity depends on the particular kind of entity. For example, a namespace declaration associates the namespace with an anonymous type containing a set of properties corresponding to the exported variables and functions in the namespace, and a function declaration associates the function with an anonymous type containing a call signature corresponding to the parameters and return type of the function. Types can be associated with variables through explicit ***type annotations***, such as + +```TypeScript +var x: number; +``` + +or through implicit ***type inference***, as in + +```TypeScript +var x = 1; +``` + +which infers the type of 'x' to be the Number primitive type because that is the type of the value used to initialize 'x'. + +## 3.1 The Any Type + +The Any type is used to represent any JavaScript value. A value of the Any type supports the same operations as a value in JavaScript and minimal static type checking is performed for operations on Any values. Specifically, properties of any name can be accessed through an Any value and Any values can be called as functions or constructors with any argument list. + +The `any` keyword references the Any type. In general, in places where a type is not explicitly provided and TypeScript cannot infer one, the Any type is assumed. + +The Any type is a supertype of all types, and is assignable to and from all types. + +Some examples: + +```TypeScript +var x: any; // Explicitly typed +var y; // Same as y: any +var z: { a; b; }; // Same as z: { a: any; b: any; } + +function f(x) { // Same as f(x: any): void + console.log(x); +} +``` + +## 3.2 Primitive Types + +The primitive types are the Number, Boolean, String, Symbol, Void, Null, and Undefined types and all user defined enum types. + +### 3.2.1 The Number Type + +The Number primitive type corresponds to the similarly named JavaScript primitive type and represents double-precision 64-bit format IEEE 754 floating point values. + +The `number` keyword references the Number primitive type and numeric literals may be used to write values of the Number primitive type. + +For purposes of determining type relationships (section [3.11](#3.11)) and accessing properties (section [4.13](#4.13)), the Number primitive type behaves as an object type with the same properties as the global interface type 'Number'. + +Some examples: + +```TypeScript +var x: number; // Explicitly typed +var y = 0; // Same as y: number = 0 +var z = 123.456; // Same as z: number = 123.456 +var s = z.toFixed(2); // Property of Number interface +``` + +### 3.2.2 The Boolean Type + +The Boolean primitive type corresponds to the similarly named JavaScript primitive type and represents logical values that are either true or false. + +The `boolean` keyword references the Boolean primitive type and the `true` and `false` literals reference the two Boolean truth values. + +For purposes of determining type relationships (section [3.11](#3.11)) and accessing properties (section [4.13](#4.13)), the Boolean primitive type behaves as an object type with the same properties as the global interface type 'Boolean'. + +Some examples: + +```TypeScript +var b: boolean; // Explicitly typed +var yes = true; // Same as yes: boolean = true +var no = false; // Same as no: boolean = false +``` + +### 3.2.3 The String Type + +The String primitive type corresponds to the similarly named JavaScript primitive type and represents sequences of characters stored as Unicode UTF-16 code units. + +The `string` keyword references the String primitive type and string literals may be used to write values of the String primitive type. + +For purposes of determining type relationships (section [3.11](#3.11)) and accessing properties (section [4.13](#4.13)), the String primitive type behaves as an object type with the same properties as the global interface type 'String'. + +Some examples: + +```TypeScript +var s: string; // Explicitly typed +var empty = ""; // Same as empty: string = "" +var abc = 'abc'; // Same as abc: string = "abc" +var c = abc.charAt(2); // Property of String interface +``` + +### 3.2.4 The Symbol Type + +The Symbol primitive type corresponds to the similarly named JavaScript primitive type and represents unique tokens that may be used as keys for object properties. + +The `symbol` keyword references the Symbol primitive type. Symbol values are obtained using the global object 'Symbol' which has a number of methods and properties and can be invoked as a function. In particular, the global object 'Symbol' defines a number of well-known symbols ([2.2.3](#2.2.3)) that can be used in a manner similar to identifiers. Note that the 'Symbol' object is available only in ECMAScript 2015 environments. + +For purposes of determining type relationships (section [3.11](#3.11)) and accessing properties (section [4.13](#4.13)), the Symbol primitive type behaves as an object type with the same properties as the global interface type 'Symbol'. + +Some examples: + +```TypeScript +var secretKey = Symbol(); +var obj = {}; +obj[secretKey] = "secret message"; // Use symbol as property key +obj[Symbol.toStringTag] = "test"; // Use of well-known symbol +``` + +### 3.2.5 The Void Type + +The Void type, referenced by the `void` keyword, represents the absence of a value and is used as the return type of functions with no return value. + +The only possible values for the Void type are `null` and `undefined`. The Void type is a subtype of the Any type and a supertype of the Null and Undefined types, but otherwise Void is unrelated to all other types. + +*NOTE: We might consider disallowing declaring variables of type Void as they serve no useful purpose. However, because Void is permitted as a type argument to a generic type or function it is not feasible to disallow Void properties or parameters*. + +### 3.2.6 The Null Type + +The Null type corresponds to the similarly named JavaScript primitive type and is the type of the `null` literal. + +The `null` literal references the one and only value of the Null type. It is not possible to directly reference the Null type itself. + +The Null type is a subtype of all types, except the Undefined type. This means that `null` is considered a valid value for all primitive types, object types, union types, intersection types, and type parameters, including even the Number and Boolean primitive types. + +Some examples: + +```TypeScript +var n: number = null; // Primitives can be null +var x = null; // Same as x: any = null +var e: Null; // Error, can't reference Null type +``` + +### 3.2.7 The Undefined Type + +The Undefined type corresponds to the similarly named JavaScript primitive type and is the type of the `undefined` literal. + +The `undefined` literal denotes the value given to all uninitialized variables and is the one and only value of the Undefined type. It is not possible to directly reference the Undefined type itself. + +The undefined type is a subtype of all types. This means that `undefined` is considered a valid value for all primitive types, object types, union types, intersection types, and type parameters. + +Some examples: + +```TypeScript +var n: number; // Same as n: number = undefined +var x = undefined; // Same as x: any = undefined +var e: Undefined; // Error, can't reference Undefined type +``` + +### 3.2.8 Enum Types + +Enum types are distinct user defined subtypes of the Number primitive type. Enum types are declared using enum declarations (section [9.1](#9.1)) and referenced using type references (section [3.8.2](#3.8.2)). + +Enum types are assignable to the Number primitive type, and vice versa, but different enum types are not assignable to each other. + +### 3.2.9 String Literal Types + +Specialized signatures (section [3.9.2.4](#3.9.2.4)) permit string literals to be used as types in parameter type annotations. String literal types are permitted only in that context and nowhere else. + +All string literal types are subtypes of the String primitive type. + +*TODO: Update to reflect [expanded support for string literal types](https://github.com/Microsoft/TypeScript/pull/5185)*. + +## 3.3 Object Types + +Object types are composed from properties, call signatures, construct signatures, and index signatures, collectively called members. + +Class and interface type references, array types, tuple types, function types, and constructor types are all classified as object types. Multiple constructs in the TypeScript language create object types, including: + +* Object type literals (section [3.8.3](#3.8.3)). +* Array type literals (section [3.8.4](#3.8.4)). +* Tuple type literals (section [3.8.5](#3.8.5)). +* Function type literals (section [3.8.8](#3.8.8)). +* Constructor type literals (section [3.8.9](#3.8.9)). +* Object literals (section [4.5](#4.5)). +* Array literals (section [4.6](#4.6)). +* Function expressions (section [4.10](#4.10)) and function declarations ([6.1](#6.1)). +* Constructor function types created by class declarations (section [8.2.5](#8.2.5)). +* Namespace instance types created by namespace declarations (section [10.3](#10.3)). + +### 3.3.1 Named Type References + +Type references (section [3.8.2](#3.8.2)) to class and interface types are classified as object types. Type references to generic class and interface types include type arguments that are substituted for the type parameters of the class or interface to produce an actual object type. + +### 3.3.2 Array Types + +***Array types*** represent JavaScript arrays with a common element type. Array types are named type references created from the generic interface type 'Array' in the global namespace with the array element type as a type argument. Array type literals (section [3.8.4](#3.8.4)) provide a shorthand notation for creating such references. + +The declaration of the 'Array' interface includes a property 'length' and a numeric index signature for the element type, along with other members: + +```TypeScript +interface Array { + length: number; + [x: number]: T; + // Other members +} +``` + +Array literals (section [4.6](#4.6)) may be used to create values of array types. For example + +```TypeScript +var a: string[] = ["hello", "world"]; +``` + +A type is said to be an ***array-like type*** if it is assignable (section [3.11.4](#3.11.4)) to the type `any[]`. + +### 3.3.3 Tuple Types + +***Tuple types*** represent JavaScript arrays with individually tracked element types. Tuple types are written using tuple type literals (section [3.8.5](#3.8.5)). A tuple type combines a set of numerically named properties with the members of an array type. Specifically, a tuple type + +```TypeScript +[ T0, T1, ..., Tn ] +``` + +combines the set of properties + +```TypeScript +{ + 0: T0; + 1: T1; + ... + n: Tn; +} +``` + +with the members of an array type whose element type is the union type (section [3.4](#3.4)) of the tuple element types. + +Array literals (section [4.6](#4.6)) may be used to create values of tuple types. For example: + +```TypeScript +var t: [number, string] = [3, "three"]; +var n = t[0]; // Type of n is number +var s = t[1]; // Type of s is string +var i: number; +var x = t[i]; // Type of x is number | string +``` + +Named tuple types can be created by declaring interfaces that derive from Array<T> and introduce numerically named properties. For example: + +```TypeScript +interface KeyValuePair extends Array { 0: K; 1: V; } + +var x: KeyValuePair = [10, "ten"]; +``` + +A type is said to be a ***tuple-like type*** if it has a property with the numeric name '0'. + +### 3.3.4 Function Types + +An object type containing one or more call signatures is said to be a ***function type***. Function types may be written using function type literals (section [3.8.8](#3.8.8)) or by including call signatures in object type literals. + +### 3.3.5 Constructor Types + +An object type containing one or more construct signatures is said to be a ***constructor type***. Constructor types may be written using constructor type literals (section [3.8.9](#3.8.9)) or by including construct signatures in object type literals. + +### 3.3.6 Members + +Every object type is composed from zero or more of the following kinds of members: + +* ***Properties***, which define the names and types of the properties of objects of the given type. Property names are unique within their type. +* ***Call signatures***, which define the possible parameter lists and return types associated with applying call operations to objects of the given type. +* ***Construct signatures***, which define the possible parameter lists and return types associated with applying the `new` operator to objects of the given type. +* ***Index signatures***, which define type constraints for properties in the given type. An object type can have at most one string index signature and one numeric index signature. + +Properties are either ***public***, ***private***, or ***protected*** and are either ***required*** or ***optional***: + +* Properties in a class declaration may be designated public, private, or protected, while properties declared in other contexts are always considered public. Private members are only accessible within their declaring class, as described in section [8.2.2](#8.2.2), and private properties match only themselves in subtype and assignment compatibility checks, as described in section [3.11](#3.11). Protected members are only accessible within their declaring class and classes derived from it, as described in section [8.2.2](#8.2.2), and protected properties match only themselves and overrides in subtype and assignment compatibility checks, as described in section [3.11](#3.11). +* Properties in an object type literal or interface declaration may be designated required or optional, while properties declared in other contexts are always considered required. Properties that are optional in the target type of an assignment may be omitted from source objects, as described in section [3.11.4](#3.11.4). + +Call and construct signatures may be ***specialized*** (section [3.9.2.4](#3.9.2.4)) by including parameters with string literal types. Specialized signatures are used to express patterns where specific string values for some parameters cause the types of other parameters or the function result to become further specialized. + +## 3.4 Union Types + +***Union types*** represent values that may have one of several distinct representations. A value of a union type *A* | *B* is a value that is *either* of type *A* or type *B*. Union types are written using union type literals (section [3.8.6](#3.8.6)). + +A union type encompasses an ordered set of constituent types. While it is generally true that *A* | *B* is equivalent to *B* | *A*, the order of the constituent types may matter when determining the call and construct signatures of the union type. + +Union types have the following subtype relationships: + +* A union type *U* is a subtype of a type *T* if each type in *U* is a subtype of *T*. +* A type *T* is a subtype of a union type *U* if *T* is a subtype of any type in *U*. + +Similarly, union types have the following assignability relationships: + +* A union type *U* is assignable to a type *T* if each type in *U* is assignable to *T*. +* A type *T* is assignable to a union type *U* if *T* is assignable to any type in *U*. + +The || and conditional operators (section [4.19.7](#4.19.7) and [4.20](#4.20)) may produce values of union types, and array literals (section [4.6](#4.6)) may produce array values that have union types as their element types. + +Type guards (section [4.24](#4.24)) may be used to narrow a union type to a more specific type. In particular, type guards are useful for narrowing union type values to a non-union type values. + +In the example + +```TypeScript +var x: string | number; +var test: boolean; +x = "hello"; // Ok +x = 42; // Ok +x = test; // Error, boolean not assignable +x = test ? 5 : "five"; // Ok +x = test ? 0 : false; // Error, number | boolean not assignable +``` + +it is possible to assign 'x' a value of type `string`, `number`, or the union type `string | number`, but not any other type. To access a value in 'x', a type guard can be used to first narrow the type of 'x' to either `string` or `number`: + +```TypeScript +var n = typeof x === "string" ? x.length : x; // Type of n is number +``` + +For purposes of property access and function calls, the apparent members (section [3.11.1](#3.11.1)) of a union type are those that are present in every one of its constituent types, with types that are unions of the respective apparent members in the constituent types. The following example illustrates the merging of member types that occurs when union types are created from object types. + +```TypeScript +interface A { + a: string; + b: number; +} + +interface B { + a: number; + b: number; + c: number; +} + +var x: A | B; +var a = x.a; // a has type string | number +var b = x.b; // b has type number +var c = x.c; // Error, no property c in union type +``` + +Note that 'x.a' has a union type because the type of 'a' is different in 'A' and 'B', whereas 'x.b' simply has type number because that is the type of 'b' in both 'A' and 'B'. Also note that there is no property 'x.c' because only 'B' has a property 'c'. + +When used as a contextual type (section [4.23](#4.23)), a union type has those members that are present in any of its constituent types, with types that are unions of the respective members in the constituent types. Specifically, a union type used as a contextual type has the apparent members defined in section [3.11.1](#3.11.1), except that a particular member need only be present in one or more constituent types instead of all constituent types. + +## 3.5 Intersection Types + +***Intersection types*** represent values that simultaneously have multiple types. A value of an intersection type *A* & *B* is a value that is *both* of type *A* and type *B*. Intersection types are written using intersection type literals (section [3.8.7](#3.8.7)). + +An intersection type encompasses an ordered set of constituent types. While it is generally true that *A* & *B* is equivalent to *B* & *A*, the order of the constituent types may matter when determining the call and construct signatures of the intersection type. + +Intersection types have the following subtype relationships: + +* An intersection type *I* is a subtype of a type *T* if any type in *I* is a subtype of *T*. +* A type *T* is a subtype of an intersection type *I* if *T* is a subtype of each type in *I*. + +Similarly, intersection types have the following assignability relationships: + +* An intersection type *I* is assignable to a type *T* if any type in *I* is assignable to *T*. +* A type *T* is assignable to an intersection type *I* if *T* is assignable to each type in *I*. + +For purposes of property access and function calls, the apparent members (section [3.11.1](#3.11.1)) of an intersection type are those that are present in one or more of its constituent types, with types that are intersections of the respective apparent members in the constituent types. The following examples illustrate the merging of member types that occurs when intersection types are created from object types. + +```TypeScript +interface A { a: number } +interface B { b: number } + +var ab: A & B = { a: 1, b: 1 }; +var a: A = ab; // A & B assignable to A +var b: B = ab; // A & B assignable to B + +interface X { p: A } +interface Y { p: B } + +var xy: X & Y = { p: ab }; // X & Y has property p of type A & B + +type F1 = (a: string, b: string) => void; +type F2 = (a: number, b: number) => void; + +var f: F1 & F2 = (a: string | number, b: string | number) => { }; +f("hello", "world"); // Ok +f(1, 2); // Ok +f(1, "test"); // Error +``` + +The union and intersection type operators can be applied to type parameters. This capability can for example be used to model functions that merge objects: + +```TypeScript +function extend(first: T, second: U): T & U { + // Extend first with properties of second +} + +var x = extend({ a: "hello" }, { b: 42 }); +var s = x.a; +var n = x.b; +``` + +It is possible to create intersection types for which no values other than null or undefined are possible. For example, intersections of primitive types such as `string & number` fall into this category. + +## 3.6 Type Parameters + +A type parameter represents an actual type that the parameter is bound to in a generic type reference or a generic function call. Type parameters have constraints that establish upper bounds for their actual type arguments. + +Since a type parameter represents a multitude of different type arguments, type parameters have certain restrictions compared to other types. In particular, a type parameter cannot be used as a base class or interface. + +### 3.6.1 Type Parameter Lists + +Class, interface, type alias, and function declarations may optionally include lists of type parameters enclosed in < and > brackets. Type parameters are also permitted in call signatures of object, function, and constructor type literals. + +  *TypeParameters:* +   `<` *TypeParameterList* `>` + +  *TypeParameterList:* +   *TypeParameter* +   *TypeParameterList* `,` *TypeParameter* + +  *TypeParameter:* +   *BindingIdentifier* *Constraintopt* + +  *Constraint:* +   `extends` *Type* + +Type parameter names must be unique. A compile-time error occurs if two or more type parameters in the same *TypeParameterList* have the same name. + +The scope of a type parameter extends over the entire declaration with which the type parameter list is associated, with the exception of static member declarations in classes. + +A type parameter may have an associated type parameter ***constraint*** that establishes an upper bound for type arguments. Type parameters may be referenced in type parameter constraints within the same type parameter list, including even constraint declarations that occur to the left of the type parameter. + +The ***base constraint*** of a type parameter *T* is defined as follows: + +* If *T* has no declared constraint, *T*'s base constraint is the empty object type `{}`. +* If *T*'s declared constraint is a type parameter, *T*'s base constraint is that of the type parameter. +* Otherwise, *T*'s base constraint is *T*'s declared constraint. + +In the example + +```TypeScript +interface G { } +``` + +the base constraint of 'T' is the empty object type and the base constraint of 'U' and 'V' is 'Function'. + +For purposes of determining type relationships (section [3.11](#3.11)), type parameters appear to be subtypes of their base constraint. Likewise, in property accesses (section [4.13](#4.13)), `new` operations (section [4.14](#4.14)), and function calls (section [4.15](#4.15)), type parameters appear to have the members of their base constraint, but no other members. + +It is an error for a type parameter to directly or indirectly be a constraint for itself. For example, both of the following declarations are invalid: + +```TypeScript +interface A { } + +interface B { } +``` + +### 3.6.2 Type Argument Lists + +A type reference (section [3.8.2](#3.8.2)) to a generic type must include a list of type arguments enclosed in angle brackets and separated by commas. Similarly, a call (section [4.15](#4.15)) to a generic function may explicitly include a type argument list instead of relying on type inference. + +  *TypeArguments:* +   `<` *TypeArgumentList* `>` + +  *TypeArgumentList:* +   *TypeArgument* +   *TypeArgumentList* `,` *TypeArgument* + +  *TypeArgument:* +   *Type* + +Type arguments correspond one-to-one with type parameters of the generic type or function being referenced. A type argument list is required to specify exactly one type argument for each corresponding type parameter, and each type argument for a constrained type parameter is required to ***satisfy*** the constraint of that type parameter. A type argument satisfies a type parameter constraint if the type argument is assignable to (section [3.11.4](#3.11.4)) the constraint type once type arguments are substituted for type parameters. + +Given the declaration + +```TypeScript +interface G { } +``` + +a type reference of the form 'G<A, B>' places no requirements on 'A' but requires 'B' to be assignable to 'Function'. + +The process of substituting type arguments for type parameters in a generic type or generic signature is known as ***instantiating*** the generic type or signature. Instantiation of a generic type or signature can fail if the supplied type arguments do not satisfy the constraints of their corresponding type parameters. + +### 3.6.3 This-types + +Every class and interface has a ***this-type*** that represents the actual type of instances of the class or interface within the declaration of the class or interface. The this-type is referenced using the keyword `this` in a type position. Within instance methods and constructors of a class, the type of the expression `this` (section [4.2](#4.2)) is the this-type of the class. + +Classes and interfaces support inheritance and therefore the instance represented by `this` in a method isn't necessarily an instance of the containing class—it may in fact be an instance of a derived class or interface. To model this relationship, the this-type of a class or interface is classified as a type parameter. Unlike other type parameters, it is not possible to explicitly pass a type argument for a this-type. Instead, in a type reference to a class or interface type, the type reference *itself* is implicitly passed as a type argument for the this-type. For example: + +```TypeScript +class A { + foo() { + return this; + } +} + +class B extends A { + bar() { + return this; + } +} + +let b: B; +let x = b.foo().bar(); // Fluent pattern works, type of x is B +``` + +In the declaration of `b` above, the type reference `B` is itself passed as a type argument for B's this-type. Thus, the referenced type is an instantiation of class `B` where all occurrences of the type `this` are replaced with `B`, and for that reason the `foo` method of `B` actually returns `B` (as opposed to `A`). + +The this-type of a given class or interface type *C* implicitly has a constraint consisting of a type reference to *C* with *C*'s own type parameters passed as type arguments and with that type reference passed as the type argument for the this-type. + +## 3.7 Named Types + +Classes, interfaces, enums, and type aliases are ***named types*** that are introduced through class declarations (section [8.1](#8.1)), interface declarations (section [7.1](#7.1)), enum declarations ([9.1](#9.1)), and type alias declarations (section [3.10](#3.10)). Classes, interfaces, and type aliases may have type parameters and are then called ***generic types***. Conversely, named types without type parameters are called ***non-generic types***. + +Interface declarations only introduce named types, whereas class declarations introduce named types *and* constructor functions that create instances of implementations of those named types. The named types introduced by class and interface declarations have only minor differences (classes can't declare optional members and interfaces can't declare private or protected members) and are in most contexts interchangeable. In particular, class declarations with only public members introduce named types that function exactly like those created by interface declarations. + +Named types are referenced through ***type references*** (section [3.8.2](#3.8.2)) that specify a type name and, if applicable, the type arguments to be substituted for the type parameters of the named type. + +Named types are technically not types—only *references* to named types are. This distinction is particularly evident with generic types: Generic types are "templates" from which multiple *actual* types can be created by writing type references that supply type arguments to substitute in place of the generic type's type parameters. This substitution process is known as ***instantiating*** a generic type. Only once a generic type is instantiated does it denote an actual type. + +TypeScript has a structural type system, and therefore an instantiation of a generic type is indistinguishable from an equivalent manually written expansion. For example, given the declaration + +```TypeScript +interface Pair { first: T1; second: T2; } +``` + +the type reference + +```TypeScript +Pair +``` + +is indistinguishable from the type + +```TypeScript +{ first: string; second: Entity; } +``` + +## 3.8 Specifying Types + +Types are specified either by referencing their keyword or name, or by writing object type literals, array type literals, tuple type literals, function type literals, constructor type literals, or type queries. + +  *Type:* +   *UnionOrIntersectionOrPrimaryType* +   *FunctionType* +   *ConstructorType* + +  *UnionOrIntersectionOrPrimaryType:* +   *UnionType* +   *IntersectionOrPrimaryType* + +  *IntersectionOrPrimaryType:* +   *IntersectionType* +   *PrimaryType* + +  *PrimaryType:* +   *ParenthesizedType* +   *PredefinedType* +   *TypeReference* +   *ObjectType* +   *ArrayType* +   *TupleType* +   *TypeQuery* +   *ThisType* + +  *ParenthesizedType:* +   `(` *Type* `)` + +Parentheses are required around union, intersection, function, or constructor types when they are used as array element types; around union, function, or constructor types in intersection types; and around function or constructor types in union types. For example: + +```TypeScript +(string | number)[] +((x: string) => string) | ((x: number) => number) +(A | B) & (C | D) +``` + +The different forms of type notations are described in the following sections. + +### 3.8.1 Predefined Types + +The `any`, `number`, `boolean`, `string`, `symbol` and `void` keywords reference the Any type and the Number, Boolean, String, Symbol, and Void primitive types respectively. + +  *PredefinedType:* +   `any` +   `number` +   `boolean` +   `string` +   `symbol` +   `void` + +The predefined type keywords are reserved and cannot be used as names of user defined types. + +### 3.8.2 Type References + +A type reference references a named type or type parameter through its name and, in the case of a generic type, supplies a type argument list. + +  *TypeReference:* +   *TypeName* *[no LineTerminator here]* *TypeArgumentsopt* + +  *TypeName:* +   *IdentifierReference* +   *NamespaceName* `.` *IdentifierReference* + +  *NamespaceName:* +   *IdentifierReference* +   *NamespaceName* `.` *IdentifierReference* + +A *TypeReference* consists of a *TypeName* that a references a named type or type parameter. A reference to a generic type must be followed by a list of *TypeArguments* (section [3.6.2](#3.6.2)). + +A *TypeName* is either a single identifier or a sequence of identifiers separated by dots. In a type name, all identifiers but the last one refer to namespaces and the last identifier refers to a named type. + +Resolution of a *TypeName* consisting of a single identifier is described in section [2.4](#2.4). + +Resolution of a *TypeName* of the form *N.X*, where *N* is a *NamespaceName* and *X* is an *IdentifierReference*, proceeds by first resolving the namespace name *N*. If the resolution of *N* is successful and the export member set (sections [10.4](#10.4) and [11.3.4.4](#11.3.4.4)) of the resulting namespace contains a named type *X*, then *N.X* refers to that member. Otherwise, *N.X* is undefined. + +Resolution of a *NamespaceName* consisting of a single identifier is described in section [2.4](#2.4). Identifiers declared in namespace declarations (section [10.1](#10.1)) or import declarations (sections [10.3](#10.3), [11.3.2](#11.3.2), and [11.3.3](#11.3.3)) may be classified as namespaces. + +Resolution of a *NamespaceName* of the form *N.X*, where *N* is a *NamespaceName* and *X* is an *IdentifierReference*, proceeds by first resolving the namespace name *N*. If the resolution of *N* is successful and the export member set (sections [10.4](#10.4) and [11.3.4.4](#11.3.4.4)) of the resulting namespace contains an exported namespace member *X*, then *N.X* refers to that member. Otherwise, *N.X* is undefined. + +A type reference to a generic type is required to specify exactly one type argument for each type parameter of the referenced generic type, and each type argument must be assignable to (section [3.11.4](#3.11.4)) the constraint of the corresponding type parameter or otherwise an error occurs. An example: + +```TypeScript +interface A { a: string; } + +interface B extends A { b: string; } + +interface C extends B { c: string; } + +interface G { + x: T; + y: U; +} + +var v1: G; // Ok +var v2: G<{ a: string }, C>; // Ok, equivalent to G +var v3: G; // Error, A not valid argument for U +var v4: G, C>; // Ok +var v5: G; // Ok +var v6: G; // Error, wrong number of arguments +var v7: G; // Error, no arguments +``` + +A type argument is simply a *Type* and may itself be a type reference to a generic type, as demonstrated by 'v4' in the example above. + +As described in section [3.7](#3.7), a type reference to a generic type *G* designates a type wherein all occurrences of *G*'s type parameters have been replaced with the actual type arguments supplied in the type reference. For example, the declaration of 'v1' above is equivalent to: + +```TypeScript +var v1: { + x: { a: string; } + y: { a: string; b: string; c: string }; +}; +``` + +### 3.8.3 Object Type Literals + +An object type literal defines an object type by specifying the set of members that are statically considered to be present in instances of the type. Object type literals can be given names using interface declarations but are otherwise anonymous. + +  *ObjectType:* +   `{` *TypeBodyopt* `}` + +  *TypeBody:* +   *TypeMemberList* `;`*opt* +   *TypeMemberList* `,`*opt* + +  *TypeMemberList:* +   *TypeMember* +   *TypeMemberList* `;` *TypeMember* +   *TypeMemberList* `,` *TypeMember* + +  *TypeMember:* +   *PropertySignature* +   *CallSignature* +   *ConstructSignature* +   *IndexSignature* +   *MethodSignature* + +The members of an object type literal are specified as a combination of property, call, construct, index, and method signatures. Object type members are described in section [3.9](#3.9). + +### 3.8.4 Array Type Literals + +An array type literal is written as an element type followed by an open and close square bracket. + +  *ArrayType:* +   *PrimaryType* *[no LineTerminator here]* `[` `]` + +An array type literal references an array type (section [3.3.2](#3.3.2)) with the given element type. An array type literal is simply shorthand notation for a reference to the generic interface type 'Array' in the global namespace with the element type as a type argument. + +When union, intersection, function, or constructor types are used as array element types they must be enclosed in parentheses. For example: + +```TypeScript +(string | number)[] +(() => string))[] +``` + +Alternatively, array types can be written using the 'Array<T>' notation. For example, the types above are equivalent to + +```TypeScript +Array +Array<() => string> +``` + +### 3.8.5 Tuple Type Literals + +A tuple type literal is written as a sequence of element types, separated by commas and enclosed in square brackets. + +  *TupleType:* +   `[` *TupleElementTypes* `]` + +  *TupleElementTypes:* +   *TupleElementType* +   *TupleElementTypes* `,` *TupleElementType* + +  *TupleElementType:* +   *Type* + +A tuple type literal references a tuple type (section [3.3.3](#3.3.3)). + +### 3.8.6 Union Type Literals + +A union type literal is written as a sequence of types separated by vertical bars. + +  *UnionType:* +   *UnionOrIntersectionOrPrimaryType* `|` *IntersectionOrPrimaryType* + +A union type literal references a union type (section [3.4](#3.4)). + +### 3.8.7 Intersection Type Literals + +An intersection type literal is written as a sequence of types separated by ampersands. + +  *IntersectionType:* +   *IntersectionOrPrimaryType* `&` *PrimaryType* + +An intersection type literal references an intersection type (section [3.5](#3.5)). + +### 3.8.8 Function Type Literals + +A function type literal specifies the type parameters, regular parameters, and return type of a call signature. + +  *FunctionType:* +   *TypeParametersopt* `(` *ParameterListopt* `)` `=>` *Type* + +A function type literal is shorthand for an object type containing a single call signature. Specifically, a function type literal of the form + +```TypeScript +< T1, T2, ... > ( p1, p2, ... ) => R +``` + +is exactly equivalent to the object type literal + +```TypeScript +{ < T1, T2, ... > ( p1, p2, ... ) : R } +``` + +Note that function types with multiple call or construct signatures cannot be written as function type literals but must instead be written as object type literals. + +### 3.8.9 Constructor Type Literals + +A constructor type literal specifies the type parameters, regular parameters, and return type of a construct signature. + +  *ConstructorType:* +   `new` *TypeParametersopt* `(` *ParameterListopt* `)` `=>` *Type* + +A constructor type literal is shorthand for an object type containing a single construct signature. Specifically, a constructor type literal of the form + +```TypeScript +new < T1, T2, ... > ( p1, p2, ... ) => R +``` + +is exactly equivalent to the object type literal + +```TypeScript +{ new < T1, T2, ... > ( p1, p2, ... ) : R } +``` + +Note that constructor types with multiple construct signatures cannot be written as constructor type literals but must instead be written as object type literals. + +### 3.8.10 Type Queries + +A type query obtains the type of an expression. + +  *TypeQuery:* +   `typeof` *TypeQueryExpression* + +  *TypeQueryExpression:* +   *IdentifierReference* +   *TypeQueryExpression* `.` *IdentifierName* + +A type query consists of the keyword `typeof` followed by an expression. The expression is restricted to a single identifier or a sequence of identifiers separated by periods. The expression is processed as an identifier expression (section [4.3](#4.3)) or property access expression (section [4.13](#4.13)), the widened type (section [3.12](#3.12)) of which becomes the result. Similar to other static typing constructs, type queries are erased from the generated JavaScript code and add no run-time overhead. + +Type queries are useful for capturing anonymous types that are generated by various constructs such as object literals, function declarations, and namespace declarations. For example: + +```TypeScript +var a = { x: 10, y: 20 }; +var b: typeof a; +``` + +Above, 'b' is given the same type as 'a', namely `{ x: number; y: number; }`. + +If a declaration includes a type annotation that references the entity being declared through a circular path of type queries or type references containing type queries, the resulting type is the Any type. For example, all of the following variables are given the type Any: + +```TypeScript +var c: typeof c; +var d: typeof e; +var e: typeof d; +var f: Array; +``` + +However, if a circular path of type queries includes at least one *ObjectType*, *FunctionType* or *ConstructorType*, the construct denotes a recursive type: + +```TypeScript +var g: { x: typeof g; }; +var h: () => typeof h; +``` + +Here, 'g' and 'g.x' have the same recursive type, and likewise 'h' and 'h()' have the same recursive type. + +### 3.8.11 This-Type References + +The `this` keyword is used to reference the this-type (section [3.6.3](#3.6.3)) of a class or interface. + +  *ThisType:* +   `this` + +The meaning of a *ThisType* depends on the closest enclosing *FunctionDeclaration*, *FunctionExpression*, *PropertyDefinition*, *ClassElement*, or *TypeMember*, known as the root declaration of the *ThisType*, as follows: + +* When the root declaration is an instance member or constructor of a class, the *ThisType* references the this-type of that class. +* When the root declaration is a member of an interface type, the *ThisType* references the this-type of that interface. +* Otherwise, the *ThisType* is an error. + +Note that in order to avoid ambiguities it is not possible to reference the this-type of a class or interface in a nested object type literal. In the example + +```TypeScript +interface ListItem { + getHead(): this; + getTail(): this; + getHeadAndTail(): { head: this, tail: this }; // Error +} +``` + +the `this` references on the last line are in error because their root declarations are not members of a class or interface. The recommended way to reference the this-type of an outer class or interface in an object type literal is to declare an intermediate generic type and pass `this` as a type argument. For example: + +```TypeScript +type HeadAndTail = { head: T, tail: T }; + +interface ListItem { + getHead(): this; + getTail(): this; + getHeadAndTail(): HeadAndTail; +} +``` + +## 3.9 Specifying Members + +The members of an object type literal (section [3.8.3](#3.8.3)) are specified as a combination of property, call, construct, index, and method signatures. + +### 3.9.1 Property Signatures + +A property signature declares the name and type of a property member. + +  *PropertySignature:* +   *PropertyName* `?`*opt* *TypeAnnotationopt* + +  *TypeAnnotation:* +   `:` *Type* + +The *PropertyName* ([2.2.2](#2.2.2)) of a property signature must be unique within its containing type, and must denote a well-known symbol if it is a computed property name ([2.2.3](#2.2.3)). If the property name is followed by a question mark, the property is optional. Otherwise, the property is required. + +If a property signature omits a *TypeAnnotation*, the Any type is assumed. + +### 3.9.2 Call Signatures + +A call signature defines the type parameters, parameter list, and return type associated with applying a call operation (section [4.15](#4.15)) to an instance of the containing type. A type may ***overload*** call operations by defining multiple different call signatures. + +  *CallSignature:* +   *TypeParametersopt* `(` *ParameterListopt* `)` *TypeAnnotationopt* + +A call signature that includes *TypeParameters* (section [3.6.1](#3.6.1)) is called a ***generic call signature***. Conversely, a call signature with no *TypeParameters* is called a non-generic call signature. + +As well as being members of object type literals, call signatures occur in method signatures (section [3.9.5](#3.9.5)), function expressions (section [4.10](#4.10)), and function declarations (section [6.1](#6.1)). + +An object type containing call signatures is said to be a ***function type***. + +#### 3.9.2.1 Type Parameters + +Type parameters (section [3.6.1](#3.6.1)) in call signatures provide a mechanism for expressing the relationships of parameter and return types in call operations. For example, a signature might introduce a type parameter and use it as both a parameter type and a return type, in effect describing a function that returns a value of the same type as its argument. + +Type parameters may be referenced in parameter types and return type annotations, but not in type parameter constraints, of the call signature in which they are introduced. + +Type arguments (section [3.6.2](#3.6.2)) for call signature type parameters may be explicitly specified in a call operation or may, when possible, be inferred (section [4.15.2](#4.15.2)) from the types of the regular arguments in the call. An ***instantiation*** of a generic call signature for a particular set of type arguments is the call signature formed by replacing each type parameter with its corresponding type argument. + +Some examples of call signatures with type parameters follow below. + +A function taking an argument of any type, returning a value of that same type: + +```TypeScript +(x: T): T +``` + +A function taking two values of the same type, returning an array of that type: + +```TypeScript +(x: T, y: T): T[] +``` + +A function taking two arguments of different types, returning an object with properties 'x' and 'y' of those types: + +```TypeScript +(x: T, y: U): { x: T; y: U; } +``` + +A function taking an array of one type and a function argument, returning an array of another type, where the function argument takes a value of the first array element type and returns a value of the second array element type: + +```TypeScript +(a: T[], f: (x: T) => U): U[] +``` + +#### 3.9.2.2 Parameter List + +A signature's parameter list consists of zero or more required parameters, followed by zero or more optional parameters, finally followed by an optional rest parameter. + +  *ParameterList:* +   *RequiredParameterList* +   *OptionalParameterList* +   *RestParameter* +   *RequiredParameterList* `,` *OptionalParameterList* +   *RequiredParameterList* `,` *RestParameter* +   *OptionalParameterList* `,` *RestParameter* +   *RequiredParameterList* `,` *OptionalParameterList* `,` *RestParameter* + +  *RequiredParameterList:* +   *RequiredParameter* +   *RequiredParameterList* `,` *RequiredParameter* + +  *RequiredParameter:* +   *AccessibilityModifieropt* *BindingIdentifierOrPattern* *TypeAnnotationopt* +   *BindingIdentifier* `:` *StringLiteral* + +  *AccessibilityModifier:* +   `public` +   `private` +   `protected` + +  *BindingIdentifierOrPattern:* +   *BindingIdentifier* +   *BindingPattern* + +  *OptionalParameterList:* +   *OptionalParameter* +   *OptionalParameterList* `,` *OptionalParameter* + +  *OptionalParameter:* +   *AccessibilityModifieropt* *BindingIdentifierOrPattern* `?` *TypeAnnotationopt* +   *AccessibilityModifieropt* *BindingIdentifierOrPattern* *TypeAnnotationopt* *Initializer* +   *BindingIdentifier* `?` `:` *StringLiteral* + +  *RestParameter:* +   `...` *BindingIdentifier* *TypeAnnotationopt* + +A parameter declaration may specify either an identifier or a binding pattern ([5.2.2](#5.2.2)). The identifiers specified in parameter declarations and binding patterns in a parameter list must be unique within that parameter list. + +The type of a parameter in a signature is determined as follows: + +* If the declaration includes a type annotation, the parameter is of that type. +* Otherwise, if the declaration includes an initializer expression (which is permitted only when the parameter list occurs in conjunction with a function body), the parameter type is the widened form (section [3.12](#3.12)) of the type of the initializer expression. +* Otherwise, if the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section [5.2.3](#5.2.3)). +* Otherwise, if the parameter is a rest parameter, the parameter type is `any[]`. +* Otherwise, the parameter type is `any`. + +A parameter is permitted to include a `public`, `private`, or `protected` modifier only if it occurs in the parameter list of a *ConstructorImplementation* (section [8.3.1](#8.3.1)) and only if it doesn't specify a *BindingPattern*. + +A type annotation for a rest parameter must denote an array type. + +When a parameter type annotation specifies a string literal type, the containing signature is a specialized signature (section [3.9.2.4](#3.9.2.4)). Specialized signatures are not permitted in conjunction with a function body, i.e. the *FunctionExpression*, *FunctionImplementation*, *MemberFunctionImplementation*, and *ConstructorImplementation* grammar productions do not permit parameters with string literal types. + +A parameter can be marked optional by following its name or binding pattern with a question mark (`?`) or by including an initializer. Initializers (including binding property or element initializers) are permitted only when the parameter list occurs in conjunction with a function body, i.e. only in a *FunctionExpression*, *FunctionImplementation*, *MemberFunctionImplementation*, or *ConstructorImplementation* grammar production. + +*TODO: Update to reflect [binding parameter cannot be optional in implementation signature](https://github.com/Microsoft/TypeScript/issues/2797)*. + +*TODO: Update to reflect [required parameters support initializers](https://github.com/Microsoft/TypeScript/pull/4022)*. + +#### 3.9.2.3 Return Type + +If present, a call signature's return type annotation specifies the type of the value computed and returned by a call operation. A `void` return type annotation is used to indicate that a function has no return value. + +When a call signature with no return type annotation occurs in a context without a function body, the return type is assumed to be the Any type. + +When a call signature with no return type annotation occurs in a context that has a function body (specifically, a function implementation, a member function implementation, or a member accessor declaration), the return type is inferred from the function body as described in section [6.3](#6.3). + +#### 3.9.2.4 Specialized Signatures + +When a parameter type annotation specifies a string literal type (section [3.2.9](#3.2.9)), the containing signature is considered a specialized signature. Specialized signatures are used to express patterns where specific string values for some parameters cause the types of other parameters or the function result to become further specialized. For example, the declaration + +```TypeScript +interface Document { + createElement(tagName: "div"): HTMLDivElement; + createElement(tagName: "span"): HTMLSpanElement; + createElement(tagName: "canvas"): HTMLCanvasElement; + createElement(tagName: string): HTMLElement; +} +``` + +states that calls to 'createElement' with the string literals "div", "span", and "canvas" return values of type 'HTMLDivElement', 'HTMLSpanElement', and 'HTMLCanvasElement' respectively, and that calls with all other string expressions return values of type 'HTMLElement'. + +When writing overloaded declarations such as the one above it is important to list the non-specialized signature last. This is because overload resolution (section [4.15.1](#4.15.1)) processes the candidates in declaration order and picks the first one that matches. + +Every specialized call or construct signature in an object type must be assignable to at least one non-specialized call or construct signature in the same object type (where a call signature *A* is considered assignable to another call signature *B* if an object type containing only *A* would be assignable to an object type containing only *B*). For example, the 'createElement' property in the example above is of a type that contains three specialized signatures, all of which are assignable to the non-specialized signature in the type. + +### 3.9.3 Construct Signatures + +A construct signature defines the parameter list and return type associated with applying the `new` operator (section [4.14](#4.14)) to an instance of the containing type. A type may overload `new` operations by defining multiple construct signatures with different parameter lists. + +  *ConstructSignature:* +   `new` *TypeParametersopt* `(` *ParameterListopt* `)` *TypeAnnotationopt* + +The type parameters, parameter list, and return type of a construct signature are subject to the same rules as a call signature. + +A type containing construct signatures is said to be a ***constructor type***. + +### 3.9.4 Index Signatures + +An index signature defines a type constraint for properties in the containing type. + +  *IndexSignature:* +   `[` *BindingIdentifier* `:` `string` `]` *TypeAnnotation* +   `[` *BindingIdentifier* `:` `number` `]` *TypeAnnotation* + +There are two kinds of index signatures: + +* ***String index signatures***, specified using index type `string`, define type constraints for all properties and numeric index signatures in the containing type. Specifically, in a type with a string index signature of type *T*, all properties and numeric index signatures must have types that are assignable to *T*. +* ***Numeric index signatures***, specified using index type `number`, define type constraints for all numerically named properties in the containing type. Specifically, in a type with a numeric index signature of type *T*, all numerically named properties must have types that are assignable to *T*. + +A ***numerically named property*** is a property whose name is a valid numeric literal. Specifically, a property with a name *N* for which ToString(ToNumber(*N*)) is identical to *N*, where ToString and ToNumber are the abstract operations defined in ECMAScript specification. + +An object type can contain at most one string index signature and one numeric index signature. + +Index signatures affect the determination of the type that results from applying a bracket notation property access to an instance of the containing type, as described in section [4.13](#4.13). + +### 3.9.5 Method Signatures + +A method signature is shorthand for declaring a property of a function type. + +  *MethodSignature:* +   *PropertyName* `?`*opt* *CallSignature* + +If the *PropertyName* is a computed property name ([2.2.3](#2.2.3)), it must specify a well-known symbol. If the *PropertyName* is followed by a question mark, the property is optional. Otherwise, the property is required. Only object type literals and interfaces can declare optional properties. + +A method signature of the form + +```TypeScript +f < T1, T2, ... > ( p1, p2, ... ) : R +``` + +is equivalent to the property declaration + +```TypeScript +f : { < T1, T2, ... > ( p1, p2, ... ) : R } +``` + +A literal type may ***overload*** a method by declaring multiple method signatures with the same name but differing parameter lists. Overloads must either all be required (question mark omitted) or all be optional (question mark included). A set of overloaded method signatures correspond to a declaration of a single property with a type composed from an equivalent set of call signatures. Specifically + +```TypeScript +f < T1, T2, ... > ( p1, p2, ... ) : R ; +f < U1, U2, ... > ( q1, q2, ... ) : S ; +... +``` + +is equivalent to + +```TypeScript +f : { + < T1, T2, ... > ( p1, p2, ... ) : R ; + < U1, U2, ... > ( q1, q2, ... ) : S ; + ... +} ; +``` + +In the following example of an object type + +```TypeScript +{ + func1(x: number): number; // Method signature + func2: (x: number) => number; // Function type literal + func3: { (x: number): number }; // Object type literal +} +``` + +the properties 'func1', 'func2', and 'func3' are all of the same type, namely an object type with a single call signature taking a number and returning a number. Likewise, in the object type + +```TypeScript +{ + func4(x: number): number; + func4(s: string): string; + func5: { + (x: number): number; + (s: string): string; + }; +} +``` + +the properties 'func4' and 'func5' are of the same type, namely an object type with two call signatures taking and returning number and string respectively. + +## 3.10 Type Aliases + +A type alias declaration introduces a ***type alias*** in the containing declaration space. + +  *TypeAliasDeclaration:* +   `type` *BindingIdentifier* *TypeParametersopt* `=` *Type* `;` + +A type alias serves as an alias for the type specified in the type alias declaration. Unlike an interface declaration, which always introduces a named object type, a type alias declaration can introduce a name for any kind of type, including primitive, union, and intersection types. + +A type alias may optionally have type parameters (section [3.6.1](#3.6.1)) that serve as placeholders for actual types to be provided when the type alias is referenced in type references. A type alias with type parameters is called a ***generic type alias***. The type parameters of a generic type alias declaration are in scope and may be referenced in the aliased *Type*. + +Type aliases are referenced using type references ([3.8.2](#3.8.2)). Type references to generic type aliases produce instantiations of the aliased type with the given type arguments. Writing a reference to a non-generic type alias has exactly the same effect as writing the aliased type itself, and writing a reference to a generic type alias has exactly the same effect as writing the resulting instantiation of the aliased type. + +The *BindingIdentifier* of a type alias declaration may not be one of the predefined type names (section [3.8.1](#3.8.1)). + +It is an error for the type specified in a type alias to depend on that type alias. Types have the following dependencies: + +* A type alias *directly depends on* the type it aliases. +* A type reference *directly depends on* the referenced type and each of the type arguments, if any. +* A union or intersection type *directly depends on* each of the constituent types. +* An array type *directly depends on* its element type. +* A tuple type *directly depends on* each of its element types. +* A type query *directly depends on* the type of the referenced entity. + +Given this definition, the complete set of types upon which a type depends is the transitive closure of the *directly depends on* relationship. Note that object type literals, function type literals, and constructor type literals do not depend on types referenced within them and are therefore permitted to circularly reference themselves through type aliases. + +Some examples of type alias declarations: + +```TypeScript +type StringOrNumber = string | number; +type Text = string | { text: string }; +type NameLookup = Dictionary; +type ObjectStatics = typeof Object; +type Callback = (data: T) => void; +type Pair = [T, T]; +type Coordinates = Pair; +type Tree = T | { left: Tree, right: Tree }; +``` + +Interface types have many similarities to type aliases for object type literals, but since interface types offer more capabilities they are generally preferred to type aliases. For example, the interface type + +```TypeScript +interface Point { + x: number; + y: number; +} +``` + +could be written as the type alias + +```TypeScript +type Point = { + x: number; + y: number; +}; +``` + +However, doing so means the following capabilities are lost: + +* An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot. +* An interface can have multiple merged declarations, but a type alias for an object type literal cannot. + +## 3.11 Type Relationships + +Types in TypeScript have identity, subtype, supertype, and assignment compatibility relationships as defined in the following sections. + +### 3.11.1 Apparent Members + +The ***apparent members*** of a type are the members observed in subtype, supertype, and assignment compatibility relationships, as well as in the type checking of property accesses (section [4.13](#4.13)), `new` operations (section [4.14](#4.14)), and function calls (section [4.15](#4.15)). The apparent members of a type are determined as follows: + +* The apparent members of the primitive type Number and all enum types are the apparent members of the global interface type 'Number'. +* The apparent members of the primitive type Boolean are the apparent members of the global interface type 'Boolean'. +* The apparent members of the primitive type String and all string literal types are the apparent members of the global interface type 'String'. +* The apparent members of a type parameter are the apparent members of the constraint (section [3.6.1](#3.6.1)) of that type parameter. +* The apparent members of an object type *T* are the combination of the following: + * The declared and/or inherited members of *T*. + * The properties of the global interface type 'Object' that aren't hidden by properties with the same name in *T*. + * If *T* has one or more call or construct signatures, the properties of the global interface type 'Function' that aren't hidden by properties with the same name in *T*. +* The apparent members of a union type *U* are determined as follows: + * When all constituent types of *U* have an apparent property named *N*, *U* has an apparent property named *N* of a union type of the respective property types. + * When all constituent types of *U* have an apparent call signature with a parameter list *P*, *U* has an apparent call signature with the parameter list *P* and a return type that is a union of the respective return types. The call signatures appear in the same order as in the first constituent type. + * When all constituent types of *U* have an apparent construct signature with a parameter list *P*, *U* has an apparent construct signature with the parameter list *P* and a return type that is a union of the respective return types. The construct signatures appear in the same order as in the first constituent type. + * When all constituent types of *U* have an apparent string index signature, *U* has an apparent string index signature of a union type of the respective string index signature types. + * When all constituent types of *U* have an apparent numeric index signature, *U* has an apparent numeric index signature of a union type of the respective numeric index signature types. +* The apparent members of an intersection type *I* are determined as follows: + * When one of more constituent types of *I* have an apparent property named *N*, *I* has an apparent property named *N* of an intersection type of the respective property types. + * When one or more constituent types of *I* have a call signature *S*, *I* has the apparent call signature *S*. The signatures are ordered as a concatenation of the signatures of each constituent type in the order of the constituent types within *I*. + * When one or more constituent types of *I* have a construct signature *S*, *I* has the apparent construct signature *S*. The signatures are ordered as a concatenation of the signatures of each constituent type in the order of the constituent types within *I*. + * When one or more constituent types of *I* have an apparent string index signature, *I* has an apparent string index signature of an intersection type of the respective string index signature types. + * When one or more constituent types of *I* have an apparent numeric index signature, *I* has an apparent numeric index signature of an intersection type of the respective numeric index signature types. + +If a type is not one of the above, it is considered to have no apparent members. + +In effect, a type's apparent members make it a subtype of the 'Object' or 'Function' interface unless the type defines members that are incompatible with those of the 'Object' or 'Function' interface—which, for example, occurs if the type defines a property with the same name as a property in the 'Object' or 'Function' interface but with a type that isn't a subtype of that in the 'Object' or 'Function' interface. + +Some examples: + +```TypeScript +var o: Object = { x: 10, y: 20 }; // Ok +var f: Function = (x: number) => x * x; // Ok +var err: Object = { toString: 0 }; // Error +``` + +The last assignment is an error because the object literal has a 'toString' method that isn't compatible with that of 'Object'. + +### 3.11.2 Type and Member Identity + +Two types are considered ***identical*** when + +* they are both the Any type, +* they are the same primitive type, +* they are the same type parameter, +* they are union types with identical sets of constituent types, or +* they are intersection types with identical sets of constituent types, or +* they are object types with identical sets of members. + +Two members are considered identical when + +* they are public properties with identical names, optionality, and types, +* they are private or protected properties originating in the same declaration and having identical types, +* they are identical call signatures, +* they are identical construct signatures, or +* they are index signatures of identical kind with identical types. + +Two call or construct signatures are considered identical when they have the same number of type parameters with identical type parameter constraints and, after substituting type Any for the type parameters introduced by the signatures, identical number of parameters with identical kind (required, optional or rest) and types, and identical return types. + +Note that, except for primitive types and classes with private or protected members, it is structure, not naming, of types that determines identity. Also, note that parameter names are not significant when determining identity of signatures. + +Private and protected properties match only if they originate in the same declaration and have identical types. Two distinct types might contain properties that originate in the same declaration if the types are separate parameterized references to the same generic class. In the example + +```TypeScript +class C { private x: T; } + +interface X { f(): string; } + +interface Y { f(): string; } + +var a: C; +var b: C; +``` + +the variables 'a' and 'b' are of identical types because the two type references to 'C' create types with a private member 'x' that originates in the same declaration, and because the two private 'x' members have types with identical sets of members once the type arguments 'X' and 'Y' are substituted. + +### 3.11.3 Subtypes and Supertypes + +*S* is a ***subtype*** of a type *T*, and *T* is a ***supertype*** of *S*, if *S* has no excess properties with respect to *T* ([3.11.5](#3.11.5)) and one of the following is true: + +* *S* and *T* are identical types. +* *T* is the Any type. +* *S* is the Undefined type. +* *S* is the Null type and *T* is not the Undefined type. +* *S* is an enum type and *T* is the primitive type Number. +* *S* is a string literal type and *T* is the primitive type String. +* *S* is a union type and each constituent type of *S* is a subtype of *T*. +* *S* is an intersection type and at least one constituent type of *S* is a subtype of *T*. +* *T* is a union type and *S* is a subtype of at least one constituent type of *T*. +* *T* is an intersection type and *S* is a subtype of each constituent type of *T*. +* *S* is a type parameter and the constraint of *S* is a subtype of *T*. +* *S* is an object type, an intersection type, an enum type, or the Number, Boolean, or String primitive type, *T* is an object type, and for each member *M* in *T*, one of the following is true: + * *M* is a property and *S* has an apparent property *N* where + * *M* and *N* have the same name, + * the type of *N* is a subtype of that of *M*, + * if *M* is a required property, *N* is also a required property, and + * *M* and *N* are both public, *M* and *N* are both private and originate in the same declaration, *M* and *N* are both protected and originate in the same declaration, or *M* is protected and *N* is declared in a class derived from the class in which *M* is declared. + * *M* is a non-specialized call or construct signature and *S* has an apparent call or construct signature *N* where, when *M* and *N* are instantiated using type Any as the type argument for all type parameters declared by *M* and *N* (if any), + * the signatures are of the same kind (call or construct), + * *M* has a rest parameter or the number of non-optional parameters in *N* is less than or equal to the total number of parameters in *M*, + * for parameter positions that are present in both signatures, each parameter type in *N* is a subtype or supertype of the corresponding parameter type in *M*, and + * the result type of *M* is Void, or the result type of *N* is a subtype of that of *M*. + * *M* is a string index signature of type *U*, and *U* is the Any type or *S* has an apparent string index signature of a type that is a subtype of *U*. + * *M* is a numeric index signature of type *U*, and *U* is the Any type or *S* has an apparent string or numeric index signature of a type that is a subtype of *U*. + +When comparing call or construct signatures, parameter names are ignored and rest parameters correspond to an unbounded expansion of optional parameters of the rest parameter element type. + +Note that specialized call and construct signatures (section [3.9.2.4](#3.9.2.4)) are not significant when determining subtype and supertype relationships. + +Also note that type parameters are not considered object types. Thus, the only subtypes of a type parameter *T* are *T* itself and other type parameters that are directly or indirectly constrained to *T*. + +### 3.11.4 Assignment Compatibility + +Types are required to be assignment compatible in certain circumstances, such as expression and variable types in assignment statements and argument and parameter types in function calls. + +*S* is ***assignable to*** a type *T*, and *T* is ***assignable from*** *S*, if *S* has no excess properties with respect to *T* ([3.11.5](#3.11.5)) and one of the following is true: + +* *S* and *T* are identical types. +* *S* or *T* is the Any type. +* *S* is the Undefined type. +* *S* is the Null type and *T* is not the Undefined type. +* *S* or *T* is an enum type and the other is the primitive type Number. +* *S* is a string literal type and *T* is the primitive type String. +* *S* is a union type and each constituent type of *S* is assignable to *T*. +* *S* is an intersection type and at least one constituent type of *S* is assignable to *T*. +* *T* is a union type and *S* is assignable to at least one constituent type of *T*. +* *T* is an intersection type and *S* is assignable to each constituent type of *T*. +* *S* is a type parameter and the constraint of *S* is assignable to *T*. +* *S* is an object type, an intersection type, an enum type, or the Number, Boolean, or String primitive type, *T* is an object type, and for each member *M* in *T*, one of the following is true: + * *M* is a property and *S* has an apparent property *N* where + * *M* and *N* have the same name, + * the type of *N* is assignable to that of *M*, + * if *M* is a required property, *N* is also a required property, and + * *M* and *N* are both public, *M* and *N* are both private and originate in the same declaration, *M* and *N* are both protected and originate in the same declaration, or *M* is protected and *N* is declared in a class derived from the class in which *M* is declared. + * *M* is an optional property and *S* has no apparent property of the same name as *M*. + * *M* is a non-specialized call or construct signature and *S* has an apparent call or construct signature *N* where, when *M* and *N* are instantiated using type Any as the type argument for all type parameters declared by *M* and *N* (if any), + * the signatures are of the same kind (call or construct), + * *M* has a rest parameter or the number of non-optional parameters in *N* is less than or equal to the total number of parameters in *M*, + * for parameter positions that are present in both signatures, each parameter type in *N* is assignable to or from the corresponding parameter type in *M*, and + * the result type of *M* is Void, or the result type of *N* is assignable to that of *M*. + * *M* is a string index signature of type *U*, and *U* is the Any type or *S* has an apparent string index signature of a type that is assignable to *U*. + * *M* is a numeric index signature of type *U*, and *U* is the Any type or *S* has an apparent string or numeric index signature of a type that is assignable to *U*. + +When comparing call or construct signatures, parameter names are ignored and rest parameters correspond to an unbounded expansion of optional parameters of the rest parameter element type. + +Note that specialized call and construct signatures (section [3.9.2.4](#3.9.2.4)) are not significant when determining assignment compatibility. + +The assignment compatibility and subtyping rules differ only in that + +* the Any type is assignable to, but not a subtype of, all types, +* the primitive type Number is assignable to, but not a subtype of, all enum types, and +* an object type without a particular property is assignable to an object type in which that property is optional. + +The assignment compatibility rules imply that, when assigning values or passing parameters, optional properties must either be present and of a compatible type, or not be present at all. For example: + +```TypeScript +function foo(x: { id: number; name?: string; }) { } + +foo({ id: 1234 }); // Ok +foo({ id: 1234, name: "hello" }); // Ok +foo({ id: 1234, name: false }); // Error, name of wrong type +foo({ name: "hello" }); // Error, id required but missing +``` + +### 3.11.5 Excess Properties + +The subtype and assignment compatibility relationships require that source types have no excess properties with respect to their target types. The purpose of this check is to detect excess or misspelled properties in object literals. + +A source type *S* is considered to have excess properties with respect to a target type *T* if + +* *S* is a fresh object literal type, as defined below, and +* *S* has one or more properties that aren't expected in *T*. + +A property *P* is said to be expected in a type *T* if one of the following is true: + +* *T* is not an object, union, or intersection type. +* *T* is an object type and + * *T* has a property with the same name as *P*, + * *T* has a string or numeric index signature, + * *T* has no properties, or + * *T* is the global type 'Object'. +* *T* is a union or intersection type and *P* is expected in at least one of the constituent types of *T*. + +The type inferred for an object literal (as described in section [4.5](#4.5)) is considered a ***fresh object literal type***. The freshness disappears when an object literal type is widened ([3.12](#3.12)) or is the type of the expression in a type assertion ([4.16](#4.16)). + +Consider the following example: + +```TypeScript +interface CompilerOptions { + strict?: boolean; + sourcePath?: string; + targetPath?: string; +} + +var options: CompilerOptions = { + strict: true, + sourcepath: "./src", // Error, excess or misspelled property + targetpath: "./bin" // Error, excess or misspelled property +}; +``` + +The 'CompilerOptions' type contains only optional properties, so without the excess property check, *any* object literal would be assignable to the 'options' variable (because a misspelled property would just be considered an excess property of a different name). + +In cases where excess properties are expected, an index signature can be added to the target type as an indicator of intent: + +```TypeScript +interface InputElement { + name: string; + visible?: boolean; + [x: string]: any; // Allow additional properties of any type +} + +var address: InputElement = { + name: "Address", + visible: true, + help: "Enter address here", // Allowed because of index signature + shortcut: "Alt-A" // Allowed because of index signature +}; +``` + +### 3.11.6 Contextual Signature Instantiation + +During type argument inference in a function call (section [4.15.2](#4.15.2)) it is in certain circumstances necessary to instantiate a generic call signature of an argument expression in the context of a non-generic call signature of a parameter such that further inferences can be made. A generic call signature *A* is ***instantiated in the context of*** non-generic call signature *B* as follows: + +* Using the process described in [3.11.7](#3.11.7), inferences for *A*'s type parameters are made from each parameter type in *B* to the corresponding parameter type in *A* for those parameter positions that are present in both signatures, where rest parameters correspond to an unbounded expansion of optional parameters of the rest parameter element type. +* The inferred type argument for each type parameter is the union type of the set of inferences made for that type parameter. However, if the union type does not satisfy the constraint of the type parameter, the inferred type argument is instead the constraint. + +### 3.11.7 Type Inference + +In certain contexts, inferences for a given set of type parameters are made *from* a type *S*, in which those type parameters do not occur, *to* another type *T*, in which those type parameters do occur. Inferences consist of a set of candidate type arguments collected for each of the type parameters. The inference process recursively relates *S* and *T* to gather as many inferences as possible: + +* If *T* is one of the type parameters for which inferences are being made, *S* is added to the set of inferences for that type parameter. +* Otherwise, if *S* and *T* are references to the same generic type, inferences are made from each type argument in *S* to each corresponding type argument in *T*. +* Otherwise, if *S* and *T* are tuple types with the same number of elements, inferences are made from each element type in *S* to each corresponding element type in *T*. +* Otherwise, if *T* is a union or intersection type: + * First, inferences are made from *S* to each constituent type in *T* that isn't simply one of the type parameters for which inferences are being made. + * If the first step produced no inferences then if T is a union type and exactly one constituent type in *T* is simply a type parameter for which inferences are being made, inferences are made from *S* to that type parameter. +* Otherwise, if *S* is a union or intersection type, inferences are made from each constituent type in *S* to *T*. +* Otherwise, if *S* and *T* are object types, then for each member *M* in *T*: + * If *M* is a property and *S* contains a property *N* with the same name as *M*, inferences are made from the type of *N* to the type of *M*. + * If *M* is a call signature and a corresponding call signature *N* exists in *S*, *N* is instantiated with the Any type as an argument for each type parameter (if any) and inferences are made from parameter types in *N* to the corresponding parameter types in *M* for positions that are present in both signatures, and from the return type of *N* to the return type of *M*. + * If *M* is a construct signature and a corresponding construct signature *N* exists in *S*, *N* is instantiated with the Any type as an argument for each type parameter (if any) and inferences are made from parameter types in *N* to the corresponding parameter types in *M* for positions that are present in both signatures, and from the return type of *N* to the return type of *M*. + * If *M* is a string index signature and *S* contains a string index signature *N*, inferences are made from the type of *N* to the type of *M*. + * If *M* is a numeric index signature and *S* contains a numeric index signature *N*, inferences are made from the type of *N* to the type of *M*. + * If *M* is a numeric index signature and *S* contains a string index signature *N*, inferences are made from the type of *N* to the type of *M*. + +When comparing call or construct signatures, signatures in *S* correspond to signatures of the same kind in *T* pairwise in declaration order. If *S* and *T* have different numbers of a given kind of signature, the excess *first* signatures in declaration order of the longer list are ignored. + +*TODO: Update to reflect [improved union and intersection type inference](https://github.com/Microsoft/TypeScript/pull/5738)*. + +### 3.11.8 Recursive Types + +Classes and interfaces can reference themselves in their internal structure, in effect creating recursive types with infinite nesting. For example, the type + +```TypeScript +interface A { next: A; } +``` + +contains an infinitely nested sequence of 'next' properties. Types such as this are perfectly valid but require special treatment when determining type relationships. Specifically, when comparing types *S* and *T* for a given relationship (identity, subtype, or assignability), the relationship in question is assumed to be true for every directly or indirectly nested occurrence of the same *S* and the same *T* (where same means originating in the same declaration and, if applicable, having identical type arguments). For example, consider the identity relationship between 'A' above and 'B' below: + +```TypeScript +interface B { next: C; } + +interface C { next: D; } + +interface D { next: B; } +``` + +To determine whether 'A' and 'B' are identical, first the 'next' properties of type 'A' and 'C' are compared. That leads to comparing the 'next' properties of type 'A' and 'D', which leads to comparing the 'next' properties of type 'A' and 'B'. Since 'A' and 'B' are already being compared this relationship is by definition true. That in turn causes the other comparisons to be true, and therefore the final result is true. + +When this same technique is used to compare generic type references, two type references are considered the same when they originate in the same declaration and have identical type arguments. + +In certain circumstances, generic types that directly or indirectly reference themselves in a recursive fashion can lead to infinite series of distinct instantiations. For example, in the type + +```TypeScript +interface List { + data: T; + next: List; + owner: List>; +} +``` + +'List<T>' has a member 'owner' of type 'List<List<T>>', which has a member 'owner' of type 'List<List<List<T>>>', which has a member 'owner' of type 'List<List<List<List<T>>>>' and so on, ad infinitum. Since type relationships are determined structurally, possibly exploring the constituent types to their full depth, in order to determine type relationships involving infinitely expanding generic types it may be necessary for the compiler to terminate the recursion at some point with the assumption that no further exploration will change the outcome. + +## 3.12 Widened Types + +In several situations TypeScript infers types from context, alleviating the need for the programmer to explicitly specify types that appear obvious. For example + +```TypeScript +var name = "Steve"; +``` + +infers the type of 'name' to be the String primitive type since that is the type of the value used to initialize it. When inferring the type of a variable, property or function result from an expression, the ***widened*** form of the source type is used as the inferred type of the target. The widened form of a type is the type in which all occurrences of the Null and Undefined types have been replaced with the type `any`. + +The following example shows the results of widening types to produce inferred variable types. + +```TypeScript +var a = null; // var a: any +var b = undefined; // var b: any +var c = { x: 0, y: null }; // var c: { x: number, y: any } +var d = [ null, undefined ]; // var d: any[] +``` + +
+ +#
4 Expressions + +This chapter describes the manner in which TypeScript provides type inference and type checking for JavaScript expressions. TypeScript's type analysis occurs entirely at compile-time and adds no run-time overhead to expression evaluation. + +TypeScript's typing rules define a type for every expression construct. For example, the type of the literal 123 is the Number primitive type, and the type of the object literal { a: 10, b: "hello" } is { a: number; b: string; }. The sections in this chapter describe these rules in detail. + +In addition to type inference and type checking, TypeScript augments JavaScript expressions with the following constructs: + +* Optional parameter and return type annotations in function expressions and arrow functions. +* Type arguments in function calls. +* Type assertions. + +Unless otherwise noted in the sections that follow, TypeScript expressions and the JavaScript expressions generated from them are identical. + +## 4.1 Values and References + +Expressions are classified as ***values*** or ***references***. References are the subset of expressions that are permitted as the target of an assignment. Specifically, references are combinations of identifiers (section [4.3](#4.3)), parentheses (section [4.8](#4.8)), and property accesses (section [4.13](#4.13)). All other expression constructs described in this chapter are classified as values. + +## 4.2 The this Keyword + +The type of `this` in an expression depends on the location in which the reference takes place: + +* In a constructor, instance member function, instance member accessor, or instance member variable initializer, `this` is of the this-type (section [3.6.3](#3.6.3)) of the containing class. +* In a static member function or static member accessor, the type of `this` is the constructor function type of the containing class. +* In a function declaration or a function expression, `this` is of type Any. +* In the global namespace, `this` is of type Any. + +In all other contexts it is a compile-time error to reference `this`. + +Note that an arrow function (section [4.11](#4.11)) has no `this` parameter but rather preserves the `this` of its enclosing context. + +## 4.3 Identifiers + +When an expression is an *IdentifierReference*, the expression refers to the most nested namespace, class, enum, function, variable, or parameter with that name whose scope (section [2.4](#2.4)) includes the location of the reference. The type of such an expression is the type associated with the referenced entity: + +* For a namespace, the object type associated with the namespace instance. +* For a class, the constructor type associated with the constructor function object. +* For an enum, the object type associated with the enum object. +* For a function, the function type associated with the function object. +* For a variable, the type of the variable. +* For a parameter, the type of the parameter. + +An identifier expression that references a variable or parameter is classified as a reference. An identifier expression that references any other kind of entity is classified as a value (and therefore cannot be the target of an assignment). + +## 4.4 Literals + +Literals are typed as follows: + +* The type of the `null` literal is the Null primitive type. +* The type of the literals `true` and `false` is the Boolean primitive type. +* The type of numeric literals is the Number primitive type. +* The type of string literals is the String primitive type. +* The type of regular expression literals is the global interface type 'RegExp'. + +## 4.5 Object Literals + +Object literals are extended to support type annotations in methods and get and set accessors. + +  *PropertyDefinition:* *( Modified )* +   *IdentifierReference* +   *CoverInitializedName* +   *PropertyName* `:` *AssignmentExpression* +   *PropertyName* *CallSignature* `{` *FunctionBody* `}` +   *GetAccessor* +   *SetAccessor* + +  *GetAccessor:* +   `get` *PropertyName* `(` `)` *TypeAnnotationopt* `{` *FunctionBody* `}` + +  *SetAccessor:* +   `set` *PropertyName* `(` *BindingIdentifierOrPattern* *TypeAnnotationopt* `)` `{` *FunctionBody* `}` + +The type of an object literal is an object type with the set of properties specified by the property assignments in the object literal. A get and set accessor may specify the same property name, but otherwise it is an error to specify multiple property assignments for the same property. + +A shorthand property assignment of the form + +```TypeScript +prop +``` + +is equivalent to + +```TypeScript +prop : prop +``` + +Likewise, a property assignment of the form + +```TypeScript +f ( ... ) { ... } +``` + +is equivalent to + +```TypeScript +f : function ( ... ) { ... } +``` + +Each property assignment in an object literal is processed as follows: + +* If the object literal is contextually typed and the contextual type contains a property with a matching name, the property assignment is contextually typed by the type of that property. +* Otherwise, if the object literal is contextually typed, if the contextual type contains a numeric index signature, and if the property assignment specifies a numeric property name, the property assignment is contextually typed by the type of the numeric index signature. +* Otherwise, if the object literal is contextually typed and the contextual type contains a string index signature, the property assignment is contextually typed by the type of the string index signature. +* Otherwise, the property assignment is processed without a contextual type. + +The type of a property introduced by a property assignment of the form *Name* `:` *Expr* is the type of *Expr*. + +A get accessor declaration is processed in the same manner as an ordinary function declaration (section [6.1](#6.1)) with no parameters. A set accessor declaration is processed in the same manner as an ordinary function declaration with a single parameter and a Void return type. When both a get and set accessor is declared for a property: + +* If both accessors include type annotations, the specified types must be identical. +* If only one accessor includes a type annotation, the other behaves as if it had the same type annotation. +* If neither accessor includes a type annotation, the inferred return type of the get accessor becomes the parameter type of the set accessor. + +If a get accessor is declared for a property, the return type of the get accessor becomes the type of the property. If only a set accessor is declared for a property, the parameter type (which may be type Any if no type annotation is present) of the set accessor becomes the type of the property. + +When an object literal is contextually typed by a type that includes a string index signature, the resulting type of the object literal includes a string index signature with the union type of the types of the properties declared in the object literal, or the Undefined type if the object literal is empty. Likewise, when an object literal is contextually typed by a type that includes a numeric index signature, the resulting type of the object literal includes a numeric index signature with the union type of the types of the numerically named properties (section [3.9.4](#3.9.4)) declared in the object literal, or the Undefined type if the object literal declares no numerically named properties. + +If the *PropertyName* of a property assignment is a computed property name that doesn't denote a well-known symbol ([2.2.3](#2.2.3)), the construct is considered a ***dynamic property assignment***. The following rules apply to dynamic property assignments: + +* A dynamic property assignment does not introduce a property in the type of the object literal. +* The property name expression of a dynamic property assignment must be of type Any or the String, Number, or Symbol primitive type. +* The name associated with a dynamic property assignment is considered to be a numeric property name if the property name expression is of type Any or the Number primitive type. + +## 4.6 Array Literals + +An array literal + +```TypeScript +[ expr1, expr2, ..., exprN ] +``` + +denotes a value of an array type (section [3.3.2](#3.3.2)) or a tuple type (section [3.3.3](#3.3.3)) depending on context. + +Each element expression in a non-empty array literal is processed as follows: + +* If the array literal contains no spread elements, and if the array literal is contextually typed (section [4.23](#4.23)) by a type *T* and *T* has a property with the numeric name *N*, where *N* is the index of the element expression in the array literal, the element expression is contextually typed by the type of that property. +* Otherwise, if the array literal is contextually typed by a type *T* with a numeric index signature, the element expression is contextually typed by the type of the numeric index signature. +* Otherwise, the element expression is not contextually typed. + +The resulting type an array literal expression is determined as follows: + +* If the array literal is empty, the resulting type is an array type with the element type Undefined. +* Otherwise, if the array literal contains no spread elements and is contextually typed by a tuple-like type (section [3.3.3](#3.3.3)), the resulting type is a tuple type constructed from the types of the element expressions. +* Otherwise, if the array literal contains no spread elements and is an array assignment pattern in a destructuring assignment (section [4.21.1](#4.21.1)), the resulting type is a tuple type constructed from the types of the element expressions. +* Otherwise, the resulting type is an array type with an element type that is the union of the types of the non-spread element expressions and the numeric index signature types of the spread element expressions. + +A spread element must specify an expression of an array-like type (section [3.3.2](#3.3.2)), or otherwise an error occurs. + +*TODO: The compiler currently doesn't support applying the spread operator to a string (to spread the individual characters of a string into a string array). This will eventually be allowed, but only when the code generation target is ECMAScript 2015 or later*. + +*TODO: Document spreading an [iterator](https://github.com/Microsoft/TypeScript/pull/2498) into an array literal*. + +The rules above mean that an array literal is always of an array type, unless it is contextually typed by a tuple-like type. For example + +```TypeScript +var a = [1, 2]; // number[] +var b = ["hello", true]; // (string | boolean)[] +var c: [number, string] = [3, "three"]; // [number, string] +``` + +When the output target is ECMAScript 3 or 5, array literals containing spread elements are rewritten to invocations of the `concat` method. For example, the assignments + +```TypeScript +var a = [2, 3, 4]; +var b = [0, 1, ...a, 5, 6]; +``` + +are rewritten to + +```TypeScript +var a = [2, 3, 4]; +var b = [0, 1].concat(a, [5, 6]); +``` + +## 4.7 Template Literals + +*TODO: [Template literals](https://github.com/Microsoft/TypeScript/pull/960)*. + +## 4.8 Parentheses + +A parenthesized expression + +```TypeScript +( expr ) +``` + +has the same type and classification as the contained expression itself. Specifically, if the contained expression is classified as a reference, so is the parenthesized expression. + +## 4.9 The super Keyword + +The `super` keyword can be used in expressions to reference base class properties and the base class constructor. + +### 4.9.1 Super Calls + +Super calls consist of the keyword `super` followed by an argument list enclosed in parentheses. Super calls are only permitted in constructors of derived classes, as described in section [8.3.2](#8.3.2). + +A super call invokes the constructor of the base class on the instance referenced by `this`. A super call is processed as a function call (section [4.15](#4.15)) using the construct signatures of the base class constructor function type as the initial set of candidate signatures for overload resolution. Type arguments cannot be explicitly specified in a super call. If the base class is a generic class, the type arguments used to process a super call are always those specified in the `extends` clause that references the base class. + +The type of a super call expression is Void. + +The JavaScript code generated for a super call is specified in section [8.7.2](#8.7.2). + +### 4.9.2 Super Property Access + +A super property access consists of the keyword `super` followed by a dot and an identifier. Super property accesses are used to access base class member functions from derived classes and are permitted in contexts where `this` (section [4.2](#4.2)) references a derived class instance or a derived class constructor function. Specifically: + +* In a constructor, instance member function, instance member accessor, or instance member variable initializer where `this` references a derived class instance, a super property access is permitted and must specify a public instance member function of the base class. +* In a static member function or static member accessor where `this` references the constructor function object of a derived class, a super property access is permitted and must specify a public static member function of the base class. + +Super property accesses are not permitted in other contexts, and it is not possible to access other kinds of base class members in a super property access. Note that super property accesses are not permitted inside function expressions nested in the above constructs because `this` is of type Any in such function expressions. + +Super property accesses are typically used to access overridden base class member functions from derived class member functions. For an example of this, see section [8.4.2](#8.4.2). + +The JavaScript code generated for a super property access is specified in section [8.7.2](#8.7.2). + +*TODO: Update section to include [bracket notation in super property access](https://github.com/Microsoft/TypeScript/issues/3970)*. + +## 4.10 Function Expressions + +Function expressions are extended from JavaScript to optionally include parameter and return type annotations. + +  *FunctionExpression:* *( Modified )* +   `function` *BindingIdentifieropt* *CallSignature* `{` *FunctionBody* `}` + +The descriptions of function declarations provided in chapter [6](#6) apply to function expressions as well, except that function expressions do not support overloading. + +The type of a function expression is an object type containing a single call signature with parameter and return types inferred from the function expression's signature and body. + +When a function expression with no type parameters and no parameter type annotations is contextually typed (section [4.23](#4.23)) by a type *T* and a contextual signature *S* can be extracted from *T*, the function expression is processed as if it had explicitly specified parameter type annotations as they exist in *S*. Parameters are matched by position and need not have matching names. If the function expression has fewer parameters than *S*, the additional parameters in *S* are ignored. If the function expression has more parameters than *S*, the additional parameters are all considered to have type Any. + +Likewise, when a function expression with no return type annotation is contextually typed (section [4.23](#4.23)) by a function type *T* and a contextual signature *S* can be extracted from *T*, expressions in contained return statements (section [5.10](#5.10)) are contextually typed by the return type of *S*. + +A contextual signature *S* is extracted from a function type *T* as follows: + +* If *T* is a function type with exactly one call signature, and if that call signature is non-generic, *S* is that signature. +* If *T* is a union type, let *U* be the set of element types in *T* that have call signatures. If each type in *U* has exactly one call signature and that call signature is non-generic, and if all of the signatures are identical ignoring return types, then *S* is a signature with the same parameters and a union of the return types. +* Otherwise, no contextual signature can be extracted from *T*. + +In the example + +```TypeScript +var f: (s: string) => string = function (s) { + return s.toLowerCase(); +}; +``` + +the function expression is contextually typed by the type of 'f', and since the function expression has no type parameters or type annotations its parameter type information is extracted from the contextual type, thus inferring the type of 's' to be the String primitive type. + +## 4.11 Arrow Functions + +Arrow functions are extended from JavaScript to optionally include parameter and return type annotations. + +  *ArrowFormalParameters:* *( Modified )* +   *CallSignature* + +The descriptions of function declarations provided in chapter [6](#6) apply to arrow functions as well, except that arrow functions do not support overloading. + +The type of an arrow function is determined in the same manner as a function expression (section [4.10](#4.10)). Likewise, parameters of an arrow function and return statements in the body of an arrow function are contextually typed in the same manner as for function expressions. + +When an arrow function with an expression body and no return type annotation is contextually typed (section [4.23](#4.23)) by a function type *T* and a contextual signature *S* can be extracted from *T*, the expression body is contextually typed by the return type of *S*. + +An arrow function expression of the form + +```TypeScript +( ... ) => expr +``` + +is exactly equivalent to + +```TypeScript +( ... ) => { return expr ; } +``` + +Furthermore, arrow function expressions of the forms + +```TypeScript +id => { ... } +id => expr +``` + +are exactly equivalent to + +```TypeScript +( id ) => { ... } +( id ) => expr +``` + +Thus, the following examples are all equivalent: + +```TypeScript +(x) => { return Math.sin(x); } +(x) => Math.sin(x) +x => { return Math.sin(x); } +x => Math.sin(x) +``` + +A function expression introduces a new dynamically bound `this`, whereas an arrow function expression preserves the `this` of its enclosing context. Arrow function expressions are particularly useful for writing callbacks, which otherwise often have an undefined or unexpected `this`. + +In the example + +```TypeScript +class Messenger { + message = "Hello World"; + start() { + setTimeout(() => alert(this.message), 3000); + } +}; + +var messenger = new Messenger(); +messenger.start(); +``` + +the use of an arrow function expression causes the callback to have the same `this` as the surrounding 'start' method. Writing the callback as a standard function expression it becomes necessary to manually arrange access to the surrounding `this`, for example by copying it into a local variable: + +```TypeScript +class Messenger { + message = "Hello World"; + start() { + var _this = this; + setTimeout(function() { alert(_this.message); }, 3000); + } +}; + +var messenger = new Messenger(); +messenger.start(); +``` + +The TypeScript compiler applies this type of transformation to rewrite arrow function expressions into standard function expressions. + +A construct of the form + +```TypeScript +< T > ( ... ) => { ... } +``` + +could be parsed as an arrow function expression with a type parameter or a type assertion applied to an arrow function with no type parameter. It is resolved as the former, but parentheses can be used to select the latter meaning: + +```TypeScript +< T > ( ( ... ) => { ... } ) +``` + +## 4.12 Class Expressions + +*TODO: Document [class expressions](https://github.com/Microsoft/TypeScript/issues/497)*. + +## 4.13 Property Access + +A property access uses either dot notation or bracket notation. A property access expression is always classified as a reference. + +A dot notation property access of the form + +```TypeScript +object . name +``` + +where *object* is an expression and *name* is an identifier (including, possibly, a reserved word), is used to access the property with the given name on the given object. A dot notation property access is processed as follows at compile-time: + +* If *object* is of type Any, any *name* is permitted and the property access is of type Any. +* Otherwise, if *name* denotes an accessible apparent property (section [3.11.1](#3.11.1)) in the widened type (section [3.12](#3.12)) of *object*, the property access is of the type of that property. Public members are always accessible, but private and protected members of a class have restricted accessibility, as described in [8.2.2](#8.2.2). +* Otherwise, the property access is invalid and a compile-time error occurs. + +A bracket notation property access of the form + +```TypeScript +object [ index ] +``` + +where *object* and *index* are expressions, is used to access the property with the name computed by the index expression on the given object. A bracket notation property access is processed as follows at compile-time: + +* If *index* is a string literal or a numeric literal and *object* has an apparent property (section [3.11.1](#3.11.1)) with the name given by that literal (converted to its string representation in the case of a numeric literal), the property access is of the type of that property. +* Otherwise, if *object* has an apparent numeric index signature and *index* is of type Any, the Number primitive type, or an enum type, the property access is of the type of that index signature. +* Otherwise, if *object* has an apparent string index signature and *index* is of type Any, the String or Number primitive type, or an enum type, the property access is of the type of that index signature. +* Otherwise, if *index* is of type Any, the String or Number primitive type, or an enum type, the property access is of type Any. +* Otherwise, the property access is invalid and a compile-time error occurs. + +*TODO: Indexing with [symbols](https://github.com/Microsoft/TypeScript/pull/1978)*. + +The rules above mean that properties are strongly typed when accessed using bracket notation with the literal representation of their name. For example: + +```TypeScript +var type = { + name: "boolean", + primitive: true +}; + +var s = type["name"]; // string +var b = type["primitive"]; // boolean +``` + +Tuple types assign numeric names to each of their elements and elements are therefore strongly typed when accessed using bracket notation with a numeric literal: + +```TypeScript +var data: [string, number] = ["five", 5]; +var s = data[0]; // string +var n = data[1]; // number +``` + +## 4.14 The new Operator + +A `new` operation has one of the following forms: + +```TypeScript +new C +new C ( ... ) +new C < ... > ( ... ) +``` + +where *C* is an expression. The first form is equivalent to supplying an empty argument list. *C* must be of type Any or of an object type with one or more construct or call signatures. The operation is processed as follows at compile-time: + +* If *C* is of type Any, any argument list is permitted and the result of the operation is of type Any. +* If *C* has one or more apparent construct signatures (section [3.11.1](#3.11.1)), the expression is processed in the same manner as a function call, but using the construct signatures as the initial set of candidate signatures for overload resolution. The result type of the function call becomes the result type of the operation. +* If *C* has no apparent construct signatures but one or more apparent call signatures, the expression is processed as a function call. A compile-time error occurs if the result of the function call is not Void. The type of the result of the operation is Any. + +## 4.15 Function Calls + +Function calls are extended from JavaScript to support optional type arguments. + +  *Arguments:* *( Modified )* +   *TypeArgumentsopt* `(` *ArgumentListopt* `)` + +A function call takes one of the forms + +```TypeScript +func ( ... ) +func < ... > ( ... ) +``` + +where *func* is an expression of a function type or of type Any. The function expression is followed by an optional type argument list (section [3.6.2](#3.6.2)) and an argument list. + +If *func* is of type Any, or of an object type that has no call or construct signatures but is a subtype of the Function interface, the call is an ***untyped function call***. In an untyped function call no type arguments are permitted, argument expressions can be of any type and number, no contextual types are provided for the argument expressions, and the result is always of type Any. + +If *func* has apparent call signatures (section [3.11.1](#3.11.1)) the call is a ***typed function call***. TypeScript employs ***overload resolution*** in typed function calls in order to support functions with multiple call signatures. Furthermore, TypeScript may perform ***type argument inference*** to automatically determine type arguments in generic function calls. + +### 4.15.1 Overload Resolution + +The purpose of overload resolution in a function call is to ensure that at least one signature is applicable, to provide contextual types for the arguments, and to determine the result type of the function call, which could differ between the multiple applicable signatures. Overload resolution has no impact on the run-time behavior of a function call. Since JavaScript doesn't support function overloading, all that matters at run-time is the name of the function. + +*TODO: Describe use of [wildcard function types](https://github.com/Microsoft/TypeScript/issues/3970) in overload resolution*. + +The compile-time processing of a typed function call consists of the following steps: + +* First, a list of candidate signatures is constructed from the call signatures in the function type in declaration order. For classes and interfaces, inherited signatures are considered to follow explicitly declared signatures in `extends` clause order. + * A non-generic signature is a candidate when + * the function call has no type arguments, and + * the signature is applicable with respect to the argument list of the function call. + * A generic signature is a candidate in a function call without type arguments when + * type inference (section [4.15.2](#4.15.2)) succeeds for each type parameter, + * once the inferred type arguments are substituted for their associated type parameters, the signature is applicable with respect to the argument list of the function call. + * A generic signature is a candidate in a function call with type arguments when + * The signature has the same number of type parameters as were supplied in the type argument list, + * the type arguments satisfy their constraints, and + * once the type arguments are substituted for their associated type parameters, the signature is applicable with respect to the argument list of the function call. +* If the list of candidate signatures is empty, the function call is an error. +* Otherwise, if the candidate list contains one or more signatures for which the type of each argument expression is a subtype of each corresponding parameter type, the return type of the first of those signatures becomes the return type of the function call. +* Otherwise, the return type of the first signature in the candidate list becomes the return type of the function call. + +A signature is said to be an ***applicable signature*** with respect to an argument list when + +* the number of arguments is not less than the number of required parameters, +* the number of arguments is not greater than the number of parameters, and +* for each argument expression *e* and its corresponding parameter *P,* when *e* is contextually typed (section [4.23](#4.23)) by the type of *P*, no errors ensue and the type of *e* is assignable to (section [3.11.4](#3.11.4)) the type of *P*. + +*TODO: [Spread operator in function calls](https://github.com/Microsoft/TypeScript/pull/1931) and spreading an [iterator](https://github.com/Microsoft/TypeScript/pull/2498) into a function call*. + +### 4.15.2 Type Argument Inference + +Given a signature < *T1* , *T2* , … , *Tn* > ( *p1* : *P1* , *p2* : *P2* , … , *pm* : *Pm* ), where each parameter type *P* references zero or more of the type parameters *T*, and an argument list ( *e1* , *e2* , … , *em* ), the task of type argument inference is to find a set of type arguments *A1*…*An* to substitute for *T1*…*Tn* such that the argument list becomes an applicable signature. + +*TODO: Update [type argument inference and overload resolution rules](https://github.com/Microsoft/TypeScript/issues/1186)*. + +Type argument inference produces a set of candidate types for each type parameter. Given a type parameter *T* and set of candidate types, the actual inferred type argument is determined as follows: + +* If the set of candidate argument types is empty, the inferred type argument for *T* is *T*'s constraint. +* Otherwise, if at least one of the candidate types is a supertype of all of the other candidate types, let *C* denote the widened form (section [3.12](#3.12)) of the first such candidate type. If *C* satisfies *T*'s constraint, the inferred type argument for *T* is *C*. Otherwise, the inferred type argument for *T* is *T*'s constraint. +* Otherwise, if no candidate type is a supertype of all of the other candidate types, type inference has fails and no type argument is inferred for *T*. + +In order to compute candidate types, the argument list is processed as follows: + +* Initially all inferred type arguments are considered ***unfixed*** with an empty set of candidate types. +* Proceeding from left to right, each argument expression *e* is ***inferentially typed*** by its corresponding parameter type *P*, possibly causing some inferred type arguments to become ***fixed***, and candidate type inferences (section [3.11.7](#3.11.7)) are made for unfixed inferred type arguments from the type computed for *e* to *P*. + +The process of inferentially typing an expression *e* by a type *T* is the same as that of contextually typing *e* by *T*, with the following exceptions: + +* Where expressions contained within *e* would be contextually typed, they are instead inferentially typed. +* When a function expression is inferentially typed (section [4.10](#4.10)) and a type assigned to a parameter in that expression references type parameters for which inferences are being made, the corresponding inferred type arguments to become ***fixed*** and no further candidate inferences are made for them. +* If *e* is an expression of a function type that contains exactly one generic call signature and no other members, and *T* is a function type with exactly one non-generic call signature and no other members, then any inferences made for type parameters referenced by the parameters of *T*'s call signature are ***fixed***, and *e*'s type is changed to a function type with *e*'s call signature instantiated in the context of *T*'s call signature (section [3.11.6](#3.11.6)). + +An example: + +```TypeScript +function choose(x: T, y: T): T { + return Math.random() < 0.5 ? x : y; +} + +var x = choose(10, 20); // Ok, x of type number +var y = choose("Five", 5); // Error +``` + +In the first call to 'choose', two inferences are made from 'number' to 'T', one for each parameter. Thus, 'number' is inferred for 'T' and the call is equivalent to + +```TypeScript +var x = choose(10, 20); +``` + +In the second call to 'choose', an inference is made from type 'string' to 'T' for the first parameter and an inference is made from type 'number' to 'T' for the second parameter. Since neither 'string' nor 'number' is a supertype of the other, type inference fails. That in turn means there are no applicable signatures and the function call is an error. + +In the example + +```TypeScript +function map(a: T[], f: (x: T) => U): U[] { + var result: U[] = []; + for (var i = 0; i < a.length; i++) result.push(f(a[i])); + return result; +} + +var names = ["Peter", "Paul", "Mary"]; +var lengths = map(names, s => s.length); +``` + +inferences for 'T' and 'U' in the call to 'map' are made as follows: For the first parameter, inferences are made from the type 'string[]' (the type of 'names') to the type 'T[]', inferring 'string' for 'T'. For the second parameter, inferential typing of the arrow expression 's => s.length' causes 'T' to become fixed such that the inferred type 'string' can be used for the parameter 's'. The return type of the arrow expression can then be determined, and inferences are made from the type '(s: string) => number' to the type '(x: T) => U', inferring 'number' for 'U'. Thus the call to 'map' is equivalent to + +```TypeScript +var lengths = map(names, s => s.length); +``` + +and the resulting type of 'lengths' is therefore 'number[]'. + +In the example + +```TypeScript +function zip(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] { + var len = Math.max(x.length, y.length); + var result: U[] = []; + for (var i = 0; i < len; i++) result.push(combine(x[i])(y[i])); + return result; +} + +var names = ["Peter", "Paul", "Mary"]; +var ages = [7, 9, 12]; +var pairs = zip(names, ages, s => n => ({ name: s, age: n })); +``` + +inferences for 'S', 'T' and 'U' in the call to 'zip' are made as follows: Using the first two parameters, inferences of 'string' for 'S' and 'number' for 'T' are made. For the third parameter, inferential typing of the outer arrow expression causes 'S' to become fixed such that the inferred type 'string' can be used for the parameter 's'. When a function expression is inferentially typed, its return expression(s) are also inferentially typed. Thus, the inner arrow function is inferentially typed, causing 'T' to become fixed such that the inferred type 'number' can be used for the parameter 'n'. The return type of the inner arrow function can then be determined, which in turn determines the return type of the function returned from the outer arrow function, and inferences are made from the type '(s: string) => (n: number) => { name: string; age: number }' to the type '(x: S) => (y: T) => R', inferring '{ name: string; age: number }' for 'R'. Thus the call to 'zip' is equivalent to + +```TypeScript +var pairs = zip( + names, ages, s => n => ({ name: s, age: n })); +``` + +and the resulting type of 'pairs' is therefore '{ name: string; age: number }[]'. + +### 4.15.3 Grammar Ambiguities + +The inclusion of type arguments in the *Arguments* production (section [4.15](#4.15)) gives rise to certain ambiguities in the grammar for expressions. For example, the statement + +```TypeScript +f(g(7)); +``` + +could be interpreted as a call to 'f' with two arguments, 'g < A' and 'B > (7)'. Alternatively, it could be interpreted as a call to 'f' with one argument, which is a call to a generic function 'g' with two type arguments and one regular argument. + +The grammar ambiguity is resolved as follows: In a context where one possible interpretation of a sequence of tokens is an *Arguments* production, if the initial sequence of tokens forms a syntactically correct *TypeArguments* production and is followed by a '`(`' token, then the sequence of tokens is processed an *Arguments* production, and any other possible interpretation is discarded. Otherwise, the sequence of tokens is not considered an *Arguments* production. + +This rule means that the call to 'f' above is interpreted as a call with one argument, which is a call to a generic function 'g' with two type arguments and one regular argument. However, the statements + +```TypeScript +f(g < A, B > 7); +f(g < A, B > +(7)); +``` + +are both interpreted as calls to 'f' with two arguments. + +## 4.16 Type Assertions + +TypeScript extends the JavaScript expression grammar with the ability to assert a type for an expression: + +  *UnaryExpression:* *( Modified )* +   … +   `<` *Type* `>` *UnaryExpression* + +A type assertion expression consists of a type enclosed in `<` and `>` followed by a unary expression. Type assertion expressions are purely a compile-time construct. Type assertions are *not* checked at run-time and have no impact on the emitted JavaScript (and therefore no run-time cost). The type and the enclosing `<` and `>` are simply removed from the generated code. + +In a type assertion expression of the form < *T* > *e*, *e* is contextually typed (section [4.23](#4.23)) by *T* and the resulting type of* e* is required to be assignable to *T*, or *T* is required to be assignable to the widened form of the resulting type of *e*, or otherwise a compile-time error occurs. The type of the result is *T*. + +Type assertions check for assignment compatibility in both directions. Thus, type assertions allow type conversions that *might* be correct, but aren't *known* to be correct. In the example + +```TypeScript +class Shape { ... } + +class Circle extends Shape { ... } + +function createShape(kind: string): Shape { + if (kind === "circle") return new Circle(); + ... +} + +var circle = createShape("circle"); +``` + +the type annotations indicate that the 'createShape' function *might* return a 'Circle' (because 'Circle' is a subtype of 'Shape'), but isn't *known* to do so (because its return type is 'Shape'). Therefore, a type assertion is needed to treat the result as a 'Circle'. + +As mentioned above, type assertions are not checked at run-time and it is up to the programmer to guard against errors, for example using the `instanceof` operator: + +```TypeScript +var shape = createShape(shapeKind); +if (shape instanceof Circle) { + var circle = shape; + ... +} +``` + +*TODO: Document [as operator](https://github.com/Microsoft/TypeScript/pull/3564)*. + +## 4.17 JSX Expressions + +*TODO: Document [JSX expressions](https://github.com/Microsoft/TypeScript/issues/3203)*. + +## 4.18 Unary Operators + +The subsections that follow specify the compile-time processing rules of the unary operators. In general, if the operand of a unary operator does not meet the stated requirements, a compile-time error occurs and the result of the operation defaults to type Any in further processing. + +### 4.18.1 The ++ and -- operators + +These operators, in prefix or postfix form, require their operand to be of type Any, the Number primitive type, or an enum type, and classified as a reference (section [4.1](#4.1)). They produce a result of the Number primitive type. + +### 4.18.2 The +, –, and ~ operators + +These operators permit their operand to be of any type and produce a result of the Number primitive type. + +The unary + operator can conveniently be used to convert a value of any type to the Number primitive type: + +```TypeScript +function getValue() { ... } + +var n = +getValue(); +``` + +The example above converts the result of 'getValue()' to a number if it isn't a number already. The type inferred for 'n' is the Number primitive type regardless of the return type of 'getValue'. + +### 4.18.3 The ! operator + +The ! operator permits its operand to be of any type and produces a result of the Boolean primitive type. + +Two unary ! operators in sequence can conveniently be used to convert a value of any type to the Boolean primitive type: + +```TypeScript +function getValue() { ... } + +var b = !!getValue(); +``` + +The example above converts the result of 'getValue()' to a Boolean if it isn't a Boolean already. The type inferred for 'b' is the Boolean primitive type regardless of the return type of 'getValue'. + +### 4.18.4 The delete Operator + +The 'delete' operator takes an operand of any type and produces a result of the Boolean primitive type. + +### 4.18.5 The void Operator + +The 'void' operator takes an operand of any type and produces the value 'undefined'. The type of the result is the Undefined type ([3.2.7](#3.2.7)). + +### 4.18.6 The typeof Operator + +The 'typeof' operator takes an operand of any type and produces a value of the String primitive type. In positions where a type is expected, 'typeof' can also be used in a type query (section [3.8.10](#3.8.10)) to produce the type of an expression. + +```TypeScript +var x = 5; +var y = typeof x; // Use in an expression +var z: typeof x; // Use in a type query +``` + +In the example above, 'x' is of type 'number', 'y' is of type 'string' because when used in an expression, 'typeof' produces a value of type string (in this case the string "number"), and 'z' is of type 'number' because when used in a type query, 'typeof' obtains the type of an expression. + +## 4.19 Binary Operators + +The subsections that follow specify the compile-time processing rules of the binary operators. In general, if the operands of a binary operator do not meet the stated requirements, a compile-time error occurs and the result of the operation defaults to type any in further processing. Tables that summarize the compile-time processing rules for operands of the Any type, the Boolean, Number, and String primitive types, and all other types (the Other column in the tables) are provided. + +### 4.19.1 The *, /, %, –, <<, >>, >>>, &, ^, and | operators + +These operators require their operands to be of type Any, the Number primitive type, or an enum type. Operands of an enum type are treated as having the primitive type Number. If one operand is the `null` or `undefined` value, it is treated as having the type of the other operand. The result is always of the Number primitive type. + +||Any|Boolean|Number|String|Other| +|:---:|:---:|:---:|:---:|:---:|:---:| +|Any|Number||Number||| +|Boolean|||||| +|Number|Number||Number||| +|String|||||| +|Other|||||| + +*TODO: Document the [exponentation operator](https://github.com/Microsoft/TypeScript/issues/4812)*. + +### 4.19.2 The + operator + +The binary + operator requires both operands to be of the Number primitive type or an enum type, or at least one of the operands to be of type Any or the String primitive type. Operands of an enum type are treated as having the primitive type Number. If one operand is the `null` or `undefined` value, it is treated as having the type of the other operand. If both operands are of the Number primitive type, the result is of the Number primitive type. If one or both operands are of the String primitive type, the result is of the String primitive type. Otherwise, the result is of type Any. + +||Any|Boolean|Number|String|Other| +|:---:|:---:|:---:|:---:|:---:|:---:| +|Any|Any|Any|Any|String|Any| +|Boolean|Any|||String|| +|Number|Any||Number|String|| +|String|String|String|String|String|String| +|Other|Any|||String|| + +A value of any type can converted to the String primitive type by adding an empty string: + +```TypeScript +function getValue() { ... } + +var s = getValue() + ""; +``` + +The example above converts the result of 'getValue()' to a string if it isn't a string already. The type inferred for 's' is the String primitive type regardless of the return type of 'getValue'. + +### 4.19.3 The <, >, <=, >=, ==, !=, ===, and !== operators + +These operators require one or both of the operand types to be assignable to the other. The result is always of the Boolean primitive type. + +||Any|Boolean|Number|String|Other| +|:---:|:---:|:---:|:---:|:---:|:---:| +|Any|Boolean|Boolean|Boolean|Boolean|Boolean| +|Boolean|Boolean|Boolean|||| +|Number|Boolean||Boolean||| +|String|Boolean|||Boolean|| +|Other|Boolean||||Boolean| + +### 4.19.4 The instanceof operator + +The `instanceof` operator requires the left operand to be of type Any, an object type, or a type parameter type, and the right operand to be of type Any or a subtype of the 'Function' interface type. The result is always of the Boolean primitive type. + +Note that object types containing one or more call or construct signatures are automatically subtypes of the 'Function' interface type, as described in section [3.3](#3.3). + +### 4.19.5 The in operator + +The `in` operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, and the right operand to be of type Any, an object type, or a type parameter type. The result is always of the Boolean primitive type. + +### 4.19.6 The && operator + +The && operator permits the operands to be of any type and produces a result of the same type as the second operand. + +||Any|Boolean|Number|String|Other| +|:---:|:---:|:---:|:---:|:---:|:---:| +|Any|Any|Boolean|Number|String|Other| +|Boolean|Any|Boolean|Number|String|Other| +|Number|Any|Boolean|Number|String|Other| +|String|Any|Boolean|Number|String|Other| +|Other|Any|Boolean|Number|String|Other| + +### 4.19.7 The || operator + +The || operator permits the operands to be of any type. + +If the || expression is contextually typed (section [4.23](#4.23)), the operands are contextually typed by the same type. Otherwise, the left operand is not contextually typed and the right operand is contextually typed by the type of the left operand. + +The type of the result is the union type of the two operand types. + +||Any|Boolean|Number|String|Other| +|:---:|:---:|:---:|:---:|:---:|:---:| +|Any|Any|Any|Any|Any|Any| +|Boolean|Any|Boolean|N | B|S | B|B | O| +|Number|Any|N | B|Number|S | N|N | O| +|String|Any|S | B|S | N|String|S | O| +|Other|Any|B | O|N | O|S | O|Other| + +## 4.20 The Conditional Operator + +In a conditional expression of the form + +```TypeScript +test ? expr1 : expr2 +``` + +the *test* expression may be of any type. + +If the conditional expression is contextually typed (section [4.23](#4.23)), *expr1* and *expr2* are contextually typed by the same type. Otherwise, *expr1* and *expr2* are not contextually typed. + +The type of the result is the union type of the types of *expr1* and *expr2*. + +## 4.21 Assignment Operators + +An assignment of the form + +```TypeScript +v = expr +``` + +requires *v* to be classified as a reference (section [4.1](#4.1)) or as an assignment pattern (section [4.21.1](#4.21.1)). The *expr* expression is contextually typed (section [4.23](#4.23)) by the type of *v*, and the type of *expr* must be assignable to (section [3.11.4](#3.11.4)) the type of *v*, or otherwise a compile-time error occurs. The result is a value with the type of *expr*. + +A compound assignment of the form + +```TypeScript +v ??= expr +``` + +where ??= is one of the compound assignment operators + +```TypeScript +*= /= %= += -= <<= >>= >>>= &= ^= |= +``` + +is subject to the same requirements, and produces a value of the same type, as the corresponding non-compound operation. A compound assignment furthermore requires *v* to be classified as a reference (section [4.1](#4.1)) and the type of the non-compound operation to be assignable to the type of *v*. Note that *v* is not permitted to be an assignment pattern in a compound assignment. + +### 4.21.1 Destructuring Assignment + +A ***destructuring assignment*** is an assignment operation in which the left hand operand is a destructuring assignment pattern as defined by the *AssignmentPattern* production in the ECMAScript 2015 specification. + +In a destructuring assignment expression, the type of the expression on the right must be assignable to the assignment target on the left. An expression of type *S* is considered assignable to an assignment target *V* if one of the following is true: + +* *V* is variable and *S* is assignable to the type of *V*. +* *V* is an object assignment pattern and, for each assignment property *P* in *V*, + * *S* is the type Any, or + * *S* has an apparent property with the property name specified in *P* of a type that is assignable to the target given in *P*, or + * *P* specifies a numeric property name and *S* has a numeric index signature of a type that is assignable to the target given in *P*, or + * *S* has a string index signature of a type that is assignable to the target given in *P*. +* *V* is an array assignment pattern, *S* is the type Any or an array-like type (section [3.3.2](#3.3.2)), and, for each assignment element *E* in *V*, + * *S* is the type Any, or + * *S* is a tuple-like type (section [3.3.3](#3.3.3)) with a property named *N* of a type that is assignable to the target given in *E*, where *N* is the numeric index of *E* in the array assignment pattern, or + * *S* is not a tuple-like type and the numeric index signature type of *S* is assignable to the target given in *E*. + +*TODO: [Update to specify behavior when assignment element E is a rest element](https://github.com/Microsoft/TypeScript/issues/2713)*. + +In an assignment property or element that includes a default value, the type of the default value must be assignable to the target given in the assignment property or element. + +When the output target is ECMAScript 2015 or higher, destructuring variable assignments remain unchanged in the emitted JavaScript code. When the output target is ECMAScript 3 or 5, destructuring variable assignments are rewritten to series of simple assignments. For example, the destructuring assignment + +```TypeScript +var x = 1; +var y = 2; +[x, y] = [y, x]; +``` + +is rewritten to the simple variable assignments + +```TypeScript +var x = 1; +var y = 2; +_a = [y, x], x = _a[0], y = _a[1]; +var _a; +``` + +## 4.22 The Comma Operator + +The comma operator permits the operands to be of any type and produces a result that is of the same type as the second operand. + +## 4.23 Contextually Typed Expressions + +Type checking of an expression is improved in several contexts by factoring in the type of the destination of the value computed by the expression. In such situations, the expression is said to be ***contextually typed*** by the type of the destination. An expression is contextually typed in the following circumstances: + +* In a variable, parameter, binding property, binding element, or member declaration, an initializer expression is contextually typed by + * the type given in the declaration's type annotation, if any, or otherwise + * for a parameter, the type provided by a contextual signature (section [4.10](#4.10)), if any, or otherwise + * the type implied by the binding pattern in the declaration (section [5.2.3](#5.2.3)), if any. +* In the body of a function declaration, function expression, arrow function, method declaration, or get accessor declaration that has a return type annotation, return expressions are contextually typed by the type given in the return type annotation. +* In the body of a function expression or arrow function that has no return type annotation, if the function expression or arrow function is contextually typed by a function type with exactly one call signature, and if that call signature is non-generic, return expressions are contextually typed by the return type of that call signature. +* In the body of a constructor declaration, return expressions are contextually typed by the containing class type. +* In the body of a get accessor with no return type annotation, if a matching set accessor exists and that set accessor has a parameter type annotation, return expressions are contextually typed by the type given in the set accessor's parameter type annotation. +* In a typed function call, argument expressions are contextually typed by their corresponding parameter types. +* In a contextually typed object literal, each property value expression is contextually typed by + * the type of the property with a matching name in the contextual type, if any, or otherwise + * for a numerically named property, the numeric index type of the contextual type, if any, or otherwise + * the string index type of the contextual type, if any. +* In a contextually typed array literal expression containing no spread elements, an element expression at index *N* is contextually typed by + * the type of the property with the numeric name *N* in the contextual type, if any, or otherwise + * the numeric index type of the contextual type, if any. +* In a contextually typed array literal expression containing one or more spread elements, an element expression at index *N* is contextually typed by the numeric index type of the contextual type, if any. +* In a contextually typed parenthesized expression, the contained expression is contextually typed by the same type. +* In a type assertion, the expression is contextually typed by the indicated type. +* In a || operator expression, if the expression is contextually typed, the operands are contextually typed by the same type. Otherwise, the right expression is contextually typed by the type of the left expression. +* In a contextually typed conditional operator expression, the operands are contextually typed by the same type. +* In an assignment expression, the right hand expression is contextually typed by the type of the left hand expression. + +In the following example + +```TypeScript +interface EventObject { + x: number; + y: number; +} + +interface EventHandlers { + mousedown?: (event: EventObject) => void; + mouseup?: (event: EventObject) => void; + mousemove?: (event: EventObject) => void; +} + +function setEventHandlers(handlers: EventHandlers) { ... } + +setEventHandlers({ + mousedown: e => { startTracking(e.x, e.y); }, + mouseup: e => { endTracking(); } +}); +``` + +the object literal passed to 'setEventHandlers' is contextually typed to the 'EventHandlers' type. This causes the two property assignments to be contextually typed to the unnamed function type '(event: EventObject) => void', which in turn causes the 'e' parameters in the arrow function expressions to automatically be typed as 'EventObject'. + +## 4.24 Type Guards + +Type guards are particular expression patterns involving the 'typeof' and 'instanceof' operators that cause the types of variables or parameters to be ***narrowed*** to more specific types. For example, in the code below, knowledge of the static type of 'x' in combination with a 'typeof' check makes it safe to narrow the type of 'x' to string in the first branch of the 'if' statement and number in the second branch of the 'if' statement. + +```TypeScript +function foo(x: number | string) { + if (typeof x === "string") { + return x.length; // x has type string here + } + else { + return x + 1; // x has type number here + } +} +``` + +The type of a variable or parameter is narrowed in the following situations: + +* In the true branch statement of an 'if' statement, the type of a variable or parameter is *narrowed* by a type guard in the 'if' condition *when true*, provided no part of the 'if' statement contains assignments to the variable or parameter. +* In the false branch statement of an 'if' statement, the type of a variable or parameter is *narrowed* by a type guard in the 'if' condition *when false*, provided no part of the 'if' statement contains assignments to the variable or parameter. +* In the true expression of a conditional expression, the type of a variable or parameter is *narrowed* by a type guard in the condition *when true*, provided no part of the conditional expression contains assignments to the variable or parameter. +* In the false expression of a conditional expression, the type of a variable or parameter is *narrowed* by a type guard in the condition *when false*, provided no part of the conditional expression contains assignments to the variable or parameter. +* In the right operand of a && operation, the type of a variable or parameter is *narrowed* by a type guard in the left operand *when true*, provided neither operand contains assignments to the variable or parameter. +* In the right operand of a || operation, the type of a variable or parameter is *narrowed* by a type guard in the left operand *when false*, provided neither operand contains assignments to the variable or parameter. + +A type guard is simply an expression that follows a particular pattern. The process of narrowing the type of a variable *x* by a type guard *when true* or *when false* depends on the type guard as follows: + +* A type guard of the form `x instanceof C`, where *x* is not of type Any, *C* is of a subtype of the global type 'Function', and *C* has a property named 'prototype' + * *when true*, narrows the type of *x* to the type of the 'prototype' property in *C* provided it is a subtype of the type of *x*, or, if the type of *x* is a union type, removes from the type of *x* all constituent types that aren't subtypes of the type of the 'prototype' property in *C*, or + * *when false*, has no effect on the type of *x*. +* A type guard of the form `typeof x === s`, where *s* is a string literal with the value 'string', 'number', or 'boolean', + * *when true*, narrows the type of *x* to the given primitive type provided it is a subtype of the type of *x*, or, if the type of *x* is a union type, removes from the type of *x* all constituent types that aren't subtypes of the given primitive type, or + * *when false*, removes the primitive type from the type of *x*. +* A type guard of the form `typeof x === s`, where *s* is a string literal with any value but 'string', 'number', or 'boolean', + * *when true*, if *x* is a union type, removes from the type of *x* all constituent types that are subtypes of the string, number, or boolean primitive type, or + * *when false*, has no effect on the type of *x*. +* A type guard of the form `typeof x !== s`, where *s* is a string literal, + * *when true*, narrows the type of x by `typeof x === s` *when false*, or + * *when false*, narrows the type of x by `typeof x === s` *when true*. +* A type guard of the form `!expr` + * *when true*, narrows the type of *x* by *expr* *when false*, or + * *when false*, narrows the type of *x* by *expr* *when true*. +* A type guard of the form `expr1 && expr2` + * *when true*, narrows the type of *x* by *expr1* *when true* and then by *expr2* *when true*, or + * *when false*, narrows the type of *x* to *T1* | *T2*, where *T1* is the type of *x* narrowed by *expr1* *when false*, and *T2* is the type of *x* narrowed by *expr1* *when true* and then by *expr2* *when false*. +* A type guard of the form `expr1 || expr2` + * *when true*, narrows the type of *x* to *T1* | *T2*, where *T1* is the type of *x* narrowed by *expr1* *when true*, and *T2* is the type of *x* narrowed by *expr1* *when false* and then by *expr2* *when true*, or + * *when false*, narrows the type of *x* by *expr1* *when false* and then by *expr2* *when false*. +* A type guard of any other form has no effect on the type of *x*. + +In the rules above, when a narrowing operation would remove all constituent types from a union type, the operation has no effect on the union type. + +Note that type guards affect types of variables and parameters only and have no effect on members of objects such as properties. Also note that it is possible to defeat a type guard by calling a function that changes the type of the guarded variable. + +*TODO: Document [user defined type guard functions](https://github.com/Microsoft/TypeScript/issues/1007)*. + +In the example + +```TypeScript +function isLongString(obj: any) { + return typeof obj === "string" && obj.length > 100; +} +``` + +the `obj` parameter has type `string` in the right operand of the && operator. + +In the example + +```TypeScript +function processValue(value: number | (() => number)) { + var x = typeof value !== "number" ? value() : value; + // Process number in x +} +``` + +the value parameter has type `() => number` in the first conditional expression and type `number` in the second conditional expression, and the inferred type of x is `number`. + +In the example + +```TypeScript +function f(x: string | number | boolean) { + if (typeof x === "string" || typeof x === "number") { + var y = x; // Type of y is string | number + } + else { + var z = x; // Type of z is boolean + } +} +``` + +the type of x is `string | number | boolean` in the left operand of the || operator, `number | boolean` in the right operand of the || operator, `string | number` in the first branch of the if statement, and `boolean` in the second branch of the if statement. + +In the example + +```TypeScript +class C { + data: string | string[]; + getData() { + var data = this.data; + return typeof data === "string" ? data : data.join(" "); + } +} +``` + +the type of the `data` variable is `string` in the first conditional expression and `string[]` in the second conditional expression, and the inferred type of `getData` is `string`. Note that the `data` property must be copied to a local variable for the type guard to have an effect. + +In the example + +```TypeScript +class NamedItem { + name: string; +} + +function getName(obj: Object) { + return obj instanceof NamedItem ? obj.name : "unknown"; +} +``` + +the type of `obj` is narrowed to `NamedItem` in the first conditional expression, and the inferred type of the `getName` function is `string`. + +
+ +#
5 Statements + +This chapter describes the static type checking TypeScript provides for JavaScript statements. TypeScript itself does not introduce any new statement constructs, but it does extend the grammar for local declarations to include interface, type alias, and enum declarations. + +## 5.1 Blocks + +Blocks are extended to include local interface, type alias, and enum declarations (classes are already included by the ECMAScript 2015 grammar). + +  *Declaration:* *( Modified )* +   … +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *EnumDeclaration* + +Local class, interface, type alias, and enum declarations are block scoped, similar to let and const declarations. + +## 5.2 Variable Statements + +Variable statements are extended to include optional type annotations. + +  *VariableDeclaration:* *( Modified )* +   *SimpleVariableDeclaration* +   *DestructuringVariableDeclaration* + +A variable declaration is either a simple variable declaration or a destructuring variable declaration. + +### 5.2.1 Simple Variable Declarations + +A ***simple variable declaration*** introduces a single named variable and optionally assigns it an initial value. + +  *SimpleVariableDeclaration:* +   *BindingIdentifier* *TypeAnnotationopt* *Initializeropt* + +The type *T* of a variable introduced by a simple variable declaration is determined as follows: + +* If the declaration includes a type annotation, *T* is that type. +* Otherwise, if the declaration includes an initializer expression, *T* is the widened form (section [3.12](#3.12)) of the type of the initializer expression. +* Otherwise, *T* is the Any type. + +When a variable declaration specifies both a type annotation and an initializer expression, the type of the initializer expression is required to be assignable to (section [3.11.4](#3.11.4)) the type given in the type annotation. + +Multiple declarations for the same variable name in the same declaration space are permitted, provided that each declaration associates the same type with the variable. + +When a variable declaration has a type annotation, it is an error for that type annotation to use the `typeof` operator to reference the variable being declared. + +Below are some examples of simple variable declarations and their associated types. + +```TypeScript +var a; // any +var b: number; // number +var c = 1; // number +var d = { x: 1, y: "hello" }; // { x: number; y: string; } +var e: any = "test"; // any +``` + +The following is permitted because all declarations of the single variable 'x' associate the same type (Number) with 'x'. + +```TypeScript +var x = 1; +var x: number; +if (x == 1) { + var x = 2; +} +``` + +In the following example, all five variables are of the same type, '{ x: number; y: number; }'. + +```TypeScript +interface Point { x: number; y: number; } + +var a = { x: 0, y: undefined }; +var b: Point = { x: 0, y: undefined }; +var c = { x: 0, y: undefined }; +var d: { x: number; y: number; } = { x: 0, y: undefined }; +var e = <{ x: number; y: number; }> { x: 0, y: undefined }; +``` + +### 5.2.2 Destructuring Variable Declarations + +A ***destructuring variable declaration*** introduces zero or more named variables and initializes them with values extracted from properties of an object or elements of an array. + +  *DestructuringVariableDeclaration:* +   *BindingPattern* *TypeAnnotationopt* *Initializer* + +Each binding property or element that specifies an identifier introduces a variable by that name. The type of the variable is the widened form (section [3.12](#3.12)) of the type associated with the binding property or element, as defined in the following. + +*TODO: Document destructuring an [iterator](https://github.com/Microsoft/TypeScript/pull/2498) into an array*. + +The type *T* associated with a destructuring variable declaration is determined as follows: + +* If the declaration includes a type annotation, *T* is that type. +* Otherwise, if the declaration includes an initializer expression, *T* is the type of that initializer expression. +* Otherwise, *T* is the Any type. + +The type *T* associated with a binding property is determined as follows: + +* Let *S* be the type associated with the immediately containing destructuring variable declaration, binding property, or binding element. +* If *S* is the Any type: + * If the binding property specifies an initializer expression, *T* is the type of that initializer expression. + * Otherwise, *T* is the Any type. +* Let *P* be the property name specified in the binding property. +* If *S* has an apparent property with the name *P*, *T* is the type of that property. +* Otherwise, if *S* has a numeric index signature and *P* is a numerical name, *T* is the type of the numeric index signature. +* Otherwise, if *S* has a string index signature, *T* is the type of the string index signature. +* Otherwise, no type is associated with the binding property and an error occurs. + +The type *T* associated with a binding element is determined as follows: + +* Let *S* be the type associated with the immediately containing destructuring variable declaration, binding property, or binding element. +* If *S* is the Any type: + * If the binding element specifies an initializer expression, *T* is the type of that initializer expression. + * Otherwise, *T* is the Any type. +* If *S* is not an array-like type (section [3.3.2](#3.3.2)), no type is associated with the binding property and an error occurs. +* If the binding element is a rest element, *T* is an array type with an element type *E*, where *E* is the type of the numeric index signature of *S*. +* Otherwise, if *S* is a tuple-like type (section [3.3.3](#3.3.3)): + * Let *N* be the zero-based index of the binding element in the array binding pattern. + * If *S* has a property with the numerical name *N*, *T* is the type of that property. + * Otherwise, no type is associated with the binding element and an error occurs. +* Otherwise, if *S* has a numeric index signature, *T* is the type of the numeric index signature. +* Otherwise, no type is associated with the binding element and an error occurs. + +When a destructuring variable declaration, binding property, or binding element specifies an initializer expression, the type of the initializer expression is required to be assignable to the widened form of the type associated with the destructuring variable declaration, binding property, or binding element. + +*TODO: Update rules to reflect [improved checking of destructuring with literal initializers](https://github.com/Microsoft/TypeScript/pull/4598)*. + +When the output target is ECMAScript 2015 or higher, except for removing the optional type annotation, destructuring variable declarations remain unchanged in the emitted JavaScript code. + +When the output target is ECMAScript 3 or 5, destructuring variable declarations are rewritten to simple variable declarations. For example, an object destructuring declaration of the form + +```TypeScript +var { x, p: y, q: z = false } = getSomeObject(); +``` + +is rewritten to the simple variable declarations + +```TypeScript +var _a = getSomeObject(), + x = _a.x, + y = _a.p, + _b = _a.q, + z = _b === void 0 ? false : _b; +``` + +The '_a' and '_b' temporary variables exist to ensure the assigned expression is evaluated only once, and the expression 'void 0' simply denotes the JavaScript value 'undefined'. + +Similarly, an array destructuring declaration of the form + +```TypeScript +var [x, y, z = 10] = getSomeArray(); +``` + +is rewritten to the simple variable declarations + +```TypeScript +var _a = getSomeArray(), + x = _a[0], + y = _a[1], + _b = _a[2], + z = _b === void 0 ? 10 : _b; +``` + +Combining both forms of destructuring, the example + +```TypeScript +var { x, p: [y, z = 10] = getSomeArray() } = getSomeObject(); +``` + +is rewritten to + +```TypeScript +var _a = getSomeObject(), + x = _a.x, + _b = _a.p, + _c = _b === void 0 ? getSomeArray() : _b, + y = _c[0], + _d = _c[1], + z = _d === void 0 ? 10 : _d; +``` + +### 5.2.3 Implied Type + +A variable, parameter, binding property, or binding element declaration that specifies a binding pattern has an ***implied type*** which is determined as follows: + +* If the declaration specifies an object binding pattern, the implied type is an object type with a set of properties corresponding to the specified binding property declarations. The type of each property is the type implied by its binding property declaration, and a property is optional when its binding property declaration specifies an initializer expression. +* If the declaration specifies an array binding pattern without a rest element, the implied type is a tuple type with elements corresponding to the specified binding element declarations. The type of each element is the type implied by its binding element declaration. +* If the declaration specifies an array binding pattern with a rest element, the implied type is an array type with an element type of Any. + +The implied type of a binding property or binding element declaration is + +* the type of the declaration's initializer expression, if any, or otherwise +* the implied type of the binding pattern specified in the declaration, if any, or otherwise +* the type Any. + +In the example + +```TypeScript +function f({ a, b = "hello", c = 1 }) { ... } +``` + +the implied type of the binding pattern in the function's parameter is '{ a: any; b?: string; c?: number; }'. Since the parameter has no type annotation, this becomes the type of the parameter. + +In the example + +```TypeScript +var [a, b, c] = [1, "hello", true]; +``` + +the array literal initializer expression is contextually typed by the implied type of the binding pattern, specifically the tuple type '[any, any, any]'. Because the contextual type is a tuple type, the resulting type of the array literal is the tuple type '[number, string, boolean]', and the destructuring declaration thus gives the types number, string, and boolean to a, b, and c respectively. + +## 5.3 Let and Const Declarations + +Let and const declarations are exended to include optional type annotations. + +  *LexicalBinding:* *( Modified )* +   *SimpleLexicalBinding* +   *DestructuringLexicalBinding* + +  *SimpleLexicalBinding:* +   *BindingIdentifier* *TypeAnnotationopt* *Initializeropt* + +  *DestructuringLexicalBinding:* +   *BindingPattern* *TypeAnnotationopt* *Initializeropt* + +*TODO: Document scoping and types of [let and const declarations](https://github.com/Microsoft/TypeScript/pull/904)*. + +## 5.4 If, Do, and While Statements + +Expressions controlling 'if', 'do', and 'while' statements can be of any type (and not just type Boolean). + +## 5.5 For Statements + +Variable declarations in 'for' statements are extended in the same manner as variable declarations in variable statements (section [5.2](#5.2)). + +## 5.6 For-In Statements + +In a 'for-in' statement of the form + +```TypeScript +for (v in expr) statement +``` + +*v* must be an expression classified as a reference of type Any or the String primitive type, and *expr* must be an expression of type Any, an object type, or a type parameter type. + +In a 'for-in' statement of the form + +```TypeScript +for (var v in expr) statement +``` + +*v* must be a variable declaration without a type annotation that declares a variable of type Any, and *expr* must be an expression of type Any, an object type, or a type parameter type. + +## 5.7 For-Of Statements + +*TODO: Document [for-of statements](https://github.com/Microsoft/TypeScript/issues/7)*. + +## 5.8 Continue Statements + +A 'continue' statement is required to be nested, directly or indirectly (but not crossing function boundaries), within an iteration ('do', 'while', 'for', or 'for-in') statement. When a 'continue' statement includes a target label, that target label must appear in the label set of an enclosing (but not crossing function boundaries) iteration statement. + +## 5.9 Break Statements + +A 'break' statement is required to be nested, directly or indirectly (but not crossing function boundaries), within an iteration ('do', 'while', 'for', or 'for-in') or 'switch' statement. When a 'break' statement includes a target label, that target label must appear in the label set of an enclosing (but not crossing function boundaries) statement. + +## 5.10 Return Statements + +It is an error for a 'return' statement to occur outside a function body. Specifically, 'return' statements are not permitted at the global level or in namespace bodies. + +A 'return' statement without an expression returns the value 'undefined' and is permitted in the body of any function, regardless of the return type of the function. + +When a 'return' statement includes an expression, if the containing function includes a return type annotation, the return expression is contextually typed (section [4.23](#4.23)) by that return type and must be of a type that is assignable to the return type. Otherwise, if the containing function is contextually typed by a type *T*, *Expr* is contextually typed by *T*'s return type. + +In a function implementation without a return type annotation, the return type is inferred from the 'return' statements in the function body, as described in section [6.3](#6.3). + +In the example + +```TypeScript +function f(): (x: string) => number { + return s => s.length; +} +``` + +the arrow expression in the 'return' statement is contextually typed by the return type of 'f', thus giving type 'string' to 's'. + +## 5.11 With Statements + +Use of the 'with' statement in TypeScript is an error, as is the case in ECMAScript 5's strict mode. Furthermore, within the body of a 'with' statement, TypeScript considers every identifier occurring in an expression (section [4.3](#4.3)) to be of the Any type regardless of its declared type. Because the 'with' statement puts a statically unknown set of identifiers in scope in front of those that are statically known, it is not possible to meaningfully assign a static type to any identifier. + +## 5.12 Switch Statements + +In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from (section [3.11.4](#3.11.4)) the type of the 'switch' expression. + +## 5.13 Throw Statements + +The expression specified in a 'throw' statement can be of any type. + +## 5.14 Try Statements + +The variable introduced by a 'catch' clause of a 'try' statement is always of type Any. It is not possible to include a type annotation in a 'catch' clause. + +
+ +#
6 Functions + +TypeScript extends JavaScript functions to include type parameters, parameter and return type annotations, overloads, default parameter values, and rest parameters. + +## 6.1 Function Declarations + +Function declarations are extended to permit the function body to be omitted in overload declarations. + +  *FunctionDeclaration:* *( Modified )* +   `function` *BindingIdentifieropt* *CallSignature* `{` *FunctionBody* `}` +   `function` *BindingIdentifieropt* *CallSignature* `;` + +A *FunctionDeclaration* introduces a named value of a function type in the containing declaration space. The *BindingIdentifier* is optional only when the function declaration occurs in an export default declaration (section [11.3.4.2](#11.3.4.2)). + +Function declarations that specify a body are called ***function implementations*** and function declarations without a body are called ***function overloads***. It is possible to specify multiple overloads for the same function (i.e. for the same name in the same declaration space), but a function can have at most one implementation. All declarations for the same function must specify the same set of modifiers (i.e. the same combination of `declare`, `export`, and `default`). + +When a function has overload declarations, the overloads determine the call signatures of the type given to the function object and the function implementation signature (if any) must be assignable to that type. Otherwise, the function implementation itself determines the call signature. + +When a function has both overloads and an implementation, the overloads must precede the implementation and all of the declarations must be consecutive with no intervening grammatical elements. + +## 6.2 Function Overloads + +Function overloads allow a more accurate specification of the patterns of invocation supported by a function than is possible with a single signature. The compile-time processing of a call to an overloaded function chooses the best candidate overload for the particular arguments and the return type of that overload becomes the result type the function call expression. Thus, using overloads it is possible to statically describe the manner in which a function's return type varies based on its arguments. Overload resolution in function calls is described further in section [4.15](#4.15). + +Function overloads are purely a compile-time construct. They have no impact on the emitted JavaScript and thus no run-time cost. + +The parameter list of a function overload cannot specify default values for parameters. In other words, an overload may use only the `?` form when specifying optional parameters. + +The following is an example of a function with overloads. + +```TypeScript +function attr(name: string): string; +function attr(name: string, value: string): Accessor; +function attr(map: any): Accessor; +function attr(nameOrMap: any, value?: string): any { + if (nameOrMap && typeof nameOrMap === "string") { + // handle string case + } + else { + // handle map case + } +} +``` + +Note that each overload and the final implementation specify the same identifier. The type of the local variable 'attr' introduced by this declaration is + +```TypeScript +var attr: { + (name: string): string; + (name: string, value: string): Accessor; + (map: any): Accessor; +}; +``` + +Note that the signature of the actual function implementation is not included in the type. + +## 6.3 Function Implementations + +A function implementation without a return type annotation is said to be an ***implicitly typed function***. The return type of an implicitly typed function *f* is inferred from its function body as follows: + +* If there are no return statements with expressions in *f*'s function body, the inferred return type is Void. +* Otherwise, if *f*'s function body directly references *f* or references any implicitly typed functions that through this same analysis reference *f*, the inferred return type is Any. +* Otherwise, if *f* is a contextually typed function expression (section [4.10](#4.10)), the inferred return type is the union type (section [3.4](#3.4)) of the types of the return statement expressions in the function body, ignoring return statements with no expressions. +* Otherwise, the inferred return type is the first of the types of the return statement expressions in the function body that is a supertype (section [3.11.3](#3.11.3)) of each of the others, ignoring return statements with no expressions. A compile-time error occurs if no return statement expression has a type that is a supertype of each of the others. + +In the example + +```TypeScript +function f(x: number) { + if (x <= 0) return x; + return g(x); +} + +function g(x: number) { + return f(x - 1); +} +``` + +the inferred return type for 'f' and 'g' is Any because the functions reference themselves through a cycle with no return type annotations. Adding an explicit return type 'number' to either breaks the cycle and causes the return type 'number' to be inferred for the other. + +An explicitly typed function whose return type isn't the Void type, the Any type, or a union type containing the Void or Any type as a constituent must have at least one return statement somewhere in its body. An exception to this rule is if the function implementation consists of a single 'throw' statement. + +The type of 'this' in a function implementation is the Any type. + +In the signature of a function implementation, a parameter can be marked optional by following it with an initializer. When a parameter declaration includes both a type annotation and an initializer, the initializer expression is contextually typed (section [4.23](#4.23)) by the stated type and must be assignable to the stated type, or otherwise a compile-time error occurs. When a parameter declaration has no type annotation but includes an initializer, the type of the parameter is the widened form (section [3.12](#3.12)) of the type of the initializer expression. + +Initializer expressions are evaluated in the scope of the function body but are not permitted to reference local variables and are only permitted to access parameters that are declared to the left of the parameter they initialize, unless the parameter reference occurs in a nested function expression. + +When the output target is ECMAScript 3 or 5, for each parameter with an initializer, a statement that substitutes the default value for an omitted argument is included in the generated JavaScript, as described in section [6.6](#6.6). The example + +```TypeScript +function strange(x: number, y = x * 2, z = x + y) { + return z; +} +``` + +generates JavaScript that is equivalent to + +```TypeScript +function strange(x, y, z) { + if (y === void 0) { y = x * 2; } + if (z === void 0) { z = x + y; } + return z; +} +``` + +In the example + +```TypeScript +var x = 1; +function f(a = x) { + var x = "hello"; +} +``` + +the local variable 'x' is in scope in the parameter initializer (thus hiding the outer 'x'), but it is an error to reference it because it will always be uninitialized at the time the parameter initializer is evaluated. + +## 6.4 Destructuring Parameter Declarations + +Parameter declarations can specify binding patterns (section [3.9.2.2](#3.9.2.2)) and are then called ***destructuring parameter declarations***. Similar to a destructuring variable declaration (section [5.2.2](#5.2.2)), a destructuring parameter declaration introduces zero or more named locals and initializes them with values extracted from properties or elements of the object or array passed as an argument for the parameter. + +The type of local introduced in a destructuring parameter declaration is determined in the same manner as a local introduced by a destructuring variable declaration, except the type *T* associated with a destructuring parameter declaration is determined as follows: + +* If the declaration includes a type annotation, *T* is that type. +* If the declaration occurs in a function expression for which a contextual signature is available (section [4.10](#4.10)), *T* is the type obtained from the contextual signature. +* Otherwise, if the declaration includes an initializer expression, *T* is the widened form (section [3.12](#3.12)) of the type of the initializer expression. +* Otherwise, if the declaration specifies a binding pattern, *T* is the implied type of that binding pattern (section [5.2.3](#5.2.3)). +* Otherwise, if the parameter is a rest parameter, *T* is `any[]`. +* Otherwise, *T* is `any`. + +When the output target is ECMAScript 2015 or higher, except for removing the optional type annotation, destructuring parameter declarations remain unchanged in the emitted JavaScript code. When the output target is ECMAScript 3 or 5, destructuring parameter declarations are rewritten to local variable declarations. + +The example + +```TypeScript +function drawText({ text = "", location: [x, y] = [0, 0], bold = false }) { + // Draw text +} +``` + +declares a function `drawText` that takes a single parameter of the type + +```TypeScript +{ text?: string; location?: [number, number]; bold?: boolean; } +``` + +When the output target is ECMAScript 3 or 5, the function is rewritten to + +```TypeScript +function drawText(_a) { + var _b = _a.text, + text = _b === void 0 ? "" : _b, + _c = _a.location, + _d = _c === void 0 ? [0, 0] : _c, + x = _d[0], + y = _d[1], + _e = _a.bold, + bold = _e === void 0 ? false : _e; + // Draw text +} +``` + +Destructuring parameter declarations do not permit type annotations on the individual binding patterns, as such annotations would conflict with the already established meaning of colons in object literals. Type annotations must instead be written on the top-level parameter declaration. For example + +```TypeScript +interface DrawTextInfo { + text?: string; + location?: [number, number]; + bold?: boolean; +} + +function drawText({ text, location: [x, y], bold }: DrawTextInfo) { + // Draw text +} +``` + +## 6.5 Generic Functions + +A function implementation may include type parameters in its signature (section [3.9.2.1](#3.9.2.1)) and is then called a ***generic function***. Type parameters provide a mechanism for expressing relationships between parameter and return types in call operations. Type parameters have no run-time representation—they are purely a compile-time construct. + +Type parameters declared in the signature of a function implementation are in scope in the signature and body of that function implementation. + +The following is an example of a generic function: + +```TypeScript +interface Comparable { + localeCompare(other: any): number; +} + +function compare(x: T, y: T): number { + if (x == null) return y == null ? 0 : -1; + if (y == null) return 1; + return x.localeCompare(y); +} +``` + +Note that the 'x' and 'y' parameters are known to be subtypes of the constraint 'Comparable' and therefore have a 'compareTo' member. This is described further in section [3.6.1](#3.6.1). + +The type arguments of a call to a generic function may be explicitly specified in a call operation or may, when possible, be inferred (section [4.15.2](#4.15.2)) from the types of the regular arguments in the call. In the example + +```TypeScript +class Person { + name: string; + localeCompare(other: Person) { + return compare(this.name, other.name); + } +} +``` + +the type argument to 'compare' is automatically inferred to be the String type because the two arguments are strings. + +## 6.6 Code Generation + +A function declaration generates JavaScript code that is equivalent to: + +```TypeScript +function () { + + +} +``` + +*FunctionName* is the name of the function (or nothing in the case of a function expression). + +*FunctionParameters* is a comma separated list of the function's parameter names. + +*DefaultValueAssignments* is a sequence of default property value assignments, one for each parameter with a default value, in the order they are declared, of the form + +```TypeScript +if ( === void 0) { = ; } +``` + +where *Parameter* is the parameter name and *Default* is the default value expression. + +*FunctionStatements* is the code generated for the statements specified in the function body. + +## 6.7 Generator Functions + +*TODO: Document [generator functions](https://github.com/Microsoft/TypeScript/issues/2873)*. + +## 6.8 Asynchronous Functions + +*TODO: Document [asynchronous functions](https://github.com/Microsoft/TypeScript/issues/1664)*. + +## 6.9 Type Guard Functions + +*TODO: Document [type guard functions](https://github.com/Microsoft/TypeScript/issues/1007), including [this type predicates](https://github.com/Microsoft/TypeScript/pull/5906)*. + +
+ +#
7 Interfaces + +Interfaces provide the ability to name and parameterize object types and to compose existing named object types into new ones. + +Interfaces have no run-time representation—they are purely a compile-time construct. Interfaces are particularly useful for documenting and validating the required shape of properties, objects passed as parameters, and objects returned from functions. + +Because TypeScript has a structural type system, an interface type with a particular set of members is considered identical to, and can be substituted for, another interface type or object type literal with an identical set of members (see section [3.11.2](#3.11.2)). + +Class declarations may reference interfaces in their implements clause to validate that they provide an implementation of the interfaces. + +## 7.1 Interface Declarations + +An interface declaration declares an ***interface type***. + +  *InterfaceDeclaration:* +   `interface` *BindingIdentifier* *TypeParametersopt* *InterfaceExtendsClauseopt* *ObjectType* + +  *InterfaceExtendsClause:* +   `extends` *ClassOrInterfaceTypeList* + +  *ClassOrInterfaceTypeList:* +   *ClassOrInterfaceType* +   *ClassOrInterfaceTypeList* `,` *ClassOrInterfaceType* + +  *ClassOrInterfaceType:* +   *TypeReference* + +An *InterfaceDeclaration* introduces a named type (section [3.7](#3.7)) in the containing declaration space. The *BindingIdentifier* of an interface declaration may not be one of the predefined type names (section [3.8.1](#3.8.1)). + +An interface may optionally have type parameters (section [3.6.1](#3.6.1)) that serve as placeholders for actual types to be provided when the interface is referenced in type references. An interface with type parameters is called a ***generic interface***. The type parameters of a generic interface declaration are in scope in the entire declaration and may be referenced in the *InterfaceExtendsClause* and *ObjectType* body. + +An interface can inherit from zero or more ***base types*** which are specified in the *InterfaceExtendsClause*. The base types must be type references to class or interface types. + +An interface has the members specified in the *ObjectType* of its declaration and furthermore inherits all base type members that aren't hidden by declarations in the interface: + +* A property declaration hides a public base type property with the same name. +* A string index signature declaration hides a base type string index signature. +* A numeric index signature declaration hides a base type numeric index signature. + +The following constraints must be satisfied by an interface declaration or otherwise a compile-time error occurs: + +* An interface declaration may not, directly or indirectly, specify a base type that originates in the same declaration. In other words an interface cannot, directly or indirectly, be a base type of itself, regardless of type arguments. +* An interface cannot declare a property with the same name as an inherited private or protected property. +* Inherited properties with the same name must be identical (section [3.11.2](#3.11.2)). +* All properties of the interface must satisfy the constraints implied by the index signatures of the interface as specified in section [3.9.4](#3.9.4). +* The this-type (section [3.6.3](#3.6.3)) of the declared interface must be assignable (section [3.11.4](#3.11.4)) to each of the base type references. + +An interface is permitted to inherit identical members from multiple base types and will in that case only contain one occurrence of each particular member. + +Below is an example of two interfaces that contain properties with the same name but different types: + +```TypeScript +interface Mover { + move(): void; + getStatus(): { speed: number; }; +} + +interface Shaker { + shake(): void; + getStatus(): { frequency: number; }; +} +``` + +An interface that extends 'Mover' and 'Shaker' must declare a new 'getStatus' property as it would otherwise inherit two 'getStatus' properties with different types. The new 'getStatus' property must be declared such that the resulting 'MoverShaker' is a subtype of both 'Mover' and 'Shaker': + +```TypeScript +interface MoverShaker extends Mover, Shaker { + getStatus(): { speed: number; frequency: number; }; +} +``` + +Since function and constructor types are just object types containing call and construct signatures, interfaces can be used to declare named function and constructor types. For example: + +```TypeScript +interface StringComparer { (a: string, b: string): number; } +``` + +This declares type 'StringComparer' to be a function type taking two strings and returning a number. + +## 7.2 Declaration Merging + +Interfaces are "open-ended" and interface declarations with the same qualified name relative to a common root (as defined in section [2.3](#2.3)) contribute to a single interface. + +When a generic interface has multiple declarations, all declarations must have identical type parameter lists, i.e. identical type parameter names with identical constraints in identical order. + +In an interface with multiple declarations, the `extends` clauses are merged into a single set of base types and the bodies of the interface declarations are merged into a single object type. Declaration merging produces a declaration order that corresponds to *prepending* the members of each interface declaration, in the order the members are written, to the combined list of members in the order of the interface declarations. Thus, members declared in the last interface declaration will appear first in the declaration order of the merged type. + +For example, a sequence of declarations in this order: + +```TypeScript +interface Document { + createElement(tagName: any): Element; +} + +interface Document { + createElement(tagName: string): HTMLElement; +} + +interface Document { + createElement(tagName: "div"): HTMLDivElement; + createElement(tagName: "span"): HTMLSpanElement; + createElement(tagName: "canvas"): HTMLCanvasElement; +} +``` + +is equivalent to the following single declaration: + +```TypeScript +interface Document { + createElement(tagName: "div"): HTMLDivElement; + createElement(tagName: "span"): HTMLSpanElement; + createElement(tagName: "canvas"): HTMLCanvasElement; + createElement(tagName: string): HTMLElement; + createElement(tagName: any): Element; +} +``` + +Note that the members of the last interface declaration appear first in the merged declaration. Also note that the relative order of members declared in the same interface body is preserved. + +*TODO: Document [class and interface declaration merging](https://github.com/Microsoft/TypeScript/pull/3333)*. + +## 7.3 Interfaces Extending Classes + +When an interface type extends a class type it inherits the members of the class but not their implementations. It is as if the interface had declared all of the members of the class without providing an implementation. Interfaces inherit even the private and protected members of a base class. When a class containing private or protected members is the base type of an interface type, that interface type can only be implemented by that class or a descendant class. For example: + +```TypeScript +class Control { + private state: any; +} + +interface SelectableControl extends Control { + select(): void; +} + +class Button extends Control { + select() { } +} + +class TextBox extends Control { + select() { } +} + +class Image extends Control { +} + +class Location { + select() { } +} +``` + +In the above example, 'SelectableControl' contains all of the members of 'Control', including the private 'state' property. Since 'state' is a private member it is only possible for descendants of 'Control' to implement 'SelectableControl'. This is because only descendants of 'Control' will have a 'state' private member that originates in the same declaration, which is a requirement for private members to be compatible (section [3.11](#3.11)). + +Within the 'Control' class it is possible to access the 'state' private member through an instance of 'SelectableControl'. Effectively, a 'SelectableControl' acts like a 'Control' that is known to have a 'select' method. The 'Button' and 'TextBox' classes are subtypes of 'SelectableControl' (because they both inherit from 'Control' and have a 'select' method), but the 'Image' and 'Location' classes are not. + +## 7.4 Dynamic Type Checks + +TypeScript does not provide a direct mechanism for dynamically testing whether an object implements a particular interface. Instead, TypeScript code can use the JavaScript technique of checking whether an appropriate set of members are present on the object. For example, given the declarations in section [7.1](#7.1), the following is a dynamic check for the 'MoverShaker' interface: + +```TypeScript +var obj: any = getSomeObject(); +if (obj && obj.move && obj.shake && obj.getStatus) { + var moverShaker = obj; + ... +} +``` + +If such a check is used often it can be abstracted into a function: + +```TypeScript +function asMoverShaker(obj: any): MoverShaker { + return obj && obj.move && obj.shake && obj.getStatus ? obj : null; +} +``` + +
+ +#
8 Classes + +TypeScript extends JavaScript classes to include type parameters, implements clauses, accessibility modifiers, member variable declarations, and parameter property declarations in constructors. + +*TODO: Document [abstract classes](https://github.com/Microsoft/TypeScript/issues/3578)*. + +## 8.1 Class Declarations + +A class declaration declares a ***class type*** and a ***constructor function***. + +  *ClassDeclaration:* *( Modified )* +   `class` *BindingIdentifieropt* *TypeParametersopt* *ClassHeritage* `{` *ClassBody* `}` + +A *ClassDeclaration* introduces a named type (the class type) and a named value (the constructor function) in the containing declaration space. The class type is formed from the instance members declared in the class body and the instance members inherited from the base class. The constructor function is given an anonymous type formed from the constructor declaration, the static member declarations in the class body, and the static members inherited from the base class. The constructor function initializes and returns an instance of the class type. + +The *BindingIdentifier* of a class declaration may not be one of the predefined type names (section [3.8.1](#3.8.1)). The *BindingIdentifier* is optional only when the class declaration occurs in an export default declaration (section [11.3.4.2](#11.3.4.2)). + +A class may optionally have type parameters (section [3.6.1](#3.6.1)) that serve as placeholders for actual types to be provided when the class is referenced in type references. A class with type parameters is called a ***generic class***. The type parameters of a generic class declaration are in scope in the entire declaration and may be referenced in the *ClassHeritage* and *ClassBody*. + +The following example introduces both a named type called 'Point' (the class type) and a named value called 'Point' (the constructor function) in the containing declaration space. + +```TypeScript +class Point { + constructor(public x: number, public y: number) { } + public length() { return Math.sqrt(this.x * this.x + this.y * this.y); } + static origin = new Point(0, 0); +} +``` + +The named type 'Point' is exactly equivalent to + +```TypeScript +interface Point { + x: number; + y: number; + length(): number; +} +``` + +The named value 'Point' is a constructor function whose type corresponds to the declaration + +```TypeScript +var Point: { + new(x: number, y: number): Point; + origin: Point; +}; +``` + +The context in which a class is referenced distinguishes between the class type and the constructor function. For example, in the assignment statement + +```TypeScript +var p: Point = new Point(10, 20); +``` + +the identifier 'Point' in the type annotation refers to the class type, whereas the identifier 'Point' in the `new` expression refers to the constructor function object. + +### 8.1.1 Class Heritage Specification + +*TODO: Update this section to reflect [expressions in class extends clauses](https://github.com/Microsoft/TypeScript/pull/3516)*. + +The heritage specification of a class consists of optional `extends` and `implements` clauses. The `extends` clause specifies the base class of the class and the `implements` clause specifies a set of interfaces for which to validate the class provides an implementation. + +  *ClassHeritage:* *( Modified )* +   *ClassExtendsClauseopt* *ImplementsClauseopt* + +  *ClassExtendsClause:* +   `extends`  *ClassType* + +  *ClassType:* +   *TypeReference* + +  *ImplementsClause:* +   `implements` *ClassOrInterfaceTypeList* + +A class that includes an `extends` clause is called a ***derived class***, and the class specified in the `extends` clause is called the ***base class*** of the derived class. When a class heritage specification omits the `extends` clause, the class does not have a base class. However, as is the case with every object type, type references (section [3.3.1](#3.3.1)) to the class will appear to have the members of the global interface type named 'Object' unless those members are hidden by members with the same name in the class. + +The following constraints must be satisfied by the class heritage specification or otherwise a compile-time error occurs: + +* If present, the type reference specified in the `extends` clause must denote a class type. Furthermore, the *TypeName* part of the type reference is required to be a reference to the class constructor function when evaluated as an expression. +* A class declaration may not, directly or indirectly, specify a base class that originates in the same declaration. In other words a class cannot, directly or indirectly, be a base class of itself, regardless of type arguments. +* The this-type (section [3.6.3](#3.6.3)) of the declared class must be assignable (section [3.11.4](#3.11.4)) to the base type reference and each of the type references listed in the `implements` clause. +* The constructor function type created by the class declaration must be assignable to the base class constructor function type, ignoring construct signatures. + +The following example illustrates a situation in which the first rule above would be violated: + +```TypeScript +class A { a: number; } + +namespace Foo { + var A = 1; + class B extends A { b: string; } +} +``` + +When evaluated as an expression, the type reference 'A' in the `extends` clause doesn't reference the class constructor function of 'A' (instead it references the local variable 'A'). + +The only situation in which the last two constraints above are violated is when a class overrides one or more base class members with incompatible new members. + +Note that because TypeScript has a structural type system, a class doesn't need to explicitly state that it implements an interface—it suffices for the class to simply contain the appropriate set of instance members. The `implements` clause of a class provides a mechanism to assert and validate that the class contains the appropriate sets of instance members, but otherwise it has no effect on the class type. + +### 8.1.2 Class Body + +The class body consists of zero or more constructor or member declarations. Statements are not allowed in the body of a class—they must be placed in the constructor or in members. + +  *ClassElement:* *( Modified )* +   *ConstructorDeclaration* +   *PropertyMemberDeclaration* +   *IndexMemberDeclaration* + +The body of class may optionally contain a single constructor declaration. Constructor declarations are described in section [8.3](#8.3). + +Member declarations are used to declare instance and static members of the class. Property member declarations are described in section [8.4](#8.4) and index member declarations are described in section [8.5](#8.5). + +## 8.2 Members + +The members of a class consist of the members introduced through member declarations in the class body and the members inherited from the base class. + +### 8.2.1 Instance and Static Members + +Members are either ***instance members*** or ***static members***. + +Instance members are members of the class type (section [8.2.4](#8.2.4)) and its associated this-type. Within constructors, instance member functions, and instance member accessors, the type of `this` is the this-type (section [3.6.3](#3.6.3)) of the class. + +Static members are declared using the `static` modifier and are members of the constructor function type (section [8.2.5](#8.2.5)). Within static member functions and static member accessors, the type of `this` is the constructor function type. + +Class type parameters cannot be referenced in static member declarations. + +### 8.2.2 Accessibility + +Property members have either ***public***, ***private***, or ***protected*** accessibility. The default is public accessibility, but property member declarations may include a `public`, `private`, or `protected` modifier to explicitly specify the desired accessibility. + +Public property members can be accessed everywhere without restrictions. + +Private property members can be accessed only within their declaring class. Specifically, a private member *M* declared in a class *C* can be accessed only within the class body of *C*. + +Protected property members can be accessed only within their declaring class and classes derived from their declaring class, and a protected instance property member must be accessed *through* an instance of the enclosing class or a subclass thereof. Specifically, a protected member *M* declared in a class *C* can be accessed only within the class body of *C* or the class body of a class derived from *C*. Furthermore, when a protected instance member *M* is accessed in a property access *E*`.`*M* within the body of a class *D*, the type of *E* is required to be *D* or a type that directly or indirectly has *D* as a base type, regardless of type arguments. + +Private and protected accessibility is enforced only at compile-time and serves as no more than an *indication of intent*. Since JavaScript provides no mechanism to create private and protected properties on an object, it is not possible to enforce the private and protected modifiers in dynamic code at run-time. For example, private and protected accessibility can be defeated by changing an object's static type to Any and accessing the member dynamically. + +The following example demonstrates private and protected accessibility: + +```TypeScript +class A { + private x: number; + protected y: number; + static f(a: A, b: B) { + a.x = 1; // Ok + b.x = 1; // Ok + a.y = 1; // Ok + b.y = 1; // Ok + } +} + +class B extends A { + static f(a: A, b: B) { + a.x = 1; // Error, x only accessible within A + b.x = 1; // Error, x only accessible within A + a.y = 1; // Error, y must be accessed through instance of B + b.y = 1; // Ok + } +} +``` + +In class 'A', the accesses to 'x' are permitted because 'x' is declared in 'A', and the accesses to 'y' are permitted because both take place through an instance of 'A' or a type derived from 'A'. In class 'B', access to 'x' is not permitted, and the first access to 'y' is an error because it takes place through an instance of 'A', which is not derived from the enclosing class 'B'. + +### 8.2.3 Inheritance and Overriding + +A derived class ***inherits*** all members from its base class it doesn't ***override***. Inheritance means that a derived class implicitly contains all non-overridden members of the base class. Only public and protected property members can be overridden. + +A property member in a derived class is said to override a property member in a base class when the derived class property member has the same name and kind (instance or static) as the base class property member. The type of an overriding property member must be assignable (section [3.11.4](#3.11.4)) to the type of the overridden property member, or otherwise a compile-time error occurs. + +Base class instance member functions can be overridden by derived class instance member functions, but not by other kinds of members. + +Base class instance member variables and accessors can be overridden by derived class instance member variables and accessors, but not by other kinds of members. + +Base class static property members can be overridden by derived class static property members of any kind as long as the types are compatible, as described above. + +An index member in a derived class is said to override an index member in a base class when the derived class index member is of the same index kind (string or numeric) as the base class index member. The type of an overriding index member must be assignable (section [3.11.4](#3.11.4)) to the type of the overridden index member, or otherwise a compile-time error occurs. + +### 8.2.4 Class Types + +A class declaration declares a new named type (section [3.7](#3.7)) called a class type. Within the constructor and instance member functions of a class, the type of `this` is the this-type (section [3.6.3](#3.6.3)) of that class type. The class type has the following members: + +* A property for each instance member variable declaration in the class body. +* A property of a function type for each instance member function declaration in the class body. +* A property for each uniquely named instance member accessor declaration in the class body. +* A property for each constructor parameter declared with a `public`, `private`, or `protected` modifier. +* An index signature for each instance index member declaration in the class body. +* All base class instance property or index members that are not overridden in the class. + +All instance property members (including those that are private or protected) of a class must satisfy the constraints implied by the index members of the class as specified in section [3.9.4](#3.9.4). + +In the example + +```TypeScript +class A { + public x: number; + public f() { } + public g(a: any) { return undefined; } + static s: string; +} + +class B extends A { + public y: number; + public g(b: boolean) { return false; } +} +``` + +the class type of 'A' is equivalent to + +```TypeScript +interface A { + x: number; + f: () => void; + g: (a: any) => any; +} +``` + +and the class type of 'B' is equivalent to + +```TypeScript +interface B { + x: number; + y: number; + f: () => void; + g: (b: boolean) => boolean; +} +``` + +Note that static declarations in a class do not contribute to the class type—rather, static declarations introduce properties on the constructor function object. Also note that the declaration of 'g' in 'B' overrides the member inherited from 'A'. + +### 8.2.5 Constructor Function Types + +The type of the constructor function introduced by a class declaration is called the constructor function type. The constructor function type has the following members: + +* If the class contains no constructor declaration and has no base class, a single construct signature with no parameters, having the same type parameters as the class (if any) and returning an instantiation of the class type with those type parameters passed as type arguments. +* If the class contains no constructor declaration and has a base class, a set of construct signatures with the same parameters as those of the base class constructor function type following substitution of type parameters with the type arguments specified in the base class type reference, all having the same type parameters as the class (if any) and returning an instantiation of the class type with those type parameters passed as type arguments. +* If the class contains a constructor declaration with no overloads, a construct signature with the parameter list of the constructor implementation, having the same type parameters as the class (if any) and returning an instantiation of the class type with those type parameters passed as type arguments. +* If the class contains a constructor declaration with overloads, a set of construct signatures with the parameter lists of the overloads, all having the same type parameters as the class (if any) and returning an instantiation of the class type with those type parameters passed as type arguments. +* A property for each static member variable declaration in the class body. +* A property of a function type for each static member function declaration in the class body. +* A property for each uniquely named static member accessor declaration in the class body. +* A property named 'prototype', the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. +* All base class constructor function type properties that are not overridden in the class. + +Every class automatically contains a static property member named 'prototype', the type of which is the containing class with type Any substituted for each type parameter. + +The example + +```TypeScript +class Pair { + constructor(public item1: T1, public item2: T2) { } +} + +class TwoArrays extends Pair { } +``` + +introduces two named types corresponding to + +```TypeScript +interface Pair { + item1: T1; + item2: T2; +} + +interface TwoArrays { + item1: T[]; + item2: T[]; +} +``` + +and two constructor functions corresponding to + +```TypeScript +var Pair: { + new (item1: T1, item2: T2): Pair; +} + +var TwoArrays: { + new (item1: T[], item2: T[]): TwoArrays; +} +``` + +Note that each construct signature in the constructor function types has the same type parameters as its class and returns an instantiation of its class with those type parameters passed as type arguments. Also note that when a derived class doesn't declare a constructor, type arguments from the base class reference are substituted before construct signatures are propagated from the base constructor function type to the derived constructor function type. + +## 8.3 Constructor Declarations + +A constructor declaration declares the constructor function of a class. + +  *ConstructorDeclaration:* +   *AccessibilityModifieropt* `constructor` `(` *ParameterListopt* `)` `{` *FunctionBody* `}` +   *AccessibilityModifieropt* `constructor` `(` *ParameterListopt* `)` `;` + +Constructor declarations that specify a body are called ***constructor implementations*** and constructor declarations without a body are called ***constructor overloads***. It is possible to specify multiple constructor overloads in a class, but a class can have at most one constructor implementation. All constructor declarations in a class must specify the same set of modifiers. Only public constructors are supported and private or protected constructors result in an error. + +In a class with no constructor declaration, an automatic constructor is provided, as described in section [8.3.3](#8.3.3). + +When a class has constructor overloads, the overloads determine the construct signatures of the type given to the constructor function object, and the constructor implementation signature (if any) must be assignable to that type. Otherwise, the constructor implementation itself determines the construct signature. This exactly parallels the way overloads are processed in a function declaration (section [6.2](#6.2)). + +When a class has both constructor overloads and a constructor implementation, the overloads must precede the implementation and all of the declarations must be consecutive with no intervening grammatical elements. + +The function body of a constructor is permitted to contain return statements. If return statements specify expressions, those expressions must be of types that are assignable to the this-type (section [3.6.3](#3.6.3)) of the class. + +The type parameters of a generic class are in scope and accessible in a constructor declaration. + +### 8.3.1 Constructor Parameters + +Similar to functions, only the constructor implementation (and not constructor overloads) can specify default value expressions for optional parameters. It is a compile-time error for such default value expressions to reference `this`. When the output target is ECMAScript 3 or 5, for each parameter with a default value, a statement that substitutes the default value for an omitted argument is included in the JavaScript generated for the constructor function. + +A parameter of a *ConstructorImplementation* may be prefixed with a `public`, `private`, or `protected` modifier. This is called a ***parameter property declaration*** and is shorthand for declaring a property with the same name as the parameter and initializing it with the value of the parameter. For example, the declaration + +```TypeScript +class Point { + constructor(public x: number, public y: number) { + // Constructor body + } +} +``` + +is equivalent to writing + +```TypeScript +class Point { + public x: number; + public y: number; + constructor(x: number, y: number) { + this.x = x; + this.y = y; + // Constructor body + } +} +``` + +A parameter property declaration may declare an optional parameter (by including a question mark or a default value), but the property introduced by such a declaration is always considered a required property (section [3.3.6](#3.3.6)). + +### 8.3.2 Super Calls + +Super calls (section [4.9.1](#4.9.1)) are used to call the constructor of the base class. A super call consists of the keyword `super` followed by an argument list enclosed in parentheses. For example: + +```TypeScript +class ColoredPoint extends Point { + constructor(x: number, y: number, public color: string) { + super(x, y); + } +} +``` + +Constructors of classes with no `extends` clause may not contain super calls, whereas constructors of derived classes must contain at least one super call somewhere in their function body. Super calls are not permitted outside constructors or in local functions inside constructors. + +The first statement in the body of a constructor *must* be a super call if both of the following are true: + +* The containing class is a derived class. +* The constructor declares parameter properties or the containing class declares instance member variables with initializers. + +In such a required super call, it is a compile-time error for argument expressions to reference `this`. + +Initialization of parameter properties and instance member variables with initializers takes place immediately at the beginning of the constructor body if the class has no base class, or immediately following the super call if the class is a derived class. + +### 8.3.3 Automatic Constructors + +If a class omits a constructor declaration, an ***automatic constructor*** is provided. + +In a class with no `extends` clause, the automatic constructor has no parameters and performs no action other than executing the instance member variable initializers (section [8.4.1](#8.4.1)), if any. + +In a derived class, the automatic constructor has the same parameter list (and possibly overloads) as the base class constructor. The automatically provided constructor first forwards the call to the base class constructor using a call equivalent to + +```TypeScript +BaseClass.apply(this, arguments); +``` + +and then executes the instance member variable initializers, if any. + +## 8.4 Property Member Declarations + +Property member declarations can be member variable declarations, member function declarations, or member accessor declarations. + +  *PropertyMemberDeclaration:* +   *MemberVariableDeclaration* +   *MemberFunctionDeclaration* +   *MemberAccessorDeclaration* + +Member declarations without a `static` modifier are called instance member declarations. Instance property member declarations declare properties in the class type (section [8.2.4](#8.2.4)), and must specify names that are unique among all instance property member and parameter property declarations in the containing class, with the exception that instance get and set accessor declarations may pairwise specify the same name. + +Member declarations with a `static` modifier are called static member declarations. Static property member declarations declare properties in the constructor function type (section [8.2.5](#8.2.5)), and must specify names that are unique among all static property member declarations in the containing class, with the exception that static get and set accessor declarations may pairwise specify the same name. + +Note that the declaration spaces of instance and static property members are separate. Thus, it is possible to have instance and static property members with the same name. + +Except for overrides, as described in section [8.2.3](#8.2.3), it is an error for a derived class to declare a property member with the same name and kind (instance or static) as a base class member. + +Every class automatically contains a static property member named 'prototype', the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. It is an error to explicitly declare a static property member with the name 'prototype'. + +Below is an example of a class containing both instance and static property member declarations: + +```TypeScript +class Point { + constructor(public x: number, public y: number) { } + public distance(p: Point) { + var dx = this.x - p.x; + var dy = this.y - p.y; + return Math.sqrt(dx * dx + dy * dy); + } + static origin = new Point(0, 0); + static distance(p1: Point, p2: Point) { return p1.distance(p2); } +} +``` + +The class type 'Point' has the members: + +```TypeScript +interface Point { + x: number; + y: number; + distance(p: Point); +} +``` + +and the constructor function 'Point' has a type corresponding to the declaration: + +```TypeScript +var Point: { + new(x: number, y: number): Point; + origin: Point; + distance(p1: Point, p2: Point): number; +} +``` + +### 8.4.1 Member Variable Declarations + +A member variable declaration declares an instance member variable or a static member variable. + +  *MemberVariableDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *TypeAnnotationopt* *Initializeropt* `;` + +The type associated with a member variable declaration is determined in the same manner as an ordinary variable declaration (see section [5.2](#5.2)). + +An instance member variable declaration introduces a member in the class type and optionally initializes a property on instances of the class. Initializers in instance member variable declarations are executed once for every new instance of the class and are equivalent to assignments to properties of `this` in the constructor. In an initializer expression for an instance member variable, `this` is of the this-type (section [3.6.3](#3.6.3)) of the class. + +A static member variable declaration introduces a property in the constructor function type and optionally initializes a property on the constructor function object. Initializers in static member variable declarations are executed once when the containing script or module is loaded. + +Initializer expressions for instance member variables are evaluated in the scope of the class constructor body but are not permitted to reference parameters or local variables of the constructor. This effectively means that entities from outer scopes by the same name as a constructor parameter or local variable are inaccessible in initializer expressions for instance member variables. + +Since instance member variable initializers are equivalent to assignments to properties of `this` in the constructor, the example + +```TypeScript +class Employee { + public name: string; + public address: string; + public retired = false; + public manager: Employee = null; + public reports: Employee[] = []; +} +``` + +is equivalent to + +```TypeScript +class Employee { + public name: string; + public address: string; + public retired: boolean; + public manager: Employee; + public reports: Employee[]; + constructor() { + this.retired = false; + this.manager = null; + this.reports = []; + } +} +``` + +### 8.4.2 Member Function Declarations + +A member function declaration declares an instance member function or a static member function. + +  *MemberFunctionDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *CallSignature* `{` *FunctionBody* `}` +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *CallSignature* `;` + +A member function declaration is processed in the same manner as an ordinary function declaration (section [6](#6)), except that in a member function `this` has a known type. + +All declarations for the same member function must specify the same accessibility (public, private, or protected) and kind (instance or static). + +An instance member function declaration declares a property in the class type and assigns a function object to a property on the prototype object of the class. In the body of an instance member function declaration, `this` is of the this-type (section [3.6.3](#3.6.3)) of the class. + +A static member function declaration declares a property in the constructor function type and assigns a function object to a property on the constructor function object. In the body of a static member function declaration, the type of `this` is the constructor function type. + +A member function can access overridden base class members using a super property access (section [4.9.2](#4.9.2)). For example + +```TypeScript +class Point { + constructor(public x: number, public y: number) { } + public toString() { + return "x=" + this.x + " y=" + this.y; + } +} + +class ColoredPoint extends Point { + constructor(x: number, y: number, public color: string) { + super(x, y); + } + public toString() { + return super.toString() + " color=" + this.color; + } +} +``` + +In a static member function, `this` represents the constructor function object on which the static member function was invoked. Thus, a call to 'new this()' may actually invoke a derived class constructor: + +```TypeScript +class A { + a = 1; + static create() { + return new this(); + } +} + +class B extends A { + b = 2; +} + +var x = A.create(); // new A() +var y = B.create(); // new B() +``` + +Note that TypeScript doesn't require or verify that derived constructor functions are subtypes of base constructor functions. In other words, changing the declaration of 'B' to + +```TypeScript +class B extends A { + constructor(public b: number) { + super(); + } +} +``` + +does not cause errors in the example, even though the call to the constructor from the 'create' function doesn't specify an argument (thus giving the value 'undefined' to 'b'). + +### 8.4.3 Member Accessor Declarations + +A member accessor declaration declares an instance member accessor or a static member accessor. + +  *MemberAccessorDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *GetAccessor* +   *AccessibilityModifieropt* `static`*opt* *SetAccessor* + +Get and set accessors are processed in the same manner as in an object literal (section [4.5](#4.5)), except that a contextual type is never available in a member accessor declaration. + +Accessors for the same member name must specify the same accessibility. + +An instance member accessor declaration declares a property in the class type and defines a property on the prototype object of the class with a get or set accessor. In the body of an instance member accessor declaration, `this` is of the this-type (section [3.6.3](#3.6.3)) of the class. + +A static member accessor declaration declares a property in the constructor function type and defines a property on the constructor function object of the class with a get or set accessor. In the body of a static member accessor declaration, the type of `this` is the constructor function type. + +Get and set accessors are emitted as calls to 'Object.defineProperty' in the generated JavaScript, as described in section [8.7.1](#8.7.1). + +### 8.4.4 Dynamic Property Declarations + +If the *PropertyName* of a property member declaration is a computed property name that doesn't denote a well-known symbol ([2.2.3](#2.2.3)), the construct is considered a ***dynamic property declaration***. The following rules apply to dynamic property declarations: + +* A dynamic property declaration does not introduce a property in the class type or constructor function type. +* The property name expression of a dynamic property assignment must be of type Any or the String, Number, or Symbol primitive type. +* The name associated with a dynamic property declarations is considered to be a numeric property name if the property name expression is of type Any or the Number primitive type. + +## 8.5 Index Member Declarations + +An index member declaration introduces an index signature (section [3.9.4](#3.9.4)) in the class type. + +  *IndexMemberDeclaration:* +   *IndexSignature* `;` + +Index member declarations have no body and cannot specify an accessibility modifier. + +A class declaration can have at most one string index member declaration and one numeric index member declaration. All instance property members of a class must satisfy the constraints implied by the index members of the class as specified in section [3.9.4](#3.9.4). + +It is not possible to declare index members for the static side of a class. + +Note that it is seldom meaningful to include a string index signature in a class because it constrains all instance properties of the class. However, numeric index signatures can be useful to control the element type when a class is used in an array-like manner. + +## 8.6 Decorators + +*TODO: Document [decorators](https://github.com/Microsoft/TypeScript/issues/2249)*. + +## 8.7 Code Generation + +When the output target is ECMAScript 2015 or higher, type parameters, implements clauses, accessibility modifiers, and member variable declarations are removed in the emitted code, but otherwise class declarations are emitted as written. When the output target is ECMAScript 3 or 5, more comprehensive rewrites are performed, as described in this section. + +### 8.7.1 Classes Without Extends Clauses + +A class with no `extends` clause generates JavaScript equivalent to the following: + +```TypeScript +var = (function () { + function () { + + + + + } + + + return ; +})(); +``` + +*ClassName* is the name of the class. + +*ConstructorParameters* is a comma separated list of the constructor's parameter names. + +*DefaultValueAssignments* is a sequence of default property value assignments corresponding to those generated for a regular function declaration, as described in section [6.6](#6.6). + +*ParameterPropertyAssignments* is a sequence of assignments, one for each parameter property declaration in the constructor, in order they are declared, of the form + +```TypeScript +this. = ; +``` + +where *ParameterName* is the name of a parameter property. + +*MemberVariableAssignments* is a sequence of assignments, one for each instance member variable declaration with an initializer, in the order they are declared, of the form + +```TypeScript +this. = ; +``` + +where *MemberName* is the name of the member variable and *InitializerExpression* is the code generated for the initializer expression. + +*ConstructorStatements* is the code generated for the statements specified in the constructor body. + +*MemberFunctionStatements* is a sequence of statements, one for each member function declaration or member accessor declaration, in the order they are declared. + +An instance member function declaration generates a statement of the form + +```TypeScript +.prototype. = function () { + + +} +``` + +and static member function declaration generates a statement of the form + +```TypeScript +. = function () { + + +} +``` + +where *MemberName* is the name of the member function, and *FunctionParameters*, *DefaultValueAssignments*, and *FunctionStatements* correspond to those generated for a regular function declaration, as described in section [6.6](#6.6). + +A get or set instance member accessor declaration, or a pair of get and set instance member accessor declarations with the same name, generates a statement of the form + +```TypeScript +Object.defineProperty(.prototype, "", { + get: function () { + + }, + set: function () { + + }, + enumerable: true, + configurable: true +}; +``` + +and a get or set static member accessor declaration, or a pair of get and set static member accessor declarations with the same name, generates a statement of the form + +```TypeScript +Object.defineProperty(, "", { + get: function () { + + }, + set: function () { + + }, + enumerable: true, + configurable: true +}; +``` + +where *MemberName* is the name of the member accessor, *GetAccessorStatements* is the code generated for the statements in the get acessor's function body, *ParameterName* is the name of the set accessor parameter, and *SetAccessorStatements* is the code generated for the statements in the set accessor's function body. The 'get' property is included only if a get accessor is declared and the 'set' property is included only if a set accessor is declared. + +*StaticVariableAssignments* is a sequence of statements, one for each static member variable declaration with an initializer, in the order they are declared, of the form + +```TypeScript +. = ; +``` + +where *MemberName* is the name of the static variable, and *InitializerExpression* is the code generated for the initializer expression. + +### 8.7.2 Classes With Extends Clauses + +A class with an `extends` clause generates JavaScript equivalent to the following: + +```TypeScript +var = (function (_super) { + __extends(, _super); + function () { + + + + + + } + + + return ; +})(); +``` + +In addition, the '__extends' function below is emitted at the beginning of the JavaScript source file. It copies all properties from the base constructor function object to the derived constructor function object (in order to inherit static members), and appropriately establishes the 'prototype' property of the derived constructor function object. + +```TypeScript +var __extends = this.__extends || function(d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function f() { this.constructor = d; } + f.prototype = b.prototype; + d.prototype = new f(); +} +``` + +*BaseClassName* is the class name specified in the `extends` clause. + +If the class has no explicitly declared constructor, the *SuperCallStatement* takes the form + +```TypeScript +_super.apply(this, arguments); +``` + +Otherwise the *SuperCallStatement* is present if the constructor function is required to start with a super call, as discussed in section [8.3.2](#8.3.2), and takes the form + +```TypeScript +_super.call(this, ) +``` + +where *SuperCallArguments* is the argument list specified in the super call. Note that this call precedes the code generated for parameter properties and member variables with initializers. Super calls elsewhere in the constructor generate similar code, but the code generated for such calls will be part of the *ConstructorStatements* section. + +A super property access in the constructor, an instance member function, or an instance member accessor generates JavaScript equivalent to + +```TypeScript +_super.prototype. +``` + +where *PropertyName* is the name of the referenced base class property. When the super property access appears in a function call, the generated JavaScript is equivalent to + +```TypeScript +_super.prototype..call(this, ) +``` + +where Arguments is the code generated for the argument list specified in the function call. + +A super property access in a static member function or a static member accessor generates JavaScript equivalent to + +```TypeScript +_super. +``` + +where *PropertyName* is the name of the referenced base class property. When the super property access appears in a function call, the generated JavaScript is equivalent to + +```TypeScript +_super..call(this, ) +``` + +where Arguments is the code generated for the argument list specified in the function call. + +
+ +#
9 Enums + +An enum type is a distinct subtype of the Number primitive type with an associated set of named constants that define the possible values of the enum type. + +## 9.1 Enum Declarations + +An enum declaration declares an ***enum type*** and an ***enum object***. + +  *EnumDeclaration:* +   `const`*opt* `enum` *BindingIdentifier* `{` *EnumBodyopt* `}` + +An *EnumDeclaration* introduces a named type (the enum type) and a named value (the enum object) in the containing declaration space. The enum type is a distinct subtype of the Number primitive type. The enum object is a value of an anonymous object type containing a set of properties, all of the enum type, corresponding to the values declared for the enum type in the body of the declaration. The enum object's type furthermore includes a numeric index signature with the signature '[x: number]: string'. + +The *BindingIdentifier* of an enum declaration may not be one of the predefined type names (section [3.8.1](#3.8.1)). + +When an enum declaration includes a `const` modifier it is said to be a constant enum declaration. The members of a constant enum declaration must all have constant values that can be computed at compile time. Constant enum declarations are discussed in section [9.4](#9.4). + +The example + +```TypeScript +enum Color { Red, Green, Blue } +``` + +declares a subtype of the Number primitive type called 'Color' and introduces a variable 'Color' with a type that corresponds to the declaration + +```TypeScript +var Color: { + [x: number]: string; + Red: Color; + Green: Color; + Blue: Color; +}; +``` + +The numeric index signature reflects a "reverse mapping" that is automatically generated in every enum object, as described in section [9.5](#9.5). The reverse mapping provides a convenient way to obtain the string representation of an enum value. For example + +```TypeScript +var c = Color.Red; +console.log(Color[c]); // Outputs "Red" +``` + +## 9.2 Enum Members + +The body of an enum declaration defines zero or more enum members which are the named values of the enum type. Each enum member has an associated numeric value of the primitive type introduced by the enum declaration. + +  *EnumBody:* +   *EnumMemberList* `,`*opt* + +  *EnumMemberList:* +   *EnumMember* +   *EnumMemberList* `,` *EnumMember* + +  *EnumMember:* +   *PropertyName* +   *PropertyName* = *EnumValue* + +  *EnumValue:* +   *AssignmentExpression* + +The *PropertyName* of an enum member cannot be a computed property name ([2.2.3](#2.2.3)). + +Enum members are either ***constant members*** or ***computed members***. Constant members have known constant values that are substituted in place of references to the members in the generated JavaScript code. Computed members have values that are computed at run-time and not known at compile-time. No substitution is performed for references to computed members. + +An enum member is classified as follows: + +* If the member declaration specifies no value, the member is considered a constant enum member. If the member is the first member in the enum declaration, it is assigned the value zero. Otherwise, it is assigned the value of the immediately preceding member plus one, and an error occurs if the immediately preceding member is not a constant enum member. +* If the member declaration specifies a value that can be classified as a constant enum expression (as defined below), the member is considered a constant enum member. +* Otherwise, the member is considered a computed enum member. + +Enum value expressions must be of type Any, the Number primitive type, or the enum type itself. + +A ***constant enum expression*** is a subset of the expression grammar that can be evaluated fully at compile time. An expression is considered a constant enum expression if it is one of the following: + +* A numeric literal. +* An identifier or property access that denotes a previously declared member in the same constant enum declaration. +* A parenthesized constant enum expression. +* A +, –, or ~ unary operator applied to a constant enum expression. +* A +, –, *, /, %, <<, >>, >>>, &, ^, or | operator applied to two constant enum expressions. + +In the example + +```TypeScript +enum Test { + A, + B, + C = Math.floor(Math.random() * 1000), + D = 10, + E +} +``` + +'A', 'B', 'D', and 'E' are constant members with values 0, 1, 10, and 11 respectively, and 'C' is a computed member. + +In the example + +```TypeScript +enum Style { + None = 0, + Bold = 1, + Italic = 2, + Underline = 4, + Emphasis = Bold | Italic, + Hyperlink = Bold | Underline +} +``` + +all members are constant members. Note that enum member declarations can reference other enum members without qualification. Also, because enums are subtypes of the Number primitive type, numeric operators, such as the bitwise OR operator, can be used to compute enum values. + +## 9.3 Declaration Merging + +Enums are "open-ended" and enum declarations with the same qualified name relative to a common root (as defined in section [2.3](#2.3)) define a single enum type and contribute to a single enum object. + +It isn't possible for one enum declaration to continue the automatic numbering sequence of another, and when an enum type has multiple declarations, only one declaration is permitted to omit a value for the first member. + +When enum declarations are merged, they must either all specify a `const` modifier or all specify no `const` modifier. + +## 9.4 Constant Enum Declarations + +An enum declaration that specifies a `const` modifier is a ***constant enum declaration***. In a constant enum declaration, all members must have constant values and it is an error for a member declaration to specify an expression that isn't classified as a constant enum expression. + +Unlike regular enum declarations, constant enum declarations are completely erased in the emitted JavaScript code. For this reason, it is an error to reference a constant enum object in any other context than a property access that selects one of the enum's members. For example: + +```TypeScript +const enum Comparison { + LessThan = -1, + EqualTo = 0, + GreaterThan = 1 +} + +var x = Comparison.EqualTo; // Ok, replaced with 0 in emitted code +var y = Comparison[Comparison.EqualTo]; // Error +var z = Comparison; // Error +``` + +The entire const enum declaration is erased in the emitted JavaScript code. Thus, the only permitted references to the enum object are those that are replaced with an enum member value. + +## 9.5 Code Generation + +An enum declaration generates JavaScript equivalent to the following: + +```TypeScript +var ; +(function () { + +})(||(={})); +``` + +*EnumName* is the name of the enum. + +*EnumMemberAssignments* is a sequence of assignments, one for each enum member, in order they are declared, of the form + +```TypeScript +[[""] = ] = ""; +``` + +where *MemberName* is the name of the enum member and *Value* is the assigned constant value or the code generated for the computed value expression. + +For example, the 'Color' enum example from section [9.1](#9.1) generates the following JavaScript: + +```TypeScript +var Color; +(function (Color) { + Color[Color["Red"] = 0] = "Red"; + Color[Color["Green"] = 1] = "Green"; + Color[Color["Blue"] = 2] = "Blue"; +})(Color||(Color={})); +``` + +
+ +#
10 Namespaces + +Namespaces provide a mechanism for organizing code and declarations in hierarchies of named containers. Namespaces have named members that each denote a value, a type, or a namespace, or some combination thereof, and those members may be local or exported. The body of a namespace corresponds to a function that is executed once, thereby providing a mechanism for maintaining local state with assured isolation. Namespaces can be thought of as a formalization of the [immediately-invoked function expression](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression) (IIFE) pattern. + +## 10.1 Namespace Declarations + +A namespace declaration introduces a name with a namespace meaning and, in the case of an instantiated namespace, a value meaning in the containing declaration space. + +  *NamespaceDeclaration:* +   `namespace` *IdentifierPath* `{` *NamespaceBody* `}` + +  *IdentifierPath:* +   *BindingIdentifier* +   *IdentifierPath* `.` *BindingIdentifier* + +Namespaces are declared using the `namespace` keyword, but for backward compatibility of earlier versions of TypeScript a `module` keyword can also be used. + +Namespaces are either ***instantiated*** or ***non-instantiated***. A non-instantiated namespace is a namespace containing only interface types, type aliases, and other non-instantiated namespace. An instantiated namespace is a namespace that doesn't meet this definition. In intuitive terms, an instantiated namespace is one for which a namespace instance is created, whereas a non-instantiated namespace is one for which no code is generated. + +When a namespace identifier is referenced as a *NamespaceName* (section [3.8.2](#3.8.2)) it denotes a container of namespace and type names, and when a namespace identifier is referenced as a *PrimaryExpression* (section [4.3](#4.3)) it denotes the singleton namespace instance. For example: + +```TypeScript +namespace M { + export interface P { x: number; y: number; } + export var a = 1; +} + +var p: M.P; // M used as NamespaceName +var m = M; // M used as PrimaryExpression +var x1 = M.a; // M used as PrimaryExpression +var x2 = m.a; // Same as M.a +var q: m.P; // Error +``` + +Above, when 'M' is used as a *PrimaryExpression* it denotes an object instance with a single member 'a' and when 'M' is used as a *NamespaceName* it denotes a container with a single type member 'P'. The final line in the example is an error because 'm' is a variable which cannot be referenced in a type name. + +If the declaration of 'M' above had excluded the exported variable 'a', 'M' would be a non-instantiated namespace and it would be an error to reference 'M' as a *PrimaryExpression*. + +A namespace declaration that specifies an *IdentifierPath* with more than one identifier is equivalent to a series of nested single-identifier namespace declarations where all but the outermost are automatically exported. For example: + +```TypeScript +namespace A.B.C { + export var x = 1; +} +``` + +corresponds to + +```TypeScript +namespace A { + export namespace B { + export namespace C { + export var x = 1; + } + } +} +``` + +The hierarchy formed by namespace and named type names partially mirrors that formed by namespace instances and members. The example + +```TypeScript +namespace A { + export namespace B { + export class C { } + } +} +``` + +introduces a named type with the qualified name 'A.B.C' and also introduces a constructor function that can be accessed using the expression 'A.B.C'. Thus, in the example + +```TypeScript +var c: A.B.C = new A.B.C(); +``` + +the two occurrences of 'A.B.C' in fact refer to different entities. It is the context of the occurrences that determines whether 'A.B.C' is processed as a type name or an expression. + +## 10.2 Namespace Body + +The body of a namespace corresponds to a function that is executed once to initialize the namespace instance. + +  *NamespaceBody:* +   *NamespaceElementsopt* + +  *NamespaceElements:* +   *NamespaceElement* +   *NamespaceElements* *NamespaceElement* + +  *NamespaceElement:* +   *Statement* +   *LexicalDeclaration* +   *FunctionDeclaration* +   *GeneratorDeclaration* +   *ClassDeclaration* +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *EnumDeclaration* +   *NamespaceDeclaration +   AmbientDeclaration +   ImportAliasDeclaration +   ExportNamespaceElement* + +  *ExportNamespaceElement:* +   `export` *VariableStatement* +   `export` *LexicalDeclaration* +   `export` *FunctionDeclaration* +   `export` *GeneratorDeclaration* +   `export` *ClassDeclaration* +   `export` *InterfaceDeclaration* +   `export` *TypeAliasDeclaration* +   `export` *EnumDeclaration* +   `export` *NamespaceDeclaration* +   `export` *AmbientDeclaration* +   `export` *ImportAliasDeclaration* + +## 10.3 Import Alias Declarations + +Import alias declarations are used to create local aliases for entities in other namespaces. + +  *ImportAliasDeclaration:* +   `import` *BindingIdentifier* `=` *EntityName* `;` + +  *EntityName:* +   *NamespaceName* +   *NamespaceName* `.` *IdentifierReference* + +An *EntityName* consisting of a single identifier is resolved as a *NamespaceName* and is thus required to reference a namespace. The resulting local alias references the given namespace and is itself classified as a namespace. + +An *EntityName* consisting of more than one identifier is resolved as a *NamespaceName* followed by an identifier that names an exported entity in the given namespace. The resulting local alias has all the meanings of the referenced entity. (As many as three distinct meanings are possible for an entity name—value, type, and namespace.) In effect, it is as if the imported entity was declared locally with the local alias name. + +In the example + +```TypeScript +namespace A { + export interface X { s: string } + export var X: X; +} + +namespace B { + interface A { n: number } + import Y = A; // Alias for namespace A + import Z = A.X; // Alias for type and value A.X + var v: Z = Z; +} +``` + +within 'B', 'Y' is an alias only for namespace 'A' and not the local interface 'A', whereas 'Z' is an alias for all exported meanings of 'A.X', thus denoting both an interface type and a variable. + +If the *NamespaceName* portion of an *EntityName* references an instantiated namespace, the *NamespaceName* is required to reference the namespace instance when evaluated as an expression. In the example + +```TypeScript +namespace A { + export interface X { s: string } +} + +namespace B { + var A = 1; + import Y = A; +} +``` + +'Y' is a local alias for the non-instantiated namespace 'A'. If the declaration of 'A' is changed such that 'A' becomes an instantiated namespace, for example by including a variable declaration in 'A', the import statement in 'B' above would be an error because the expression 'A' doesn't reference the namespace instance of namespace 'A'. + +When an import statement includes an export modifier, all meanings of the local alias are exported. + +## 10.4 Export Declarations + +An export declaration declares an externally accessible namespace member. An export declaration is simply a regular declaration prefixed with the keyword `export`. + +The members of a namespace's export declaration space (section [2.3](#2.3)) constitute the namespace's ***export member set***. A namespace's ***instance type*** is an object type with a property for each member in the namespace's export member set that denotes a value. + +An exported member depends on a (possibly empty) set of named types (section [3.7](#3.7)). Those named types must be at least as accessible as the exported member, or otherwise an error occurs. + +The named types upon which a member depends are the named types occurring in the transitive closure of the ***directly depends on*** relationship defined as follows: + +* A variable directly depends on the *Type* specified in its type annotation. +* A function directly depends on each *Type* specified in a parameter or return type annotation. +* A class directly depends on each *Type* specified as a type parameter constraint, each *TypeReference* specified as a base class or implemented interface, and each *Type* specified in a constructor parameter type annotation, public member variable type annotation, public member function parameter or return type annotation, public member accessor parameter or return type annotation, or index signature type annotation. +* An interface directly depends on each *Type* specified as a type parameter constraint, each *TypeReference* specified as a base interface, and the *ObjectType* specified as its body. +* A namespace directly depends on its exported members. +* A *Type* or *ObjectType* directly depends on every *TypeReference* that occurs within the type at any level of nesting. +* A *TypeReference* directly depends on the type it references and on each *Type* specified as a type argument. + +A named type *T* having a root namespace *R* (section [2.3](#2.3)) is said to be ***at least as accessible as*** a member *M* if + +* *R* is the global namespace or a module, or +* *R* is a namespace in the parent namespace chain of *M*. + +In the example + +```TypeScript +interface A { x: string; } + +namespace M { + export interface B { x: A; } + export interface C { x: B; } + export function foo(c: C) { … } +} +``` + +the 'foo' function depends upon the named types 'A', 'B', and 'C'. In order to export 'foo' it is necessary to also export 'B' and 'C' as they otherwise would not be at least as accessible as 'foo'. The 'A' interface is already at least as accessible as 'foo' because I t is declared in a parent namespace of foo's namespace. + +## 10.5 Declaration Merging + +Namespaces are "open-ended" and namespace declarations with the same qualified name relative to a common root (as defined in section [2.3](#2.3)) contribute to a single namespace. For example, the following two declarations of a namespace 'outer' might be located in separate source files. + +File a.ts: + +```TypeScript +namespace outer { + var local = 1; // Non-exported local variable + export var a = local; // outer.a + export namespace inner { + export var x = 10; // outer.inner.x + } +} +``` + +File b.ts: + +```TypeScript +namespace outer { + var local = 2; // Non-exported local variable + export var b = local; // outer.b + export namespace inner { + export var y = 20; // outer.inner.y + } +} +``` + +Assuming the two source files are part of the same program, the two declarations will have the global namespace as their common root and will therefore contribute to the same namespace instance, the instance type of which will be: + +```TypeScript +{ + a: number; + b: number; + inner: { + x: number; + y: number; + }; +} +``` + +Declaration merging does not apply to local aliases created by import alias declarations. In other words, it is not possible have an import alias declaration and a namespace declaration for the same name within the same namespace body. + +*TODO: Clarify rules for [alias resolution](https://github.com/Microsoft/TypeScript/issues/3158)*. + +Declaration merging also extends to namespace declarations with the same qualified name relative to a common root as a function, class, or enum declaration: + +* When merging a function and a namespace, the type of the function object is merged with the instance type of the namespace. In effect, the overloads or implementation of the function provide the call signatures and the exported members of the namespace provide the properties of the combined type. +* When merging a class and a namespace, the type of the constructor function object is merged with the instance type of the namespace. In effect, the overloads or implementation of the class constructor provide the construct signatures, and the static members of the class and exported members of the namespace provide the properties of the combined type. It is an error to have static class members and exported namespace members with the same name. +* When merging an enum and a namespace, the type of the enum object is merged with the instance type of the namespace. In effect, the members of the enum and the exported members of the namespace provide the properties of the combined type. It is an error to have enum members and exported namespace members with the same name. + +When merging a non-ambient function or class declaration and a non-ambient namespace declaration, the function or class declaration must be located prior to the namespace declaration in the same source file. This ensures that the shared object instance is created as a function object. (While it is possible to add properties to an object after its creation, it is not possible to make an object "callable" after the fact.) + +The example + +```TypeScript +interface Point { + x: number; + y: number; +} + +function point(x: number, y: number): Point { + return { x: x, y: y }; +} + +namespace point { + export var origin = point(0, 0); + export function equals(p1: Point, p2: Point) { + return p1.x == p2.x && p1.y == p2.y; + } +} + +var p1 = point(0, 0); +var p2 = point.origin; +var b = point.equals(p1, p2); +``` + +declares 'point' as a function object with two properties, 'origin' and 'equals'. Note that the namespace declaration for 'point' is located after the function declaration. + +## 10.6 Code Generation + +A namespace generates JavaScript code that is equivalent to the following: + +```TypeScript +var ; +(function() { + +})(||(={})); +``` + +where *NamespaceName* is the name of the namespace and *NamespaceStatements* is the code generated for the statements in the namespace body. The *NamespaceName* function parameter may be prefixed with one or more underscore characters to ensure the name is unique within the function body. Note that the entire namespace is emitted as an anonymous function that is immediately executed. This ensures that local variables are in their own lexical environment isolated from the surrounding context. Also note that the generated function doesn't create and return a namespace instance, but rather it extends the existing instance (which may have just been created in the function call). This ensures that namespaces can extend each other. + +An import statement generates code of the form + +```TypeScript +var = ; +``` + +This code is emitted only if the imported entity is referenced as a *PrimaryExpression* somewhere in the body of the importing namespace. If an imported entity is referenced only as a *TypeName* or *NamespaceName*, nothing is emitted. This ensures that types declared in one namespace can be referenced through an import alias in another namespace with no run-time overhead. + +When a variable is exported, all references to the variable in the body of the namespace are replaced with + +```TypeScript +. +``` + +This effectively promotes the variable to be a property on the namespace instance and ensures that all references to the variable become references to the property. + +When a function, class, enum, or namespace is exported, the code generated for the entity is followed by an assignment statement of the form + +```TypeScript +. = ; +``` + +This copies a reference to the entity into a property on the namespace instance. + +
+ +#
11 Scripts and Modules + +TypeScript implements support for ECMAScript 2015 modules and supports down-level code generation targeting CommonJS, AMD, and other module systems. + +## 11.1 Programs and Source Files + +A TypeScript ***program*** consists of one or more source files. + +  *SourceFile:* +   *ImplementationSourceFile* +   *DeclarationSourceFile* + +  *ImplementationSourceFile:* +   *ImplementationScript* +   *ImplementationModule* + +  *DeclarationSourceFile:* +   *DeclarationScript* +   *DeclarationModule* + +Source files with extension '.ts' are ***implementation source files*** containing statements and declarations, and source files with extension '.d.ts' are ***declaration source files*** containing declarations only. + +Declaration source files are a strict subset of implementation source files and are used to declare the static type information associated with existing JavaScript code in an adjunct manner. They are entirely optional but enable the TypeScript compiler and tools to provide better verification and assistance when integrating existing JavaScript code and libraries in a TypeScript application. + +When a TypeScript program is compiled, all of the program's source files are processed together. Statements and declarations in different source files can depend on each other, possibly in a circular fashion. By default, a JavaScript output file is generated for each implementation source file in a compilation, but no output is generated from declaration source files. + +### 11.1.1 Source Files Dependencies + +The TypeScript compiler automatically determines a source file's dependencies and includes those dependencies in the program being compiled. The determination is made from "reference comments" and module import declarations as follows: + +* A comment of the form /// <reference path="…"/> that occurs before the first token in a source file adds a dependency on the source file specified in the path argument. The path is resolved relative to the directory of the containing source file. +* A module import declaration that specifies a relative module name (section [11.3.1](#11.3.1)) resolves the name relative to the directory of the containing source file. If a source file with the resulting path and file extension '.ts' exists, that file is added as a dependency. Otherwise, if a source file with the resulting path and file extension '.d.ts' exists, that file is added as a dependency. +* A module import declaration that specifies a top-level module name (section [11.3.1](#11.3.1)) resolves the name in a host dependent manner (typically by resolving the name relative to a module name space root or searching for the name in a series of directories). If a source file with extension '.ts' or '.d.ts' corresponding to the reference is located, that file is added as a dependency. + +Any files included as dependencies in turn have their references analyzed in a transitive manner until all dependencies have been determined. + +## 11.2 Scripts + +Source files that contain no module import or export declarations are classified as ***scripts***. Scripts form the single ***global namespace*** and entities declared in scripts are in scope everywhere in a program. + +  *ImplementationScript:* +   *ImplementationScriptElementsopt* + +  *ImplementationScriptElements:* +   *ImplementationScriptElement* +   *ImplementationScriptElements* *ImplementationScriptElement* + +  *ImplementationScriptElement:* +   *ImplementationElement* +   *AmbientModuleDeclaration* + +  *ImplementationElement:* +   *Statement* +   *LexicalDeclaration* +   *FunctionDeclaration* +   *GeneratorDeclaration* +   *ClassDeclaration* +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *EnumDeclaration* +   *NamespaceDeclaration* +   *AmbientDeclaration* +   *ImportAliasDeclaration* + +  *DeclarationScript:* +   *DeclarationScriptElementsopt* + +  *DeclarationScriptElements:* +   *DeclarationScriptElement* +   *DeclarationScriptElements* *DeclarationScriptElement* + +  *DeclarationScriptElement:* +   *DeclarationElement* +   *AmbientModuleDeclaration* + +  *DeclarationElement:* +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *NamespaceDeclaration* +   *AmbientDeclaration* +   *ImportAliasDeclaration* + +The initialization order of the scripts that make up the global namespace ultimately depends on the order in which the generated JavaScript files are loaded at run-time (which, for example, may be controlled by <script/> tags that reference the generated JavaScript files). + +## 11.3 Modules + +Source files that contain at least one module import or export declaration are considered separate ***modules***. Non-exported entities declared in a module are in scope only in that module, but exported entities can be imported into other modules using import declarations. + +  *ImplementationModule:* +   *ImplementationModuleElementsopt* + +  *ImplementationModuleElements:* +   *ImplementationModuleElement* +   *ImplementationModuleElements* *ImplementationModuleElement* + +  *ImplementationModuleElement:* +   *ImplementationElement* +   *ImportDeclaration* +   *ImportAliasDeclaration* +   *ImportRequireDeclaration* +   *ExportImplementationElement* +   *ExportDefaultImplementationElement* +   *ExportListDeclaration* +   *ExportAssignment* + +  *DeclarationModule:* +   *DeclarationModuleElementsopt* + +  *DeclarationModuleElements:* +   *DeclarationModuleElement* +   *DeclarationModuleElements* *DeclarationModuleElement* + +  *DeclarationModuleElement:* +   *DeclarationElement* +   *ImportDeclaration* +   *ImportAliasDeclaration* +   *ExportDeclarationElement* +   *ExportDefaultDeclarationElement* +   *ExportListDeclaration* +   *ExportAssignment* + +Initialization order of modules is determined by the module loader being used and is not specified by the TypeScript language. However, it is generally the case that non-circularly dependent modules are automatically loaded and initialized in the correct order. + +Modules can additionally be declared using *AmbientModuleDeclarations* in declaration scripts that directly specify the module names as string literals. This is described further in section [12.2](#12.2). + +Below is an example of two modules written in separate source files: + +```TypeScript +// -------- main.ts -------- +import { message } from "./log"; +message("hello"); + +// -------- log.ts -------- +export function message(s: string) { + console.log(s); +} +``` + +The import declaration in the 'main' module references the 'log' module and compiling the 'main.ts' file causes the 'log.ts' file to also be compiled as part of the program. + +TypeScript supports multiple patterns of JavaScript code generation for modules: + +* CommonJS. This format is used by server frameworks such as node.js. +* AMD (Asynchronous Module Definition). This format is used by asynchronous module loaders such as RequireJS. +* UMD (Universal Module Definition). A variation of the AMD format that allows modules to also be loaded by CommonJS loaders. +* System. This format is used to represent ECMAScript 2015 semantics with high fidelity in down-level environments. + +The desired module code generation pattern is selected through a compiler option and does not affect the TypeScript source code. Indeed, it is possible to author modules that can be compiled for use both on the server side (e.g. using node.js) and on the client side (using an AMD compliant loader) with no changes to the TypeScript source code. + +### 11.3.1 Module Names + +Modules are identified and referenced using module names. The following definition is aligned with that provided in the [CommonJS Modules](http://www.commonjs.org/specs/modules/1.0/) 1.0 specification. + +* A module name is a string of terms delimited by forward slashes. +* Module names may not have file-name extensions like ".js". +* Module names may be relative or top-level. A module name is relative if the first term is "." or "..". +* Top-level names are resolved off the conceptual module name space root. +* Relative names are resolved relative to the name of the module in which they occur. + +For purposes of resolving module references, TypeScript associates a file path with every module. The file path is simply the path of the module's source file without the file extension. For example, a module contained in the source file 'C:\src\lib\io.ts' has the file path 'C:/src/lib/io' and a module contained in the source file 'C:\src\ui\editor.d.ts' has the file path 'C:/src/ui/editor'. + +A module name in an import declaration is resolved as follows: + +* If the import declaration specifies a relative module name, the name is resolved relative to the directory of the referencing module's file path. The program must contain a module with the resulting file path or otherwise an error occurs. For example, in a module with the file path 'C:/src/ui/main', the module names './editor' and '../lib/io' reference modules with the file paths 'C:/src/ui/editor' and 'C:/src/lib/io'. +* If the import declaration specifies a top-level module name and the program contains an *AmbientModuleDeclaration* (section [12.2](#12.2)) with a string literal that specifies that exact name, then the import declaration references that ambient module. +* If the import declaration specifies a top-level module name and the program contains no *AmbientModuleDeclaration* (section [12.2](#12.2)) with a string literal that specifies that exact name, the name is resolved in a host dependent manner (for example by considering the name relative to a module name space root). If a matching module cannot be found an error occurs. + +### 11.3.2 Import Declarations + +Import declarations are used to import entities from other modules and provide bindings for them in the current module. + +An import declaration of the form + +```TypeScript +import * as m from "mod"; +``` + +imports the module with the given name and creates a local binding for the module itself. The local binding is classified as a value (representing the module instance) and a namespace (representing a container of types and namespaces). + +An import declaration of the form + +```TypeScript +import { x, y, z } from "mod"; +``` + +imports a given module and creates local bindings for a specified list of exported members of the module. The specified names must each reference an entity in the export member set ([11.3.4.4](#11.3.4.4)) of the given module. The local bindings have the same names and classifications as the entities they represent unless `as` clauses are used to that specify different local names: + +```TypeScript +import { x as a, y as b } from "mod"; +``` + +An import declaration of the form + +```TypeScript +import d from "mod"; +``` + +is exactly equivalent to the import declaration + +```TypeScript +import { default as d } from "mod"; +``` + +An import declaration of the form + +```TypeScript +import "mod"; +``` + +imports the given module without creating any local bindings (this is useful only if the imported module has side effects). + +### 11.3.3 Import Require Declarations + +Import require declarations exist for backward compatibility with earlier versions of TypeScript. + +  *ImportRequireDeclaration:* +   `import` *BindingIdentifier* `=` `require` `(` *StringLiteral* `)` `;` + +An import require declaration introduces a local identifier that references a given module. The string literal specified in an import require declaration is interpreted as a module name (section [11.3.1](#11.3.1)). The local identifier introduced by the declaration becomes an alias for, and is classified exactly like, the entity exported from the referenced module. Specifically, if the referenced module contains no export assignment the identifier is classified as a value and a namespace, and if the referenced module contains an export assignment the identifier is classified exactly like the entity named in the export assignment. + +An import require declaration of the form + +```TypeScript +import m = require("mod"); +``` + +is equivalent to the ECMAScript 2015 import declaration + +```TypeScript +import * as m from "mod"; +``` + +provided the referenced module contains no export assignment. + +### 11.3.4 Export Declarations + +An export declaration declares one or more exported module members. The exported members of a module can be imported in other modules using import declarations ([11.3.2](#11.3.2)). + +#### 11.3.4.1 Export Modifiers + +In the body of a module, a declaration can export the declared entity by including an `export` modifier. + +  *ExportImplementationElement:* +   `export` *VariableStatement* +   `export` *LexicalDeclaration* +   `export` *FunctionDeclaration* +   `export` *GeneratorDeclaration* +   `export` *ClassDeclaration* +   `export` *InterfaceDeclaration* +   `export` *TypeAliasDeclaration* +   `export` *EnumDeclaration* +   `export` *NamespaceDeclaration* +   `export` *AmbientDeclaration* +   `export` *ImportAliasDeclaration* + +  *ExportDeclarationElement:* +   `export` *InterfaceDeclaration* +   `export` *TypeAliasDeclaration* +   `export` *AmbientDeclaration* +   `export` *ImportAliasDeclaration* + +In addition to introducing a name in the local declaration space of the module, an exported declaration introduces the same name with the same classification in the module's export declaration space. For example, the declaration + +```TypeScript +export function point(x: number, y: number) { + return { x, y }; +} +``` + +introduces a local name `point` and an exported name `point` that both reference the function. + +#### 11.3.4.2 Export Default Declarations + +Export default declarations provide short-hand syntax for exporting an entity named `default`. + +  *ExportDefaultImplementationElement:* +   `export` `default` *FunctionDeclaration* +   `export` `default` *GeneratorDeclaration* +   `export` `default` *ClassDeclaration* +   `export` `default` *AssignmentExpression* `;` + +  *ExportDefaultDeclarationElement:* +   `export` `default` *AmbientFunctionDeclaration* +   `export` `default` *AmbientClassDeclaration* +   `export` `default` *IdentifierReference* `;` + +An *ExportDefaultImplementationElement* or *ExportDefaultDeclarationElement* for a function, generator, or class introduces a value named `default`, and in the case of a class, a type named `default`, in the containing module's export declaration space. The declaration may optionally specify a local name for the exported function, generator, or class. For example, the declaration + +```TypeScript +export default function point(x: number, y: number) { + return { x, y }; +} +``` + +introduces a local name `point` and an exported name `default` that both reference the function. The declaration is effectively equivalent to + +```TypeScript +function point(x: number, y: number) { + return { x, y }; +} + +export default point; +``` + +which again is equivalent to + +```TypeScript +function point(x: number, y: number) { + return { x, y }; +} + +export { point as default }; +``` + +An *ExportDefaultImplementationElement* or *ExportDefaultDeclarationElement* for an expression consisting of a single identifier must name an entity declared in the current module or the global namespace. The declaration introduces an entity named `default`, with the same classification as the referenced entity, in the containing module's export declaration space. For example, the declarations + +```TypeScript +interface Point { + x: number; + y: number; +} + +function Point(x: number, y: number): Point { + return { x, y }; +} + +export default Point; +``` + +introduce a local name `Point` and an exported name `default`, both with a value and a type meaning. + +An *ExportDefaultImplementationElement* for any expression but a single identifier introduces a value named `default` in the containing module's export declaration space. For example, the declaration + +```TypeScript +export default "hello"; +``` + +introduces an exported value named `default` of type string. + +#### 11.3.4.3 Export List Declarations + +An export list declaration exports one or more entities from the current module or a specified module. + +  *ExportListDeclaration:* +   `export` `*` *FromClause* `;` +   `export` *ExportClause* *FromClause* `;` +   `export` *ExportClause* `;` + +An *ExportListDeclaration* without a *FromClause* exports entities from the current module. In a declaration of the form + +```TypeScript +export { x }; +``` + +the name `x` must reference an entity declared in the current module or the global namespace, and the declaration introduces an entity with the same name and meaning in the containing module's export declaration space. + +An *ExportListDeclaration* with a *FromClause* re-exports entities from a specified module. In a declaration of the form + +```TypeScript +export { x } from "mod"; +``` + +the name `x` must reference an entity in the export member set of the specified module, and the declaration introduces an entity with the same name and meaning in the containing module's export declaration space. No local bindings are created for `x`. + +The *ExportClause* of an *ExportListDeclaration* can specify multiple entities and may optionally specify different names to be used for the exported entities. For example, the declaration + +```TypeScript +export { x, y as b, z as c }; +``` + +introduces entities named `x`, `b`, and `c` in the containing module's export declaration space with the same meaning as the local entities named `x`, `y`, and `z` respectively. + +An *ExportListDeclaration* that specifies `*` instead of an *ExportClause* is called an ***export star*** declaration. An export star declaration re-exports all members of a specified module. + +```TypeScript +export * from "mod"; +``` + +Explicitly exported members take precedence over members re-exported using export star declarations, as described in the following section. + +#### 11.3.4.4 Export Member Set + +The ***export member set*** of a particular module is determined by starting with an empty set of members *E* and an empty set of processed modules *P*, and then processing the module as described below to form the full set of exported members in *E*. Processing a module *M* consists of these steps: + +* Add *M* to *P*. +* Add to *E* each member in the export declaration space of *M* with a name that isn't already in *E*. +* For each export star declaration in *M*, in order of declaration, process the referenced module if it is not already in *P*. + +A module's ***instance type*** is an object type with a property for each member in the module's export member set that denotes a value. + +If a module contains an export assignment it is an error for the module to also contain export declarations. The two types of exports are mutually exclusive. + +### 11.3.5 Export Assignments + +Export assignments exist for backward compatibility with earlier versions of TypeScript. An export assignment designates a module member as the entity to be exported in place of the module itself. + +  *ExportAssignment:* +   `export` `=` *IdentifierReference* `;` + +A module containing an export assignment can be imported using an import require declaration ([11.3.3](#11.3.3)), and the local alias introduced by the import require declaration then takes on all meanings of the identifier named in the export assignment. + +A module containing an export assignment can also be imported using a regular import declaration ([11.3.2](#11.3.2)) provided the entity referenced in the export assignment is declared as a namespace or as a variable with a type annotation. + +Assume the following example resides in the file 'point.ts': + +```TypeScript +export = Point; + +class Point { + constructor(public x: number, public y: number) { } + static origin = new Point(0, 0); +} +``` + +When 'point.ts' is imported in another module, the import alias references the exported class and can be used both as a type and as a constructor function: + +```TypeScript +import Pt = require("./point"); + +var p1 = new Pt(10, 20); +var p2 = Pt.origin; +``` + +Note that there is no requirement that the import alias use the same name as the exported entity. + +### 11.3.6 CommonJS Modules + +The [CommonJS Modules](http://www.commonjs.org/specs/modules/1.0/) definition specifies a methodology for writing JavaScript modules with implied privacy, the ability to import other modules, and the ability to explicitly export members. A CommonJS compliant system provides a 'require' function that can be used to synchronously load other modules to obtain their singleton module instance, as well as an 'exports' variable to which a module can add properties to define its external API. + +The 'main' and 'log' example from section [11.3](#11.3) above generates the following JavaScript code when compiled for the CommonJS Modules pattern: + +File main.js: + +```TypeScript +var log_1 = require("./log"); +log_1.message("hello"); +``` + +File log.js: + +```TypeScript +function message(s) { + console.log(s); +} +exports.message = message; +``` + +A module import declaration is represented in the generated JavaScript as a variable initialized by a call to the 'require' function provided by the module system host. A variable declaration and 'require' call is emitted for a particular imported module only if the imported module, or a local alias (section [10.3](#10.3)) that references the imported module, is referenced as a *PrimaryExpression* somewhere in the body of the importing module. If an imported module is referenced only as a *NamespaceName* or *TypeQueryExpression*, nothing is emitted. + +An example: + +File geometry.ts: + +```TypeScript +export interface Point { x: number; y: number }; + +export function point(x: number, y: number): Point { + return { x, y }; +} +``` + +File game.ts: + +```TypeScript +import * as g from "./geometry"; +let p = g.point(10, 20); +``` + +The 'game' module references the imported 'geometry' module in an expression (through its alias 'g') and a 'require' call is therefore included in the emitted JavaScript: + +```TypeScript +var g = require("./geometry"); +var p = g.point(10, 20); +``` + +Had the 'game' module instead been written to only reference 'geometry' in a type position + +```TypeScript +import * as g from "./geometry"; +let p: g.Point = { x: 10, y: 20 }; +``` + +the emitted JavaScript would have no dependency on the 'geometry' module and would simply be + +```TypeScript +var p = { x: 10, y: 20 }; +``` + +### 11.3.7 AMD Modules + +The [Asynchronous Module Definition](https://github.com/amdjs/amdjs-api/wiki/AMD) (AMD) specification extends the CommonJS Modules specification with a pattern for authoring asynchronously loadable modules with associated dependencies. Using the AMD pattern, modules are emitted as calls to a global 'define' function taking an array of dependencies, specified as module names, and a callback function containing the module body. The global 'define' function is provided by including an AMD compliant loader in the application. The loader arranges to asynchronously load the module's dependencies and, upon completion, calls the callback function passing resolved module instances as arguments in the order they were listed in the dependency array. + +The "main" and "log" example from above generates the following JavaScript code when compiled for the AMD pattern. + +File main.js: + +```TypeScript +define(["require", "exports", "./log"], function(require, exports, log_1) { + log_1.message("hello"); +} +``` + +File log.js: + +```TypeScript +define(["require", "exports"], function(require, exports) { + function message(s) { + console.log(s); + } + exports.message = message; +} +``` + +The special 'require' and 'exports' dependencies are always present. Additional entries are added to the dependencies array and the parameter list as required to represent imported modules. Similar to the code generation for CommonJS Modules, a dependency entry is generated for a particular imported module only if the imported module is referenced as a *PrimaryExpression* somewhere in the body of the importing module. If an imported module is referenced only as a *NamespaceName*, no dependency is generated for that module. + +
+ +#
12 Ambients + +Ambient declarations are used to provide static typing over existing JavaScript code. Ambient declarations differ from regular declarations in that no JavaScript code is emitted for them. Instead of introducing new variables, functions, classes, enums, or namespaces, ambient declarations provide type information for entities that exist "ambiently" and are included in a program by external means, for example by referencing a JavaScript library in a <script/> tag. + +## 12.1 Ambient Declarations + +Ambient declarations are written using the `declare` keyword and can declare variables, functions, classes, enums, namespaces, or modules. + +  *AmbientDeclaration:* +   `declare` *AmbientVariableDeclaration* +   `declare` *AmbientFunctionDeclaration* +   `declare` *AmbientClassDeclaration* +   `declare` *AmbientEnumDeclaration* +   `declare` *AmbientNamespaceDeclaration* + +### 12.1.1 Ambient Variable Declarations + +An ambient variable declaration introduces a variable in the containing declaration space. + +  *AmbientVariableDeclaration:* +   `var` *AmbientBindingList* `;` +   `let` *AmbientBindingList* `;` +   `const` *AmbientBindingList* `;` + +  *AmbientBindingList:* +   *AmbientBinding* +   *AmbientBindingList* `,` *AmbientBinding* + +  *AmbientBinding:* +   *BindingIdentifier* *TypeAnnotationopt* + +An ambient variable declaration may optionally include a type annotation. If no type annotation is present, the variable is assumed to have type Any. + +An ambient variable declaration does not permit an initializer expression to be present. + +### 12.1.2 Ambient Function Declarations + +An ambient function declaration introduces a function in the containing declaration space. + +  *AmbientFunctionDeclaration:* +   `function` *BindingIdentifier* *CallSignature* `;` + +Ambient functions may be overloaded by specifying multiple ambient function declarations with the same name, but it is an error to declare multiple overloads that are considered identical (section [3.11.2](#3.11.2)) or differ only in their return types. + +Ambient function declarations cannot specify a function bodies and do not permit default parameter values. + +### 12.1.3 Ambient Class Declarations + +An ambient class declaration declares a class type and a constructor function in the containing declaration space. + +  *AmbientClassDeclaration:* +   `class` *BindingIdentifier* *TypeParametersopt* *ClassHeritage* `{` *AmbientClassBody* `}` + +  *AmbientClassBody:* +   *AmbientClassBodyElementsopt* + +  *AmbientClassBodyElements:* +   *AmbientClassBodyElement* +   *AmbientClassBodyElements* *AmbientClassBodyElement* + +  *AmbientClassBodyElement:* +   *AmbientConstructorDeclaration* +   *AmbientPropertyMemberDeclaration* +   *IndexSignature* + +  *AmbientConstructorDeclaration:* +   `constructor` `(` *ParameterListopt* `)` `;` + +  *AmbientPropertyMemberDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *TypeAnnotationopt* `;` +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *CallSignature* `;` + +### 12.1.4 Ambient Enum Declarations + +An ambient enum is grammatically equivalent to a non-ambient enum declaration. + +  *AmbientEnumDeclaration:* +   *EnumDeclaration* + +Ambient enum declarations differ from non-ambient enum declarations in two ways: + +* In ambient enum declarations, all values specified in enum member declarations must be classified as constant enum expressions. +* In ambient enum declarations that specify no `const` modifier, enum member declarations that omit a value are considered computed members (as opposed to having auto-incremented values assigned). + +Ambient enum declarations are otherwise processed in the same manner as non-ambient enum declarations. + +### 12.1.5 Ambient Namespace Declarations + +An ambient namespace declaration declares a namespace. + +  *AmbientNamespaceDeclaration:* +   `namespace` *IdentifierPath* `{` *AmbientNamespaceBody* `}` + +  *AmbientNamespaceBody:* +   *AmbientNamespaceElementsopt* + +  *AmbientNamespaceElements:* +   *AmbientNamespaceElement* +   *AmbientNamespaceElements* *AmbientNamespaceElement* + +  *AmbientNamespaceElement:* +   `export`*opt* *AmbientVariableDeclaration* +   `export`*opt* *AmbientLexicalDeclaration* +   `export`*opt* *AmbientFunctionDeclaration* +   `export`*opt* *AmbientClassDeclaration* +   `export`*opt* *InterfaceDeclaration* +   `export`*opt* *AmbientEnumDeclaration* +   `export`*opt* *AmbientNamespaceDeclaration* +   `export`*opt* *ImportAliasDeclaration* + +Except for *ImportAliasDeclarations*, *AmbientNamespaceElements* always declare exported entities regardless of whether they include the optional `export` modifier. + +## 12.2 Ambient Module Declarations + +An *AmbientModuleDeclaration* declares a module. This type of declaration is permitted only at the top level in a source file that contributes to the global namespace (section [11.1](#11.1)). The *StringLiteral* must specify a top-level module name. Relative module names are not permitted. + +  *AmbientModuleDeclaration:* +   `declare` `module` *StringLiteral* `{`  *DeclarationModule* `}` + +An *ImportRequireDeclaration* in an *AmbientModuleDeclaration* may reference other modules only through top-level module names. Relative module names are not permitted. + +If an ambient module declaration includes an export assignment, it is an error for any of the declarations within the module to specify an `export` modifier. If an ambient module declaration contains no export assignment, entities declared in the module are exported regardless of whether their declarations include the optional `export` modifier. + +Ambient modules are "open-ended" and ambient module declarations with the same string literal name contribute to a single module. For example, the following two declarations of a module 'io' might be located in separate source files. + +```TypeScript +declare module "io" { + export function readFile(filename: string): string; +} + +declare module "io" { + export function writeFile(filename: string, data: string): void; +} +``` + +This has the same effect as a single combined declaration: + +```TypeScript +declare module "io" { + export function readFile(filename: string): string; + export function writeFile(filename: string, data: string): void; +} +``` + +
+ +#
A Grammar + +This appendix contains a summary of the grammar found in the main document. As described in section [2.1](#2.1), the TypeScript grammar is a superset of the grammar defined in the [ECMAScript 2015 Language Specification](http://www.ecma-international.org/ecma-262/6.0/) (specifically, the ECMA-262 Standard, 6th Edition) and this appendix lists only productions that are new or modified from the ECMAScript grammar. + +## A.1 Types + +  *TypeParameters:* +   `<` *TypeParameterList* `>` + +  *TypeParameterList:* +   *TypeParameter* +   *TypeParameterList* `,` *TypeParameter* + +  *TypeParameter:* +   *BindingIdentifier* *Constraintopt* + +  *Constraint:* +   `extends` *Type* + +  *TypeArguments:* +   `<` *TypeArgumentList* `>` + +  *TypeArgumentList:* +   *TypeArgument* +   *TypeArgumentList* `,` *TypeArgument* + +  *TypeArgument:* +   *Type* + +  *Type:* +   *UnionOrIntersectionOrPrimaryType* +   *FunctionType* +   *ConstructorType* + +  *UnionOrIntersectionOrPrimaryType:* +   *UnionType* +   *IntersectionOrPrimaryType* + +  *IntersectionOrPrimaryType:* +   *IntersectionType* +   *PrimaryType* + +  *PrimaryType:* +   *ParenthesizedType* +   *PredefinedType* +   *TypeReference* +   *ObjectType* +   *ArrayType* +   *TupleType* +   *TypeQuery* +   *ThisType* + +  *ParenthesizedType:* +   `(` *Type* `)` + +  *PredefinedType:* +   `any` +   `number` +   `boolean` +   `string` +   `symbol` +   `void` + +  *TypeReference:* +   *TypeName* *[no LineTerminator here]* *TypeArgumentsopt* + +  *TypeName:* +   *IdentifierReference* +   *NamespaceName* `.` *IdentifierReference* + +  *NamespaceName:* +   *IdentifierReference* +   *NamespaceName* `.` *IdentifierReference* + +  *ObjectType:* +   `{` *TypeBodyopt* `}` + +  *TypeBody:* +   *TypeMemberList* `;`*opt* +   *TypeMemberList* `,`*opt* + +  *TypeMemberList:* +   *TypeMember* +   *TypeMemberList* `;` *TypeMember* +   *TypeMemberList* `,` *TypeMember* + +  *TypeMember:* +   *PropertySignature* +   *CallSignature* +   *ConstructSignature* +   *IndexSignature* +   *MethodSignature* + +  *ArrayType:* +   *PrimaryType* *[no LineTerminator here]* `[` `]` + +  *TupleType:* +   `[` *TupleElementTypes* `]` + +  *TupleElementTypes:* +   *TupleElementType* +   *TupleElementTypes* `,` *TupleElementType* + +  *TupleElementType:* +   *Type* + +  *UnionType:* +   *UnionOrIntersectionOrPrimaryType* `|` *IntersectionOrPrimaryType* + +  *IntersectionType:* +   *IntersectionOrPrimaryType* `&` *PrimaryType* + +  *FunctionType:* +   *TypeParametersopt* `(` *ParameterListopt* `)` `=>` *Type* + +  *ConstructorType:* +   `new` *TypeParametersopt* `(` *ParameterListopt* `)` `=>` *Type* + +  *TypeQuery:* +   `typeof` *TypeQueryExpression* + +  *TypeQueryExpression:* +   *IdentifierReference* +   *TypeQueryExpression* `.` *IdentifierName* + +  *ThisType:* +   `this` + +  *PropertySignature:* +   *PropertyName* `?`*opt* *TypeAnnotationopt* + +  *PropertyName:* +   *IdentifierName* +   *StringLiteral* +   *NumericLiteral* + +  *TypeAnnotation:* +   `:` *Type* + +  *CallSignature:* +   *TypeParametersopt* `(` *ParameterListopt* `)` *TypeAnnotationopt* + +  *ParameterList:* +   *RequiredParameterList* +   *OptionalParameterList* +   *RestParameter* +   *RequiredParameterList* `,` *OptionalParameterList* +   *RequiredParameterList* `,` *RestParameter* +   *OptionalParameterList* `,` *RestParameter* +   *RequiredParameterList* `,` *OptionalParameterList* `,` *RestParameter* + +  *RequiredParameterList:* +   *RequiredParameter* +   *RequiredParameterList* `,` *RequiredParameter* + +  *RequiredParameter:* +   *AccessibilityModifieropt* *BindingIdentifierOrPattern* *TypeAnnotationopt* +   *BindingIdentifier* `:` *StringLiteral* + +  *AccessibilityModifier:* +   `public` +   `private` +   `protected` + +  *BindingIdentifierOrPattern:* +   *BindingIdentifier* +   *BindingPattern* + +  *OptionalParameterList:* +   *OptionalParameter* +   *OptionalParameterList* `,` *OptionalParameter* + +  *OptionalParameter:* +   *AccessibilityModifieropt* *BindingIdentifierOrPattern* `?` *TypeAnnotationopt* +   *AccessibilityModifieropt* *BindingIdentifierOrPattern* *TypeAnnotationopt* *Initializer* +   *BindingIdentifier* `?` `:` *StringLiteral* + +  *RestParameter:* +   `...` *BindingIdentifier* *TypeAnnotationopt* + +  *ConstructSignature:* +   `new` *TypeParametersopt* `(` *ParameterListopt* `)` *TypeAnnotationopt* + +  *IndexSignature:* +   `[` *BindingIdentifier* `:` `string` `]` *TypeAnnotation* +   `[` *BindingIdentifier* `:` `number` `]` *TypeAnnotation* + +  *MethodSignature:* +   *PropertyName* `?`*opt* *CallSignature* + +  *TypeAliasDeclaration:* +   `type` *BindingIdentifier* *TypeParametersopt* `=` *Type* `;` + +## A.2 Expressions + +  *PropertyDefinition:* *( Modified )* +   *IdentifierReference* +   *CoverInitializedName* +   *PropertyName* `:` *AssignmentExpression* +   *PropertyName* *CallSignature* `{` *FunctionBody* `}` +   *GetAccessor* +   *SetAccessor* + +  *GetAccessor:* +   `get` *PropertyName* `(` `)` *TypeAnnotationopt* `{` *FunctionBody* `}` + +  *SetAccessor:* +   `set` *PropertyName* `(` *BindingIdentifierOrPattern* *TypeAnnotationopt* `)` `{` *FunctionBody* `}` + +  *FunctionExpression:* *( Modified )* +   `function` *BindingIdentifieropt* *CallSignature* `{` *FunctionBody* `}` + +  *ArrowFormalParameters:* *( Modified )* +   *CallSignature* + +  *Arguments:* *( Modified )* +   *TypeArgumentsopt* `(` *ArgumentListopt* `)` + +  *UnaryExpression:* *( Modified )* +   … +   `<` *Type* `>` *UnaryExpression* + +## A.3 Statements + +  *Declaration:* *( Modified )* +   … +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *EnumDeclaration* + +  *VariableDeclaration:* *( Modified )* +   *SimpleVariableDeclaration* +   *DestructuringVariableDeclaration* + +  *SimpleVariableDeclaration:* +   *BindingIdentifier* *TypeAnnotationopt* *Initializeropt* + +  *DestructuringVariableDeclaration:* +   *BindingPattern* *TypeAnnotationopt* *Initializer* + +  *LexicalBinding:* *( Modified )* +   *SimpleLexicalBinding* +   *DestructuringLexicalBinding* + +  *SimpleLexicalBinding:* +   *BindingIdentifier* *TypeAnnotationopt* *Initializeropt* + +  *DestructuringLexicalBinding:* +   *BindingPattern* *TypeAnnotationopt* *Initializeropt* + +## A.4 Functions + +  *FunctionDeclaration:* *( Modified )* +   `function` *BindingIdentifieropt* *CallSignature* `{` *FunctionBody* `}` +   `function` *BindingIdentifieropt* *CallSignature* `;` + +## A.5 Interfaces + +  *InterfaceDeclaration:* +   `interface` *BindingIdentifier* *TypeParametersopt* *InterfaceExtendsClauseopt* *ObjectType* + +  *InterfaceExtendsClause:* +   `extends` *ClassOrInterfaceTypeList* + +  *ClassOrInterfaceTypeList:* +   *ClassOrInterfaceType* +   *ClassOrInterfaceTypeList* `,` *ClassOrInterfaceType* + +  *ClassOrInterfaceType:* +   *TypeReference* + +## A.6 Classes + +  *ClassDeclaration:* *( Modified )* +   `class` *BindingIdentifieropt* *TypeParametersopt* *ClassHeritage* `{` *ClassBody* `}` + +  *ClassHeritage:* *( Modified )* +   *ClassExtendsClauseopt* *ImplementsClauseopt* + +  *ClassExtendsClause:* +   `extends`  *ClassType* + +  *ClassType:* +   *TypeReference* + +  *ImplementsClause:* +   `implements` *ClassOrInterfaceTypeList* + +  *ClassElement:* *( Modified )* +   *ConstructorDeclaration* +   *PropertyMemberDeclaration* +   *IndexMemberDeclaration* + +  *ConstructorDeclaration:* +   *AccessibilityModifieropt* `constructor` `(` *ParameterListopt* `)` `{` *FunctionBody* `}` +   *AccessibilityModifieropt* `constructor` `(` *ParameterListopt* `)` `;` + +  *PropertyMemberDeclaration:* +   *MemberVariableDeclaration* +   *MemberFunctionDeclaration* +   *MemberAccessorDeclaration* + +  *MemberVariableDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *TypeAnnotationopt* *Initializeropt* `;` + +  *MemberFunctionDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *CallSignature* `{` *FunctionBody* `}` +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *CallSignature* `;` + +  *MemberAccessorDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *GetAccessor* +   *AccessibilityModifieropt* `static`*opt* *SetAccessor* + +  *IndexMemberDeclaration:* +   *IndexSignature* `;` + +## A.7 Enums + +  *EnumDeclaration:* +   `const`*opt* `enum` *BindingIdentifier* `{` *EnumBodyopt* `}` + +  *EnumBody:* +   *EnumMemberList* `,`*opt* + +  *EnumMemberList:* +   *EnumMember* +   *EnumMemberList* `,` *EnumMember* + +  *EnumMember:* +   *PropertyName* +   *PropertyName* = *EnumValue* + +  *EnumValue:* +   *AssignmentExpression* + +## A.8 Namespaces + +  *NamespaceDeclaration:* +   `namespace` *IdentifierPath* `{` *NamespaceBody* `}` + +  *IdentifierPath:* +   *BindingIdentifier* +   *IdentifierPath* `.` *BindingIdentifier* + +  *NamespaceBody:* +   *NamespaceElementsopt* + +  *NamespaceElements:* +   *NamespaceElement* +   *NamespaceElements* *NamespaceElement* + +  *NamespaceElement:* +   *Statement* +   *LexicalDeclaration* +   *FunctionDeclaration* +   *GeneratorDeclaration* +   *ClassDeclaration* +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *EnumDeclaration* +   *NamespaceDeclaration +   AmbientDeclaration +   ImportAliasDeclaration +   ExportNamespaceElement* + +  *ExportNamespaceElement:* +   `export` *VariableStatement* +   `export` *LexicalDeclaration* +   `export` *FunctionDeclaration* +   `export` *GeneratorDeclaration* +   `export` *ClassDeclaration* +   `export` *InterfaceDeclaration* +   `export` *TypeAliasDeclaration* +   `export` *EnumDeclaration* +   `export` *NamespaceDeclaration* +   `export` *AmbientDeclaration* +   `export` *ImportAliasDeclaration* + +  *ImportAliasDeclaration:* +   `import` *BindingIdentifier* `=` *EntityName* `;` + +  *EntityName:* +   *NamespaceName* +   *NamespaceName* `.` *IdentifierReference* + +## A.9 Scripts and Modules + +  *SourceFile:* +   *ImplementationSourceFile* +   *DeclarationSourceFile* + +  *ImplementationSourceFile:* +   *ImplementationScript* +   *ImplementationModule* + +  *DeclarationSourceFile:* +   *DeclarationScript* +   *DeclarationModule* + +  *ImplementationScript:* +   *ImplementationScriptElementsopt* + +  *ImplementationScriptElements:* +   *ImplementationScriptElement* +   *ImplementationScriptElements* *ImplementationScriptElement* + +  *ImplementationScriptElement:* +   *ImplementationElement* +   *AmbientModuleDeclaration* + +  *ImplementationElement:* +   *Statement* +   *LexicalDeclaration* +   *FunctionDeclaration* +   *GeneratorDeclaration* +   *ClassDeclaration* +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *EnumDeclaration* +   *NamespaceDeclaration* +   *AmbientDeclaration* +   *ImportAliasDeclaration* + +  *DeclarationScript:* +   *DeclarationScriptElementsopt* + +  *DeclarationScriptElements:* +   *DeclarationScriptElement* +   *DeclarationScriptElements* *DeclarationScriptElement* + +  *DeclarationScriptElement:* +   *DeclarationElement* +   *AmbientModuleDeclaration* + +  *DeclarationElement:* +   *InterfaceDeclaration* +   *TypeAliasDeclaration* +   *NamespaceDeclaration* +   *AmbientDeclaration* +   *ImportAliasDeclaration* + +  *ImplementationModule:* +   *ImplementationModuleElementsopt* + +  *ImplementationModuleElements:* +   *ImplementationModuleElement* +   *ImplementationModuleElements* *ImplementationModuleElement* + +  *ImplementationModuleElement:* +   *ImplementationElement* +   *ImportDeclaration* +   *ImportAliasDeclaration* +   *ImportRequireDeclaration* +   *ExportImplementationElement* +   *ExportDefaultImplementationElement* +   *ExportListDeclaration* +   *ExportAssignment* + +  *DeclarationModule:* +   *DeclarationModuleElementsopt* + +  *DeclarationModuleElements:* +   *DeclarationModuleElement* +   *DeclarationModuleElements* *DeclarationModuleElement* + +  *DeclarationModuleElement:* +   *DeclarationElement* +   *ImportDeclaration* +   *ImportAliasDeclaration* +   *ExportDeclarationElement* +   *ExportDefaultDeclarationElement* +   *ExportListDeclaration* +   *ExportAssignment* + +  *ImportRequireDeclaration:* +   `import` *BindingIdentifier* `=` `require` `(` *StringLiteral* `)` `;` + +  *ExportImplementationElement:* +   `export` *VariableStatement* +   `export` *LexicalDeclaration* +   `export` *FunctionDeclaration* +   `export` *GeneratorDeclaration* +   `export` *ClassDeclaration* +   `export` *InterfaceDeclaration* +   `export` *TypeAliasDeclaration* +   `export` *EnumDeclaration* +   `export` *NamespaceDeclaration* +   `export` *AmbientDeclaration* +   `export` *ImportAliasDeclaration* + +  *ExportDeclarationElement:* +   `export` *InterfaceDeclaration* +   `export` *TypeAliasDeclaration* +   `export` *AmbientDeclaration* +   `export` *ImportAliasDeclaration* + +  *ExportDefaultImplementationElement:* +   `export` `default` *FunctionDeclaration* +   `export` `default` *GeneratorDeclaration* +   `export` `default` *ClassDeclaration* +   `export` `default` *AssignmentExpression* `;` + +  *ExportDefaultDeclarationElement:* +   `export` `default` *AmbientFunctionDeclaration* +   `export` `default` *AmbientClassDeclaration* +   `export` `default` *IdentifierReference* `;` + +  *ExportListDeclaration:* +   `export` `*` *FromClause* `;` +   `export` *ExportClause* *FromClause* `;` +   `export` *ExportClause* `;` + +  *ExportAssignment:* +   `export` `=` *IdentifierReference* `;` + +## A.10 Ambients + +  *AmbientDeclaration:* +   `declare` *AmbientVariableDeclaration* +   `declare` *AmbientFunctionDeclaration* +   `declare` *AmbientClassDeclaration* +   `declare` *AmbientEnumDeclaration* +   `declare` *AmbientNamespaceDeclaration* + +  *AmbientVariableDeclaration:* +   `var` *AmbientBindingList* `;` +   `let` *AmbientBindingList* `;` +   `const` *AmbientBindingList* `;` + +  *AmbientBindingList:* +   *AmbientBinding* +   *AmbientBindingList* `,` *AmbientBinding* + +  *AmbientBinding:* +   *BindingIdentifier* *TypeAnnotationopt* + +  *AmbientFunctionDeclaration:* +   `function` *BindingIdentifier* *CallSignature* `;` + +  *AmbientClassDeclaration:* +   `class` *BindingIdentifier* *TypeParametersopt* *ClassHeritage* `{` *AmbientClassBody* `}` + +  *AmbientClassBody:* +   *AmbientClassBodyElementsopt* + +  *AmbientClassBodyElements:* +   *AmbientClassBodyElement* +   *AmbientClassBodyElements* *AmbientClassBodyElement* + +  *AmbientClassBodyElement:* +   *AmbientConstructorDeclaration* +   *AmbientPropertyMemberDeclaration* +   *IndexSignature* + +  *AmbientConstructorDeclaration:* +   `constructor` `(` *ParameterListopt* `)` `;` + +  *AmbientPropertyMemberDeclaration:* +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *TypeAnnotationopt* `;` +   *AccessibilityModifieropt* `static`*opt* *PropertyName* *CallSignature* `;` + +  *AmbientEnumDeclaration:* +   *EnumDeclaration* + +  *AmbientNamespaceDeclaration:* +   `namespace` *IdentifierPath* `{` *AmbientNamespaceBody* `}` + +  *AmbientNamespaceBody:* +   *AmbientNamespaceElementsopt* + +  *AmbientNamespaceElements:* +   *AmbientNamespaceElement* +   *AmbientNamespaceElements* *AmbientNamespaceElement* + +  *AmbientNamespaceElement:* +   `export`*opt* *AmbientVariableDeclaration* +   `export`*opt* *AmbientLexicalDeclaration* +   `export`*opt* *AmbientFunctionDeclaration* +   `export`*opt* *AmbientClassDeclaration* +   `export`*opt* *InterfaceDeclaration* +   `export`*opt* *AmbientEnumDeclaration* +   `export`*opt* *AmbientNamespaceDeclaration* +   `export`*opt* *ImportAliasDeclaration* + +  *AmbientModuleDeclaration:* +   `declare` `module` *StringLiteral* `{`  *DeclarationModule* `}` + diff --git "a/stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" "b/stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" new file mode 100644 index 00000000..121e9a6c --- /dev/null +++ "b/stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" @@ -0,0 +1,53 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/导言/范围与一致性 { + r##"# 范围与一致性 + +## 本规范的地位 + +本规范是 kvlang 语言的**唯一事实源**。语言核心的任何设计或实现调整,一律**规范驱动**:先改本规范的相应条款及其锚定示例,再改实现,直至锚例在三后端全绿。规范与实现不符时,以规范为准,实现视为缺陷。 + +规范以 kvlang 自身书写(`.kv`),layout&run 后落进 `/lib/kvlang/规范/…`——规范即 KV 树里的数据,可被 kvlang 自解析与自校验。 + +## 范围 + +本规范界定 kvlang 语言本体: + +- **词法**(卷 01)——源码表示、词法单元、注释、标识符、字面量、运算符。 +- **kvspace 模型**(卷 02)——地址空间、寻址与命名、键系统与数组访问、指令布局格式、系统变量。kvspace 既是寻址空间也是内存空间,是 kvlang 的第一性前置概念,故前置于语义两卷。 +- **类型系统**(卷 03)——种类与定宽类型、kindexpr 签名类型表达式、数组形态、容器。类型跨 layout 与 runtime 两阶段,故独立成卷。 +- **layout 语义**(卷 04)——静态语义:语法检查与布局。layout 是 **o0 编译器**:做检查、布局与降级,**不做任何优化**(一旦优化即丢失高层语义,使扩展编译器无法按原语义在异构硬件上优化),可报诊断。 +- **runtime 语义**(卷 05)——动态语义:纯解释执行。 + +附录给出唯一权威文法;设计理由卷为非规范(non-normative)的动机说明。 + +## 核心与扩展边界 + +kvlang 是**小核心 + 扩展主导**的语言。本规范只界定语言核心必须保证的语义,以及核心与扩展之间的契约(rwir 声明、rwirext 扩展运行时)。具体扩展(numpy、fs、networld、gpu 等)提供的 rwir 语义不属本规范,由各扩展自身文档界定;本规范只规定 kvlang 如何声明、定位、调用扩展 rwir(见卷 05)。 + +## 一致性 + +**tutorial 套件即一致性测试。** 一个实现是否符合本规范,由 `tutorial/` 下的可运行 `.kv` 示例判定:三后端(shm / fs / redis)全部通过、输出逐字节一致,即为符合。 + +本规范每条 normative 条款应锚定至 tutorial 中至少一条示例。修改语言的流程恒为: + +1. 修改本规范条款; +2. 增改其锚定的 tutorial 示例(新增条款须补锚例,不改动既有冻结示例的语义); +3. 修改 layout / runtime 实现,直至锚例三后端全绿。 + +## 规范用语 + +规范用语对齐 RFC 2119 语义: + +- **必须 / 不得**(must / must not / shall)——绝对要求 / 绝对禁止。违反即不符合规范。 +- **应 / 不应**(should / should not)——存在正当理由时可偏离,但须权衡后果。 +- **可**(may)——纯可选。 + +未加此类限定词的陈述句为**事实性描述**(语言如此这般),同样是 normative 的。设计动机、历史与取舍一律归入非规范的**设计理由**卷,不混入正文条款。 + +## 阅读约定 + +- 文法元记法与本规范其余用语约定见 [[元记法与规范用语]]。 +- 完整权威文法汇总于 [[文法]](附录);正文各章只引用其片段,不各自另立文法。 +- 章节间引用以 `[[章节名]]` 链接。 +"## -> /lib/kvlang/规范/导言/范围与一致性 +} diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\344\270\216\350\257\215\346\263\225\345\215\225\345\205\203.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\344\270\216\350\257\215\346\263\225\345\215\225\345\205\203.kv" new file mode 100644 index 00000000..4f4ee117 --- /dev/null +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\344\270\216\350\257\215\346\263\225\345\215\225\345\205\203.kv" @@ -0,0 +1,59 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/词法/源码与词法单元 { + r####"# 源码与词法单元 + +## 源码表示 + +kvlang 源文件是一段 **UTF-8 字节序列**。词法分析按字节推进:ASCII 字节触发语法结构,其余多字节序列(如中文、`é`)作为普通字符原样穿过,出现在标识符、字符串与路径内部。 + +一处**行**由换行符 `\n`(U+000A)界定;`\r`(U+000D)在词法阶段被直接跳过,不产生任何词法单元,故 `\r\n` 与 `\n` 等价。位置以 1 起始的 `line`、`col` 计。 + +## 空白与语句分隔 + +空格 ` ` 与制表符 `\t` 是词法单元之间的分隔符,本身不产生词法单元;除用于分隔相邻词法单元外不具意义。 + +**语句分隔**由换行符 `\n` 与分号 `;` 表达,二者语义等价,均产生一个 `Newline` 词法单元。词法器执行两条归并规则: + +- 连续的语句分隔(多个换行/分号、含其间空白)**折叠**为单个 `Newline`; +- 词法单元流开头的语句分隔被**抑制**,不产生 `Newline`。 + +字符串与原始字符串字面量内部的物理换行**不**产生 `Newline`(它是字面量内容的一部分),但行号仍随之前进。 + +## 词法单元种类 + +词法分析把源码切分为下列种类的词法单元,末尾附一个 `EOF` 哨兵: + +- `Ident`——标识符,以及未被单独归类的符号运算符(见 [[运算符]]); +- `Literal`——字面量:数值、字符串、原始字符串、绝对路径(见 [[字面量]]、[[标识符与路径]]); +- `Arrow`——三种赋值/方向记号 `=`、`<-`、`->`(见 [[运算符]]); +- `Dot`——成员分隔符 `·`(U+00B7,见 [[标识符与路径]]); +- `LParen` `RParen` `LBrace` `RBrace` `LBrack` `RBrack`——`( ) { } [ ]`; +- `Comma` `Colon`——`,` `:`; +- `Newline`——语句分隔(`\n` 或 `;`,见上); +- `Comment`——注释(见 [[注释]]); +- 关键字词法单元 `Return` `If` `Else` `For` `While` `Break` `Continue`; +- `EOF`——源码结束哨兵。 + +## 关键字 + +kvlang 只有 **7 个词法关键字**,它们在词法阶段即被识别,不得用作标识符: + +``` +return if else for while break continue +``` + +其余在语言中具有特殊含义的词(`lib`、`rwir`、`rwfunc`、`in`、`any`、`None`、`true`、`false`、种类名如 `int64`/`float32`/`object` 等)**不是**词法关键字:它们一律词法化为 `Ident`,其含义由 layout 阶段依上下文赋予。这类词称为**上下文词**。 + +## 最长匹配 + +词法分析遵循**最长匹配**(maximal munch):在每个位置,词法器取能构成合法词法单元的最长字符序列。特别地: + +- 以数字开头的序列必为数值字面量,不会被识别为标识符; +- `<` 后紧跟 `-` 构成 `<-`,`-` 后紧跟 `>` 构成 `->`,`<` 后紧跟 `<` 构成 `<<`,依此类推——双字符运算符优先于其单字符成分。 + +## 锚例 + +- `tutorial/01-basics/hello.kv`——最小源文件与 `Ident`/`Literal`/调用记号。 +- `tutorial/01-basics/vars.kv`——换行作语句分隔、`<-`/`=` 记号、行注释。 +"#### -> /lib/kvlang/规范/词法/源码与词法单元 +} diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\346\263\250\351\207\212.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\346\263\250\351\207\212.kv" new file mode 100644 index 00000000..4ea4f473 --- /dev/null +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\346\263\250\351\207\212.kv" @@ -0,0 +1,42 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/词法/注释 { + r####"# 注释 + +kvlang 有两种注释,语法与 Rust 一致。**不存在** `#` 注释。 + +## 行注释 + +行注释以 `//` 开始,延伸至(但**不含**)该行的换行符: + +``` +x <- 42 // 这是行注释 +``` + +行注释不消费其后的换行符,故一行末尾的行注释之后仍产生一个 `Newline` 语句分隔。行注释不嵌套:其内部的 `//`、`/*` 均无特殊含义。 + +## 块注释 + +块注释由 `/*` 与 `*/` 界定,**可跨行**: + +``` +/* 这一段 + 跨越多行 */ +``` + +块注释**可嵌套**:词法器对 `/*` 计数、对 `*/` 递减,仅当计数归零才结束。因此下例整体是一条注释: + +``` +/* 外层 /* 内层 */ 仍在注释内 */ +``` + +嵌套能力使得注释掉一段本身含块注释的代码是安全的。若源码结束时块注释仍未闭合,注释延伸至文件末尾。 + +## 注释的地位 + +注释被词法化为 `Comment` 词法单元,在词法流中保留,但对程序语义无贡献——layout 阶段将其忽略。注释不是语句分隔符:其内部的换行不产生 `Newline`(块注释),行注释后的换行照常产生 `Newline`。 + +## 锚例 + +- `tutorial/01-basics/vars.kv`、`tutorial/01-basics/arith.kv`——行注释(含期望输出注释块与行尾 `// = 等价于 <-`)。 +"#### -> /lib/kvlang/规范/词法/注释 +} diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\240\207\350\257\206\347\254\246\344\270\216\350\267\257\345\276\204.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\240\207\350\257\206\347\254\246\344\270\216\350\267\257\345\276\204.kv" new file mode 100644 index 00000000..6b5c6725 --- /dev/null +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\240\207\350\257\206\347\254\246\344\270\216\350\267\257\345\276\204.kv" @@ -0,0 +1,59 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/词法/标识符与路径 { + r####"# 标识符与路径 + +## 标识符 + +标识符命名帧内变量、参数、lib 段、rwir/rwfunc、成员键等。其规范形态为: + +``` +letter = unicode_letter | "_" +ident = letter { letter | digit } +``` + +其中 `unicode_letter` 为任意 Unicode 字母。因此标识符**可含非 ASCII 字母**,中文标识符合法: + +``` +变量数 <- 42 +println("值 =", 变量数) +``` + +此决策使 kvlang 与 C99、Go、Python、Rust、TypeScript 在「允许 Unicode 标识符」上对齐。 + +7 个词法关键字(`return if else for while break continue`)为保留字,不得用作标识符;其余上下文词(`lib`、`None`、`true`、`false`、种类名等)不保留,但用作普通标识符会遮蔽其上下文含义,不应如此使用。 + +> 实现说明(非规范):当前词法器以「最长非分隔符字节串」切分标识符,未逐字符校验上述字母表,故比本节所述更宽松。分隔符集合为空白、`; , ( ) { } [ ] :`、成员分隔符 `·`,以及运算符字符 `+ - * % ! = < > & | ^`。 + +## 成员分隔符 `·` + +`·`(U+00B7,中点)是 kvlang 唯一的成员/方法分隔符,词法化为独立的 `Dot` 词法单元。它出现于: + +- 成员访问 `base·field`; +- 方法/限定调用 `base·method(...)`、`pkg·func(...)`; +- 坐标访问 `base·[i,j]`。 + +kvlang **不使用** ASCII 句点 `.` 作成员分隔符(`.` 仅作路径子键,见下)。 + +## 绝对路径字面量 + +绝对路径直接寻址 kvspace 树中的节点,是一类字面量(词法化为以 `/` 起始的 `Literal`)。路径以 `/` 开头,后随一个 ASCII 字母、数字或下划线,随后是由下列成分构成的最长序列: + +- `/`——段分隔符,划分树的层级; +- `.`——子键分隔符,寻址同一节点下的子键; +- `·[i,j,…]`——坐标段,按整数下标寻址 strkeymap/容器的坐标; +- 其余非分隔符字符构成段名(同样允许非 ASCII)。 + +``` +kv·set("/tmp/kvt·data", 42) +kv·get("/tmp/kvt", "data") -> x +kv·set("/tmp/kvt/a", 1) +``` + +路径的完整寻址语义见 [[kvspace 模型]]卷;本节只界定其词法形态。裸 `/`(其后不接字母/数字/下划线,且非 `//`、`/*`)不构成路径,见 [[运算符]]。 + +## 锚例 + +- `tutorial/01-basics/vars.kv`——标识符 `x`、`y`。 +- `tutorial/01-basics/kv_tree.kv`——绝对路径 `/tmp/kvt`、子键路径 `/tmp/kvt·data`、层级路径 `/tmp/kvt/a`,以及成员/方法 `kv·set`、`kv·get`。 +"#### -> /lib/kvlang/规范/词法/标识符与路径 +} diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\345\255\227\351\235\242\351\207\217.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\345\255\227\351\235\242\351\207\217.kv" new file mode 100644 index 00000000..9b35d95a --- /dev/null +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\345\255\227\351\235\242\351\207\217.kv" @@ -0,0 +1,69 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/词法/字面量 { + r####"# 字面量 + +字面量是源码中直接书写的常量值。kvlang 有四类字面量:数值、字符串、绝对路径(词法见 [[标识符与路径]]),以及上下文空/布尔字面量。 + +## 数值字面量 + +``` +digit = "0" … "9" +integer = digit { digit } +float = integer [ "." integer ] [ ("e" | "E") [ "+" | "-" ] integer ] +``` + +- 整数为一串十进制数字。**无**十六进制、八进制、二进制前缀,**无**下划线数字分隔符。 +- 浮点数为整数部分后可选跟小数部分 `.digits` 与可选指数 `(e|E)[±]digits`。小数点前必须有数字(不支持 `.5` 这类前导点写法)。 +- 数值字面量本身**无符号**;负数由前缀一元运算符 `-` 与字面量组合而成(见 [[运算符]])。 + +`3` 是整数字面量,`3.14`、`6.28`、`1e3`、`2.5E-4` 是浮点字面量。字面量到具体定宽种类的落定由类型系统与上下文决定(见 [[类型系统]]卷)。 + +## 字符串字面量 + +kvlang 有三种字符串书写形式,与 Rust 一致;**无**三引号串,**无**反引号原始串。 + +### 转义串 `"…"` + +以双引号界定,**可跨行**(内部的物理换行成为内容中的换行字符)。反斜杠 `\` 引入转义: + +- `\n`→换行、`\t`→制表符、`\r`→回车、`\0`→空字符; +- `\<其他字符>`→该字符本身,故 `\"`→`"`、`\\`→`\`。 + +``` +s <- "line1 +line2" // 跨行,含一个真实换行 +t <- "one\ntwo" // 转义换行 +``` + +### 原始串 `r"…"` / `r#"…"#` / `r##"…"##` … + +以 `r` 引导,**零转义**、可跨行。可在 `r` 与首个 `"` 之间加 `N` 个井号 `#`,此时须以 `"` 后接同样 `N` 个 `#` 闭合;井号越多可嵌套越深,内容因而能包含 `"`: + +``` +r <- r"raw\nliteral" // 输出含反斜杠与 n,非换行 +q <- r#"he said "hi""# // 内容含双引号 +``` + +### 单引号形式 `'…'` + +以单引号界定,用于 char / keypath 场景,与转义串共享同一套转义规则。其内容作为裸字面量交由后续阶段依上下文(char 种类、键路径)解释。 + +kvlang 的动态字符串阵营中,单个字符通常以**长度为 1 的字符串**表示(如 `s[i]` 读返单字符字符串),char 的定宽种类见 [[类型系统]]卷。 + +## 空值与布尔字面量 + +- `None`——空值字面量。kvlang 的空值**只有** `None`;书写 `null` 是错误,layout **必须**显式拒绝,**不得**当作裸标识符静默放行。未赋值的变量地址即读作 `None`。 +- `true` / `false`——布尔字面量。 + +三者均为**上下文词**:词法阶段化为标识符,由 layout/runtime 依类型上下文解释为对应值。 + +## 锚例 + +- `tutorial/01-basics/float_literal.kv`——浮点字面量 `3.14`、结果 `6.28`。 +- `tutorial/01-basics/arith.kv`、`tutorial/01-basics/numtypes.kv`——整数字面量与定宽落定。 +- `tutorial/01-basics/strings.kv`——双引号串、`+` 拼接、单字符字符串。 +- `tutorial/11-string/07-multiline.kv`——字符串三形式(`"…"` 跨行、`r"…"`、`r#"…"#`)。 +- `tutorial/01-basics/none.kv`——`None` 空值。 +- `tutorial/01-basics/kv_tree.kv`、`tutorial/03-control/if.kv`——`true`/`false` 布尔字面量。 +"#### -> /lib/kvlang/规范/词法/字面量 +} diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\350\277\220\347\256\227\347\254\246.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\350\277\220\347\256\227\347\254\246.kv" new file mode 100644 index 00000000..19fc8bac --- /dev/null +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\350\277\220\347\256\227\347\254\246.kv" @@ -0,0 +1,96 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/词法/运算符 { + r####"# 运算符 + +本节界定运算符与方向记号的**词法**:有哪些符号、各写作什么字形。其求值与结合语义见 [[layout 语义]]与 [[runtime 语义]]卷。符号表是权威的双向查找表,其余部分不得另行硬编码符号字符串。 + +## 赋值 / 方向记号 + +kvlang 有三种赋值/方向记号,均词法化为 `Arrow`: + +- `=`——写入左侧,等价于 `<-`; +- `<-`——写入左侧(数据从右流向左); +- `->`——写入右侧(数据从左流向右)。 + +``` +x <- 42 +y = x + 8 // = 等价于 <- +42 -> x // 写入右侧 +``` + +`=` 仅为写入记号,kvlang **无**独立的等号赋值语义之外用法;相等比较写作 `==`。 + +## 算术运算符 + +| 字形 | 含义 | 一元 | +|------|------|------| +| `+` | 加 | 是(一元正) | +| `-` | 减 | 是(一元负) | +| `×` | 乘(U+00D7) | 否 | +| `÷` | 除(U+00F7) | 否 | +| `%` | 取模 | 否 | + +**乘法是 `×`、除法是 `÷`**,非 ASCII 的 `*` 与 `/`: + +- `*`(U+002A)**不是**乘号。它在符号表中登记为 `pointer`,非算术运算符。 +- `/`(U+002F)**不是**除号。它只用于绝对路径字面量与注释(`//`、`/*`);出现在其他位置的裸 `/` 不承载算术除法语义。 + +一元 `+`、`-` 作前缀;`√`(U+221A,平方根)亦为一元前缀运算符。 + +## 比较运算符 + +``` +== != < > <= >= +``` + +其中三者另有等价的 Unicode 字形别名,词法上与 ASCII 形式同义: + +- `!=` ≡ `≠`(U+2260) +- `<=` ≡ `≤`(U+2264) +- `>=` ≡ `≥`(U+2265) + +## 逻辑运算符 + +``` +&& || ! +``` + +`!` 为一元前缀(逻辑非)。 + +## 位运算符 + +``` +& | ^ << >> +``` + +分别为按位与、按位或、按位异或、左移、右移。 + +## 优先级 + +中缀运算符的优先级如下(数值越大结合越紧);一元前缀运算符(`+ - ! √`)优先级高于全部中缀。 + +| 运算符 | 优先级 | +|--------|--------| +| `\|\|` | 10 | +| `&&` | 20 | +| `==` `!=`(`≠`) | 30 | +| `<` `>` `<=`(`≤`) `>=`(`≥`) | 40 | +| `+` `-` | 50 | +| `×` `÷` `%` | 60 | +| `<<` `>>` | 70 | +| `&` | 80 | +| `^` | 90 | +| `\|` | 100 | + +## 成员分隔符 `·` + +`·`(U+00B7)是成员/方法分隔符,非算术运算符,词法化为独立的 `Dot` 词法单元,其词法与用途见 [[标识符与路径]]。 + +## 锚例 + +- `tutorial/01-basics/arith.kv`——`+ - × ÷ %` 与一元 `√`(`√(144)`)、`<-`/`=`/`->` 三记号。 +- `tutorial/01-basics/vars.kv`——`<-`、`=` 与 `+`。 +- `tutorial/03-control/if.kv`——比较与逻辑运算符。 +- `tutorial/01-basics/kv_tree.kv`——`!= None` 比较。 +"#### -> /lib/kvlang/规范/词法/运算符 +} diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" new file mode 100644 index 00000000..909af44d --- /dev/null +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" @@ -0,0 +1,61 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/kvspace模型/地址空间 { + r##"# 地址空间 + +kvspace 是 kvlang 的第一性前置概念:它**既是寻址空间也是内存空间**。程序计数器 PC 是一条 kvspace 路径字符串,指令是路径上的值,变量是路径上的值,代码与数据统一在同一棵 KV 树上。本卷其余各章([[寻址与命名]]、[[键系统与数组访问]]、[[指令布局格式]]、[[系统变量]])均以本章界定的地址空间为基础。 + +## 存储铁律 + +kvspace 是文件系统风格的键值抽象。任一条目由 key 与 value 构成: + +- key **必须**是绝对、规范的字符串路径:以 `/` 开头,`/` 分隔层级;不得为相对路径。 +- value **必须**是一个 XValue 序列化后的字节串(TLV 编码,格式见 [[键系统与数组访问]])。 +- **不得**向 kvspace 直接写入裸基础类型字节;所有值必须经 XValue 编解码。违反此铁律的写入,读取方在解码非法字节时行为未定义。 + +目录以尾随 `/` 标记:key `/a/` 是目录(其 value 为 `index`),key `/a` 是普通值。同一路径的有尾斜杠与无尾斜杠形态可独立共存。 + +## 结构域 + +kvspace 的路径中,只有以下前缀由语言核心赋予固定结构语义;其余 `/` 路径全部自由,由用户代码定义,核心不预设 schema。 + +| 前缀 | 语义 | +|------|------| +| `/lib` | 函数与扩展指令的单一事实源:layout 产物(签名 + 指令树)、`.src` 源码副本、扩展 rwir 注册项均落于此 | +| `/vthread` | 虚线程运行时状态:每 vthread 一棵子树,栈帧、PC、状态等随身系统变量暴露执行现场 | +| `/networld` | 与外部世界交互的名册域:本机与外部进程、文件等以 `/networld/{host}/…` 登记,供扩展 rwir 定位与兑现 | + +`/lib` 与 `/vthread` 的前缀常量由运行时与 layout 各自定义(C 运行时 `runtime/src/runtime_internal.h` 的 `LIB_ROOT`/`VTHREAD_ROOT`,Rust layout `layout/src/keytree.rs` 的 `LIB_ROOT`/`VTHREAD_ROOT`)。 + +### `/lib` + +`/lib` 是全局命名空间,无 `import`——lib 树本身即命名空间。`lib name { … }` 块声明包;跨包调用走全路径 `/lib/{pkg}·{func}`。多文件经引导拼接后统一 layout 进 `/lib`,已加载条目去重。函数在 `/lib` 下只读,帧调用经 extindex 复用同一份指令树(见 [[指令布局格式]])。 + +### `/vthread` + +每个虚线程 `vid` 占一棵子树 `/vthread/{vid}/`,借用 Unix `/proc//` 思想:栈帧为其下的 KV 子树,`‥pc`、`‥status` 等系统变量(前缀 `‥`,见 [[系统变量]])暴露执行状态。PC 为路径字符串、帧根落 KV,故进程崩溃后可从 kvspace 续跑。 + +### `/networld` + +`/networld` 是本机在网络命名空间下的身份域,`host` 取裸 hostname。外部进程执行、宿主文件系统读写等**不**经设备文件,而是登记在 `/networld/{host}/…` 下并由扩展 rwir 兑现:例如外部进程的 stdout/stderr 捕获为扩展存储句柄,其逻辑定位符形如 `/networld/{host}/proc/{pid}/{stream}`(`runtime-rs/src/rwir/networld/`)。 + +### 没有设备域 + +kvspace 世界中没有终端、没有设备文件,只有 key 与 value。`print`/`println` 等 I/O 不是地址空间的一个域,也不是核心内建,而是扩展 rwir(签名以 `defrwir` 注册于 `/lib/`,见 [[指令布局格式]]),执行时直接作用于宿主 I/O。 + +## 扩展存储 + +kvspace 元存中的 value 分两类:**内联数据**(基础类型、容器元数据)与**扩展存储句柄**。句柄 value 的 kindexpr 以 `@` 前缀标记(见 [[键系统与数组访问]]),其 body 只记录目标位置描述符,真实字节位于元存之外: + +| 扩展位置 | 典型数据 | +|---------|---------| +| 集群/本机共享内存 | 大张量、激活值 | +| GPU 显存 | 计算张量 | +| 文件系统 / 对象存储 | 模型权重、检查点、数据集、外部进程输出 | + +读取一个 `@` 句柄 value 时,运行时按 body 定位符前缀路由到对应兑现器还原真实字节(`runtime-rs/src/engine.rs`)。 + +## 后端与前端 + +kvspace 的 C ABI 由前端 dispatch 层(`kvspace` 仓 `src/frontend.c`)统一导出,运行期按连接串 scheme 选择后端:`shm://` 走 kvspace-c,`redis`/`fs`/`s3` 等走 kvspace-durable。三后端**必须**实现同一 ABI 与同一线格式(byte-identical),语义一致;一致性由 tutorial 三后端全绿判定(见 [[范围与一致性]])。ABI 符号与 XValue 线格式见 [[寻址与命名]] 与 [[键系统与数组访问]]。 +"## -> /lib/kvlang/规范/kvspace模型/地址空间 +} diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" new file mode 100644 index 00000000..0a08140d --- /dev/null +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" @@ -0,0 +1,78 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/kvspace模型/寻址与命名 { + r##"# 寻址与命名 + +本章界定 kvlang 如何在 [[地址空间]] 上寻址:PC 的形态、变量名与指针的关系、路径分隔符语义,以及访问 kvspace 的 C ABI。 + +## PC 是路径字符串 + +传统 VM 的程序计数器是一维线性整数(内存地址),跳转与调用是整数算术。kvlang 的 PC 是一条 kvspace 路径字符串,跳转与调用是路径拼接与子树导航。 + +| 维度 | 传统 VM | kvlang | +|------|---------|--------| +| PC 类型 | `uint64` / 指令指针 | `string`(KV 路径) | +| 指令获取 | 解引用内存地址 | 读 PC 路径处的 XValue | +| 跳转 | 改寄存器 | PC 置为新路径 | +| 调用 | 压返回地址、跳入口 | 建帧子树、帧根 extindex 指向 `/lib` 指令树 | +| 栈帧 | 连续内存 | `/vthread/{vid}/…` KV 子树 | + +PC 落在 kvspace、帧根落在 kvspace,故执行现场可观测、可崩溃恢复。指令布局与帧机制见 [[指令布局格式]]。 + +## 变量名即指针 + +kvlang 没有取址运算符——**代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)。指令槽里存的从来不是值,而是指针文本;求值恒经一次指针间接。指针有两种形态: + +| 形态 | 写法 | 语义 | 解析 | +|------|------|------|------| +| 相对指针 | 裸标识符 `x` | 相对当前栈帧 | 运行时与帧根拼接 | +| 绝对指针 | `/counter` | kvspace 全局绝对路径 | 零拼接,直接读写 | + +局部变量的名字即相对指针。运行时解析公式: + +``` +绝对路径 = FrameRoot(PC) + "/" + 相对指针 +``` + +`FrameRoot(PC)` 从 PC 截去末尾的 `/[coord]` 指令坐标段即得帧根(`layout/src/keytree.rs` 的 `frame_root`:PC 无 `/[` 坐标段则为非法)。这与 C 的 `rbp + offset` 同构:帧根对应帧基址,相对指针对应栈偏移,绝对指针对应固定地址。 + +`/lib` 下的函数模板中只有相对指针,因此天然可重入:每次调用产生不同的帧根,同一份相对指针拼接出互不干扰的绝对指针——递归与尾调用无需额外机制。 + +**参数不得同名**:变量名即指针,同一帧内两个同名参数将指向同一 kvspace 位置。读参列表内、写参列表内、以及读写列表之间均**不得**同名;layout 静态阻断,运行时兜底。 + +## 路径分隔符 + +kvspace 路径与 XValue 的 kindexpr 共用一套分隔符语义,每个分隔符承载固定含义(常量定义处:`kvspace/include/kvspace/const.h`、`kvspace-durable/src/const.rs`): + +| 分隔符 | 码位 | 语义 | +|--------|------|------| +| `/` | U+002F | 层级;目录以尾随 `/` 标记 | +| `·` | U+00B7 | 用户成员(`obj·field`、`pkg·func`、stringkeymap 元素 `m·[i]`) | +| `‥` | U+2025 | 运行时系统变量前缀(`X/‥pc`,见 [[系统变量]]) | +| `…` | U+2026 | extindex 句柄 body 的首元素前缀 | + +标识符**不得**以 `‥` 开头,故用户代码永远造不出 `‥` 前缀段,系统变量命名空间与用户命名空间零交集(见 [[键系统与数组访问]] 的键形态三分)。 + +## C ABI + +访问 kvspace 的唯一 C ABI 由前端 dispatch 静态导出(`kvspace/include/kvspace/kvspace.h`)。读写采用**借用指针模型**:读返回指向后端常驻空间的指针,调用方不得释放;写返回 body 偏移指针供调用方直接填。核心符号: + +| 符号 | 语义 | +|------|------| +| `kvspaceGet` | 借用读:`*out` 指向后端常驻空间;`resolve=1` 穿透 link;不存在/空值 → `*out=NULL`、返回 0 | +| `kvspaceWriteInPlace` | 就地写:key 已存在、kind 不变、body 长度不变;返回原 box body 偏移指针,违反前置条件即报错,绝不静默重分配 | +| `kvspaceWriteNewPlace` | 新位置写:按 `(kindexpr, body_len)` 分配新 box、写好 head,返回 body 偏移指针;用于新建或 kind/尺寸变化 | +| `kvspaceListLen` | 返回前缀下直接子项计数 | +| `kvspaceListAt` | 取前缀下第 `idx` 个子项名,写入调用方自备缓冲;配合 `kvspaceListLen` 遍历 | +| `kvspaceDel` | 批量删除给定 key 数组 | +| `kvspaceDelTree` | 删除前缀子树 | +| `kvspaceCp` / `kvspaceCpTree` / `kvspaceCpList` | 复制单值 / 子树 / 直接子项 | +| `kvspaceMkindex` | 建目录,带 `capacity` 预留容量 | +| `kvspaceMkindexExt` / `kvspaceRmindexExt` | 建立 / 撤销 extindex 叠加层 | +| `kvspaceClear` | 清空 | +| `kvspaceWatch` | 一次性等待某 key 变为目标值 | + +无句柄的编解码符号(前端静态实现,byte-identical):`kvspaceTlvEncode` / `kvspaceTlvEncodeMode` / `kvspaceDecodeHead`,以及构造器 `kvspaceNewPtr`(存目标完整 kindexpr + 目标 key)、`kvspaceNewChar` / `kvspaceNewBool` / `kvspaceNewInt64` / `kvspaceNewFloat64`。 + +读写各带 `resolve` 参数:`resolve=1` 时透明穿透 `*` 指针(link);`kvspaceListLen`/`kvspaceListAt` 另有 `expand_ext` 参数控制是否展开 extindex 子项。head 线格式与 kindexpr 编码见 [[键系统与数组访问]]。 +"## -> /lib/kvlang/规范/kvspace模型/寻址与命名 +} diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" new file mode 100644 index 00000000..881dfc4e --- /dev/null +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" @@ -0,0 +1,113 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/kvspace模型/键系统与数组访问 { + r##"# 键系统与数组访问 + +本章界定 kvspace 键的三种形态、XValue 的 kindexpr 类型表达与线格式、数组的两种物理存储形态及其访问方式。 + +## 键形态三分 + +任一 key 的形态唯一确定其性质与所有权: + +| 形态 | 例 | 性质 | 所有权 | +|------|----|------|--------| +| `X/名`(`/` + 普通名) | `/vthread/7/[3,0]`、`/lib/f/[1,0]` | 结构:帧、指令槽、目录 | 核心 | +| `X·名`(`·` 中点键) | `/c0·next`、`m·[0]` | 用户数据成员 | 用户 | +| `X/‥名`(`/` + `‥` 名) | `/vthread/7/‥pc` | 系统变量(影子元数据) | 核心 | + +标识符禁以 `‥` 开头,故三类零交集。系统变量清单见 [[系统变量]]。 + +## kind 与 kindexpr + +| 概念 | 内容 | 例 | +|------|------|----| +| **kind** | 基础类型字符串(标量或元素类型),是 kindexpr 的叶子 | `uint8` `int32` `float64` `bool` `char/utf32` `object` `stringkeymap` `rwir` `rwfunc` … | +| **kindexpr** | 完整类型表达式:可选 ref 前缀 + 可选 `[dims]` + kind | `int8` `*int8` `[10]int32` `[256,256]uint8` `@[256,256]uint8` | + +kind 常量集中定义于 `kvspace/include/kvspace/const.h`(C)与 `kvspace-durable/src/const.rs`(Rust),两侧同名同值。剥掉 kindexpr 的所有前缀与 `[dims]` 修饰即得 kind。 + +### kindexpr 文法 + +kindexpr **全前缀**书写,最左符号为最外层构造器,无优先级歧义(对齐 Go/Rust 的 `*[]int`): + +``` +kindexpr ::= [ ref ] [ dims ] kind +ref ::= '*' # 指针(软链接):body = 目标 key 路径 + | '@' # 扩展存储句柄:body = 位置描述符 +dims ::= '[' ']' # 变长一维 + | '[' INT ( ',' INT )* ']' # 定长 / 多维(compact 连续布局) +``` + +ref 前缀、维数与各维长度全部编码进 kindexpr 字符串本身;线格式中**不再**有独立的 ref / ndim / dims 字段。完整签名类型表达式(并集 `A|B`、通配 `any`、动态维 `?`、stringkeymap 键类型)见 [[文法]] 与类型系统卷。 + +## XValueHead 线格式 + +XValue = head + body。head 以 kindexpr 串为唯一类型真相,body 靠偏移与长度定位(`kvspace/include/kvspace/kvspace.h`、`kvspace-c/src/xvalue.h`、`kvspace-durable/src/xvalue.rs`,三处 byte-identical): + +``` +XValueHead = [1B kindexprlen][kindexpr 含 NUL 与 padding][1B ro][4B vid LE][4B raw_len LE] +body = [raw_len B raw] +``` + +| 字段 | 大小 | 含义 | +|------|------|------| +| `kindexprlen` | 1B | kindexpr 槽总长(内容 + 终止 NUL + padding) | +| `kindexpr` | `kindexprlen` B | kindexpr 内容,首个 NUL 终止;含 ref 前缀与 `[dims]` | +| `ro` | 1B | 1=只读,0=可写 | +| `vid` | 4B LE | vthread id(默认 0) | +| `raw_len` | 4B LE | body 字节数 | + +`HeadLen = kindexprlen + 10`;body 起始偏移即 HeadLen。ref、ndim、dims 从 kindexpr 串解析派生:首字节 `*` → 指针、`@` → 扩展句柄、否则内联;其后 `[d0,d1]kind` 承载维数与各维长度(裸 kind 为标量 ndim=0,`[n]kind` 一维,`[d0,d1]kind` 多维)。`char/*` kind 恒为一维序列(含空串、单字符)。因 `kindexprlen` 为含 padding 的槽总长,reshape 时只要新 kindexpr 不超过槽长即可原地改写、不搬 body。None 编码为 NULL / 长度 0。 + +指针(`*`)的 head kindexpr = `*` + 目标完整 kindexpr(含目标自身的 `*`/`@`/`[dims]`),body = 目标 key 路径;由 `kvspaceNewPtr(target_kindexpr, target)` 构造,Set 时据此单跳类型检查。 + +## 数组的两种物理形态 + +理论上的数组(含多维)在 kvlang 有两种物理落盘形态: + +| 形态 | head kind | 触发写法 | 元素位置 | XValue 数 | +|------|-----------|---------|---------|----------| +| **compact** | 元素 kind(`int64`…) | `[1,2,3]`、`[N]T`、`[d0,d1]T` | 连续打包进单个 XValue 的 body | 1 | +| **stringkeymap** | `stringkeymap` | `{v0,v1,…}`、`array·scatter` 等 | 每元素落独立子 key `base·[i]` | N+1 | + +- **compact**:元素连续打包进一个 XValue,`raw_len = ∏dims × 元素字节宽`,head kind 即元素类型、ndim≥1。对齐 C `int[10]`、Go `[10]int`、Rust `[i32;10]`;多维即连续布局的 ndarray/tensor。要求元素定长同类型——含变长字符串字面量的 `[…]` 在 layout 阶段报错。支持 `arr[i]` 随机访问(下标读经 `xv·at` 在 body 内定位),可零拷贝整块读。 +- **stringkeymap**:head kind=`stringkeymap`、ndim≥1,body 只记形状;每个元素是独立子 key,成员名为**坐标段**。变长、可增长、允许变长元素——字符串数组、可追加数组走此形态。stringkeymap **必须** ndim≥1(无维度的键值容器应为 `object`),且成员名**必须**是坐标段(`kvspace-durable/src/const.rs` 的 `ERR_MAP_NDIM`、`ERR_MAP_COORD`)。 + +## 坐标段 + +stringkeymap 元素的成员名是坐标段,物理 key 形如 `m·[i]`(一维)或 `m·[i,j]`(多维)——`·` 后紧跟方括号坐标,**不是** `m·0` 这类裸后缀。坐标段格式为 `[s0,s1,…]`:十进制、逗号分隔、无空格(`kvspace-durable/src/coord.rs` 的 `format_coord`)。 + +- 结构判定 `is_coord`:`[` 开头、`]` 结尾、内部不含嵌套 `[`/`]`;判定不要求整数(允许含点或字符串坐标)。 +- 排序 `cmp_coord`(row-major):坐标段恒排在非坐标段之前;两个可按整数解析的坐标段按数值升序,否则字典序。 +- 访问:源码 `m·[i]` 对散 key 元素走 `kv·get`(member 名 `[i]`);compact 的 `arr[i]` 走 `xv·at`。二者由括号与形态区分。 + +## 字面量括号即形态 + +| 字面量 | 形态 | 约束 | +|--------|------|------| +| `[1, 2, 3]` | compact(head kind=元素类型) | 元素须定长同 kind;含变长字符串成员时 layout 报错 | +| `{1, 2, 3}` | stringkeymap(散 key) | 变长 / 可增长;字符串数组必须走此形式 | +| `{k = v; …}` | object 或 stringkeymap(map) | 由 `=` 键值对与散 key 数组区分;空 `{}` 须带类型标注 | + +## 形态转换 + +| rwir | 方向 | 语义 | +|------|------|------| +| `array·scatter(arr) -> dst` | compact → stringkeymap | 连续数组拆成 `dst·[0]…dst·[N-1]` 独立 key | +| `array·compact(arr) -> dst` | stringkeymap → compact | 读散 key 打包成连续数组 | +| `array·append` / `array·slice` | 变长 | 作用于 compact 时先自动 scatter | + +## `@` 扩展句柄 + +| ref | 语义 | body | +|-----|------|------| +| 无 | 内联值 | 数据本体 | +| `*` | kvspace 内软链接 | 目标 key 路径 | +| `@` | 扩展存储句柄 | 元存外位置描述符 | + +`@[256,256]uint8` 表示 256×256 uint8 张量的句柄,数据在 SHM/GPU/文件,body 记位置。`@` 只组合 `kind` 与 `[dims]kind`(compact 形态),外部分散数组无意义、拒绝。读取时按 body 前缀路由兑现(见 [[地址空间]] 扩展存储)。 + +## memindex:定宽目录矩阵 + +目录(`index`)可携带定宽矩阵形态用于增长型容器:body 记 `dims=[len, cap, M]`,`M` 向上 8 对齐;`len` 为当前项数、`cap` 为预留容量、`M` 为行宽。`kvspaceMkindex` 带 `capacity` 参数、构造器 `kvspaceXvalueNewIndexGrow(children, count, cap_hint, m_hint)`(`kvspace-c/src/xvalue.h`)据此保留容量与行宽,使增删可就地覆写、不重分配。 +"## -> /lib/kvlang/规范/kvspace模型/键系统与数组访问 +} diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" new file mode 100644 index 00000000..6bdd1d45 --- /dev/null +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" @@ -0,0 +1,69 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/kvspace模型/指令布局格式 { + r##"# 指令布局格式 + +本章界定函数经 layout 后在 `/lib` 下的 KV 布局:指令如何以坐标键落盘、签名与命名参数如何编码、调用如何经 extindex 复用指令树、参数如何经指针链解析。 + +## 空间布局,非线性字节码 + +传统 VM 编译产线性字节码,调用即压返回地址后跳入口。kvlang 的 layout 不产线性序列,而是**空间布局**:每条指令展开为一组 `[s0,s1]` 坐标键,可逐槽 `kv·get`/`kv·list` 寻址,无需反汇编器。函数体永不被复制——调用时经 extindex 令帧根指向 `/lib` 下同一份指令树(见下 [[指令布局格式]] 调用机制)。 + +## 坐标键 `[s0,s1]` + +函数 `/lib/{pkg}·{name}/` 目录下,每个槽以 `[s0,s1]` 坐标键寻址。约定: + +- `s0` = 行号:`[0,·]` 为签名行,`[1,·]` 起为指令行(指令 0 落 `[1,·]`)。 +- `s1` = 列:`0` 为 opcode 槽,负号 `-j` 为第 j 个读槽,正号 `+j` 为第 j 个写槽。 + +入口 PC 为 `…/[1,0]`(`layout/src/keytree.rs` 的 `is_entry_pc`:PC 以 `/[1,0]` 结尾即入口)。 + +### 签名行 + +- `[0,0]` = 函数签名槽,kind = `rwfunc`,body = `[2B nr][2B nw][sig]`(读参数、写参数计数 + 签名类型串)(`layout/src/kvkind.rs`、`layout/src/code.rs`)。 +- 命名参数 → 槽映射:`/lib/{pkg}·{name}/{param}` 是一个 char/utf32 值,内容为该参数的槽坐标串(如 `x` → `"[0,-1]"`、返回值 `R` → `"[0,1]"`)。读参映射到 `[0,-j]`、写参映射到 `[0,+j]`。 + +### 指令行 + +以 `id_val(x:int64) -> (R:int64) { int64·add(x, 0) -> R }` 为例,`/lib/id_val/` 下: + +``` +[0,0] rwfunc:(nr=1,nw=1) int64 | int64 ← 签名 +x char/utf32:[0,-1] ← 命名读参 → 槽 +R char/utf32:[0,1] ← 命名写参 → 槽 +[1,0] rwir|rwfunc:int64·add ← 指令0 opcode +[1,-1] rwir:x ← 指令0 读槽1 +[1,-2] int64:0 ← 指令0 读槽2(内联字面量) +[1,1] rwir:R ← 指令0 写槽1 +``` + +opcode 槽 kind 为 `rwir|rwfunc`(body 记 nr/nw + opcode 名)。读/写槽的值有两类:`rwir:name` 是对变量的引用(存名字文本,即相对指针),或内联字面量(如 `int64:0`、`char/utf32:"…"`)。opcode 槽永不存变量引用,故值拷贝 `=` 与函数调用 `call` 在 KV 层无歧义。 + +## 调用:extindex 复用指令树 + +调用一个函数时,运行时**不**拷贝指令,而是为本次调用建帧子树,令帧根成为指向 `/lib/{pkg}·{name}/` 指令树的 extindex 叠加层,再把实参 / 结果地址写进帧根下的 `[0,±j]` 槽: + +- `/lib` 下只有命名参数键(如 `x`、`R`),坐标键 `[0,-j]` / `[0,+j]` 不存在;故运行时向 `frameRoot/[0,±j]` 写入不与只读指令树冲突。 +- 所有帧共享 `/lib` 下同一份指令树,零拷贝;帧根下叠加各自的实参槽与局部变量。 + +崩溃恢复由此自然成立:PC 是路径字符串、帧根落 KV、返回点落 KV——进程重启后可从 kvspace 续跑。 + +## 参数解析:指针链 + +指令读到 `rwir:x` 时,`x` 是相对当前帧的名字。运行时经指针链解析到实参真实位置: + +``` +1. 读 frameRoot/x → "[0,-1]" 名字 → 槽坐标 +2. 读 frameRoot/[0,-1] → 实参 key 路径 槽 → 实参地址 +3. 读该路径 → 值 解引用 +``` + +第 1 跳的 `frameRoot/x` 由 `/lib` 指令树经 extindex 透出(layout 写入、只读),第 2 跳的 `frameRoot/[0,-1]` 由运行时在调用点写入。读参地址可指向调用方值以实现零拷贝重定向(见 [[系统变量]] 的 `‥rparam` / `‥wparam`)。 + +## init 与标签 + +- lib 内的裸指令收集为隐式 `init` 函数(无 `init` 关键字),同样以上述布局落 `/lib/{pkg}·init/`。 +- 具名作用域(scope)的标签落 `/lib/{pkg}·{name}/‥labels/{label}` → 指令序号(`layout/src/code.rs`、`layout/src/keytree.rs`)。 + +签名类型表达式文法见 [[文法]];帧的系统变量见 [[系统变量]];坐标键与 kindexpr 的分隔符语义见 [[键系统与数组访问]]。 +"## -> /lib/kvlang/规范/kvspace模型/指令布局格式 +} diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\347\263\273\347\273\237\345\217\230\351\207\217.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\347\263\273\347\273\237\345\217\230\351\207\217.kv" new file mode 100644 index 00000000..51b64eb3 --- /dev/null +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\347\263\273\347\273\237\345\217\230\351\207\217.kv" @@ -0,0 +1,53 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/kvspace模型/系统变量 { + r##"# 系统变量 + +运行时为它管理的对象附带**系统变量**(影子元数据),以 `{对象key}/‥{名}` 形式存放:宿主对象 `/` 下探一层、键名以 `‥`(U+2025)开头。标识符禁以 `‥` 开头,故所有 `‥` 前缀键均为核心保留,用户代码无法直接读写——类比 Unix 隐藏文件,默认视图不显示、引擎可见。 + +系统变量(`X/‥名`,`/` + `‥` 前缀)与用户成员(`X·名`,`·` 中点键)正交,零交集(见 [[键系统与数组访问]] 键形态三分)。生命周期绑定:`X/‥*` 落在 X 的 `/` 子树内,删除 X 子树即连带清除其全部系统变量。 + +## vthread 系统变量 + +宿主 = `/vthread/{vid}`(常量:`runtime/src/keytree.c`、`layout/src/keytree.rs`): + +| 键 | 语义 | +|----|------| +| `‥pc` | 当前执行 PC(绝对路径字符串) | +| `‥status` | 运行状态:`init` / `running` / `wait` / `paused`;进入终态时删除并 Notify 返回值 | +| `‥status/msg` | 状态附带消息;错误时形如 `‥error/msg` 承载错误文本 | +| `‥debugger` | 调试控制:空为正常,`paused` 为暂停;`debugger()` 内建写此键 | +| `‥ctime` | 创建时刻 | + +## 帧系统变量 + +宿主 = 帧根(rwfunc 帧或 scope 帧的根路径): + +| 键 | 语义 | +|----|------| +| *(帧根 extindex)* | rwfunc 帧根经 extindex 指向 `/lib/{pkg}·{name}/` 只读指令树;scope 帧不建 extindex | +| `‥lib` | rwfunc 帧的 lib 路径,用于识别 rwfunc 帧边界 | +| `‥callpc` | 帧内执行进度(每 op 更新;scope 帧重入亦更新) | +| `‥returnpc` | 返回地址(帧创建时固化;scope 帧仅首次设置,重入不覆写) | +| `‥ro` | 只读参数名单,写槽检查用 | +| `‥rparam/{name}` | 读参重定向:存调用方值的绝对路径,读参从此路径直读(零拷贝) | +| `‥wparam/{name}` | 写参重定向:存调用方写目标的绝对路径,写参直写此路径 | + +调用点如何写实参 / 结果槽、如何经指针链解析读到重定向路径,见 [[指令布局格式]]。 + +## 函数标签 + +具名作用域的标签不落在帧上,而落在函数的 `/lib` 定义处:`/lib/{pkg}·{name}/‥labels/{label}` → 指令序号(`layout/src/keytree.rs`、`layout/src/code.rs`)。 + +## 语法层保留名 `._` + +`._` 是源码层的丢弃槽占位符:写目标为 `._` 时不落 kvspace(帧槽键构造遇此名返回空路径)。它是语法占位符,**不**是 `‥` 系统变量,不落盘。 + +## `debugger()` + +`debugger()` 内建对齐 V8/TypeScript 的 `debugger;` 语句:源码内联暂停点。非调试模式下为 no-op;调试模式下将 `‥status` 置 `paused`,由外部驱动改回 `running` 恢复执行。 + +## 域与变量之别 + +注意区分:[[地址空间]] 的结构**域**(`/lib`、`/vthread`、`/networld` 顶层树)与对象随身的 `‥` 系统**变量**是两种机制。域是路径前缀赋予的固定结构语义,系统变量是任一对象 `/` 子树内的影子元数据。 +"## -> /lib/kvlang/规范/kvspace模型/系统变量 +} diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" new file mode 100644 index 00000000..7bc689fc --- /dev/null +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" @@ -0,0 +1,122 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/类型系统/种类与定宽类型 { + r##"# 种类与定宽类型 + +kvlang 是**严格定宽类型语言**。每个变量、参数、返回值都有确定的种类(kind);无无类型变量,运行时种类不隐式改变。类型信息随值自描述:一个 XValue 的种类由其 head 中的 kindexpr 表达(见 [[kindexpr签名类型表达式]] 与 [[kvspace模型]] 的 XValue 编码)。 + +## 种类(kind) + +**种类**是值的运行时类别。种类字符串是 kindexpr 的基(base)部分(见 [[kindexpr签名类型表达式]])。 + +### 定宽数字种类 + +kvlang 的数字种类**必须携带精确位宽**: + +| 类别 | 种类 | +|------|------| +| 有符号整数 | `int8` `int16` `int32` `int64` | +| 无符号整数 | `uint8` `uint16` `uint32` `uint64` | +| IEEE 754 浮点 | `float32` `float64` | + +整数按小端补码编码,浮点按 IEEE 754 编码。 + +**铁律——无家族简写**。`int`、`uint`、`float`、`num`、`char` 这类不含位宽/编码的简写**不是**合法种类,在任何类型标注中均**不得**出现。位宽与字符编码是**开放集合**(未来可扩 `int4`、`fp8`、`fp16` 等),封闭的家族枚举必然漏项;多态**必须**靠 [[kindexpr签名类型表达式]] 的显式 `|` 枚举表达(如 `int8|int16|int32|int64`)。 + +### bool 与字符种类 + +| 种类 | 说明 | +|------|------| +| `bool` | 1 字节:`0`=false、`1`=true | +| `char/utf32` | 码点序列,4B×N,定宽、可索引;**字符串字面量的默认种类** | +| `char/ascii` | ASCII 字节序列,1B×N,定宽、可索引 | +| `char/utf8` | UTF-8 字节序列,1B×N,变宽、**禁索引**(仅存储与交换) | + +字符三种编码的判定为前缀相等:某种类是字符种类当且仅当它以 `char/` 起始。定宽编码(`utf32`、`ascii`)**必须**支持 O(1) 码点索引;变宽编码 `utf8` 的按码点索引操作(`string·char`、`s[i]` 等)**必须**报 TypeError。单个字符标注为 `char/<编码>`(标量),字符串标注为 `[]char/<编码>`(序列);字符种类的值恒为一维序列。 + +### 容器与结构种类 + +| 种类 | 说明 | +|------|------| +| `object` | 异构命名成员容器(类 struct/record),成员经 `·` 访问 | +| `stringkeymap` | map 容器,kindexpr 为 `key·value`(如 `[]char/utf8·int64`) | +| `struct` | 结构原型实例的种类(见 [[容器]] 与结构声明) | +| `index` | 目录/成员索引(memindex;容器的成员名索引即此种类) | +| `extindex` | 扩展索引,以 kindexpr 前缀 `@` 标记 | + +容器的物理组成(值 + memindex)见 [[容器]]。 + +### 时间种类 + +| 种类 | 说明 | +|------|------| +| `time` | 时刻,由 `time·now()` 等产生 | +| `duration` | 时长,由 `time/duration·*` 产生 | + +`time`/`duration` 是不透明标量种类,其运算由 time 标准库提供,字节布局不由本卷规定。 + +### 代码种类 + +下列种类描述 KV 树中的代码与目录节点(见 [[kvspace模型]] 的指令布局):`rwir`(指令槽文本引用)、`rwfunc`(函数引用,并作用户函数定义的签名槽 kind)、`scope`(词法作用域帧目录)。扩展算子定义所用的 `defrwir` 是**内部种类**,由 layout 落盘、runtime 消费,**不得**出现在用户书写的类型标注中;用户函数的定义与栈内调用统一用 `rwfunc`,不再有独立的 defrwfunc。(`def*` 内部种类仅保留 defrwir——扩展算子声明,并预留未来调度用途。) + +### None 与 ptr 不是种类 + +- **None** 不是种类:它是 kindexpr 为空的 XValue(空字节)。任何有名变量都有地址、都有 XValue;未赋值即 None。None 参与算术、比较、分支条件、类型构造一律 TypeError(见下文与 [[runtime语义]])。 +- **ptr(软链接)** 不是种类:它是 kindexpr 的前缀 `*`。ptr 的 head kindexpr 为 `*` 加目标的完整 kindexpr,body 存目标 key 路径(见 [[容器]])。 + +> 前缀 `*`(ptr)与 `@`(extindex)是 head 编码层的记法,**不属于**类型表达式文法:类型标注里不得书写 `*int64` 或 `@int64`(见 [[kindexpr签名类型表达式]])。 + +## 构造器兼转换器 + +十个定宽数字种类名与三个字符编码名**既是构造器也是转换器**——同名一元调用把实参转换为该种类: + +```kv +f = float32(3) // kind=float32,值 3.0 +i <- int8(0.1) // 0(float→int 向零截断) +int8(300) -> w // 44(窄化 = 补码回绕) +t <- char/utf32(s) // 变宽 utf8 转定宽 utf32(转后可索引) +u <- char/ascii(t) // 非 ASCII 码点 → TypeError +``` + +转换规则(对齐 C / Go / Rust `as`): + +| 规则 | 语义 | +|------|------| +| float → int | 向零截断(`int32(3.9)`=3、`int32(-2.7)`=-2、`int64(0.5)`=0) | +| 整数窄化 | 补码回绕(`int8(300)`=44、`uint8(-1)`=255、`int16(70000)`=4464、`int32(2147483648)`=-2147483648) | +| float32 精度 | 收窄至单精度(`float32(3.141592653589793)`=3.1415927、`float32(16777217)`=16777216.0) | +| None 输入 | TypeError(`int64(None)` 报错,不得静默产生 0) | + +构造器接受字面量与变量表达式(`42.9 -> x; int8(x)`)。种类构造的结果 XValue 以该种类名为 kindexpr 落盘,精度信息随值保留。 + +## 数值运算域 + +1. **同种类算术产生同种类结果**,溢出按补码回绕:`int8(127)+int8(1)`=-128、`uint8(255)+uint8(1)`=0、`int32(100)×int32(100)`=10000(kind 保持 `int32`)。float32 运算不升 float64:`float32(16777216)+float32(1)`=16777216.0。 +2. **混合宽度整数向更宽种类提升**:`int8(100)×int16(2)`=200(结果 `int16`);`int8(7)%int16(3)`=1(结果 `int16`)。 +3. **任一侧浮点则提升为浮点**:`int8(120)÷float32(10)`=12.0(结果 `float32`);两整数 `÷` 为整除(`int8(120)÷int8(10)`=12)。 +4. **无符号取负** `-(uint8 值)` TypeError(对齐 C 警告 / Rust、Go 编译错误)。 +5. **bool 不参与算术**:`true + false` TypeError。 +6. **None 参与算术** TypeError;**None 参与分支条件** TypeError。 +7. **跨种类比较** TypeError(`int64(5) == "hello"` 报错);数值种类之间可跨宽度比较(`3 == 3.0` 为 true)。 + +## bool 铁律 + +`bool` 值**只能**为 `true`/`false`,**禁止**一切隐式布尔化: + +| 输入 | kvlang | +|------|--------| +| `true` / `false` | 合法 | +| `0` / `1` 整数 | TypeError——须显式写 `!= 0` | +| 非空字符串 | TypeError——须显式写 `!= ""` | +| None | TypeError | + +分支条件(`if`/`while`/`br`)的条件槽**必须**是 `bool`。强制显式比较使控制流走向可被静态判定,不依赖运行时种类。 + +## 锚例 + +- 定宽构造与转换、float→int 截断、窄化回绕:`tutorial/01-basics/cast.kv`、`tutorial/01-basics/numtypes.kv`。 +- 算术保宽与混合提升:`tutorial/01-basics/type_narrowing.kv`。 +- 字符编码与索引:`tutorial/11-string/05-encodings.kv`、`06-convert.kv`、`02-char-ord.kv`。 +- 时间种类:`tutorial/01-basics/time.kv`、`tutorial/13-stdlib/time/`、`13-stdlib/duration/`。 +- 类型错误(bool 算术、跨种类比较、无符号取负、None、compact 变长串):`tutorial/error_cases/type_error/`、`error_cases/none_type_error/`。 +"## -> /lib/kvlang/规范/类型系统/种类与定宽类型 +} diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-kindexpr\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-kindexpr\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" new file mode 100644 index 00000000..6f930709 --- /dev/null +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-kindexpr\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" @@ -0,0 +1,104 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/类型系统/kindexpr签名类型表达式 { + r##"# kindexpr 签名类型表达式 + +**类型表达式**是函数与扩展算子签名中参数、返回值的类型标注语法。它既供人和工具读写,也逐字节落盘为运行时匹配的依据。同一套表达式贯穿 layout(静态校验)与 runtime(值匹配),故本卷统称 **kindexpr**。 + +完整权威文法见 [[文法]](附录)的「类型表达式」小节;本章只界定其语义。 + +## 归属与落盘 + +| 归属 | 存放位置 | 种类 | +|------|---------|------| +| 用户函数签名 | `/lib/·` | `rwfunc` | +| 扩展算子签名 | `/lib/` | `defrwir` | +| native 算子签名 | C 注册表(不落盘) | —— | + +**铁律**:`rwfunc`/`rwir` 每个参数落盘的 kindexpr 与源码里的类型标注**逐字节相同**(同一文法,含 `...`)。签名定义体(`char/utf8` 值)布局为: + +``` +[nr : u16 LE][nw : u16 LE][读参 kindexpr × nr,再 写参 kindexpr × nw,全部以 "\n" 连接] +``` + +native 算子的 kindexpr 内联在 C 注册表中,是唯一权威来源,运行时匹配**直接读 C 表、不回查 kvspace**;数值多类型算子在 C 表中融合为单条(如 `add(a:int8|…|float64, b:…)`)。 + +## 强制类型标注 + +`def`(`rwfunc`/`rwir`)签名中每个参数与每个返回值**必须**声明类型(`name:type_expr`)。缺标注的签名**拒绝装载**——layout 在语法检查期报错,指出该参数/返回值无类型标注。类型标注须通过 kindexpr 合法性校验(拒绝非种类名,见下)。 + +## 文法与合法性 + +类型表达式的构成(详见 [[文法]]): + +- **并集** `A|B`——以 `|` 拆分为若干 atom,表「A 或 B」。多态**必须**用显式并集表达。 +- **atom** = 形状(shape)或 map 表达式(mapexpr)。 +- **shape** = 可选维度 `dims` 后跟 `any` 或精确种类名。 +- **dims** = `[]`(无内容)或 `[dim,dim,…]`;`dim` 为整数或 `?`(动态维)。 +- **mapexpr** = `key·value`,`value` 递归为完整类型表达式(故 map 可无限嵌套)。 +- **key** = `[]char/<编码>`(字符串键)或 `[scalar,…]`(标量元组键);`scalar` 限 `bool` 与十个定宽数字种类。 +- **any** = 通配,匹配任意种类;是**唯一**简写。 +- **structref** = 以 `/` 起始的原型路径(如 `/lib/Point`),作为 atom 标注结构类型(见 [[容器]] 的 struct)。 +- **变参** `...`——见下。 + +**合法性校验**(layout 与 runtime 一致):每个 atom 的基须为 `known` 种类名或 `any`;键须为 `[]char/<编码>` 或全标量元组。非法示例及拒因: + +| 非法 | 拒因 | +|------|------| +| `int` `float` `char` | 家族简写,非种类名 | +| `*int64` `@int64` `int64*` | ptr/extindex 前缀不属类型表达式 | +| `char/utf8·int64` | map 键未加方括号 | +| `[]int32·int64` | map 字符串键的编码非 `char/*` | +| `[?]·int64` | map 键含维度 | +| `[foo,int32]·int64` | 元组键含非标量元素 | +| 裸 `[]` / 裸 `[?]` | 无基种类 | + +`defrwir` 是内部落盘种类,**不得**作为类型标注书写;`rwfunc` 兼作用户函数定义的签名槽 kind,不再有独立的 defrwfunc(见 [[种类与定宽类型]])。 + +## 变参 `...` + +变参尾缀 `...` **仅**允许加在**末位读参**的类型表达式上(如 `A:any...`、`A:int64|float64...`),表「0..N 个同型实参」,用于 `print`/`println`/`min`/`max` 等 arity 开放的算子。 + +- 非末位参数带 `...`:装载期错误。 +- 写参(返回值)带 `...`:装载期错误。 + +匹配时,变参把所有尾随实参逐个按去掉 `...` 后的类型表达式判定。 + +## 匹配语义 + +一个值(种类 `k`、维数 `n`、维列表 `d`)匹配类型表达式 `E`:按 `|` 拆成若干 atom,**任一** atom 命中即匹配。单个 atom 的判定: + +1. atom 为 `any` → 命中。 +2. atom 含 `·`(mapexpr)→ 命中当且仅当 `k == stringkeymap`。键/值结构在**匹配期不再校验**(已在装载期校验合法性)。 +3. atom 有 `[` 前缀(shape)→ 先按维度段做形状匹配,再以剩余基种类匹配 `k`。 +4. atom 无 `[` 前缀(标量)→ 命中当且仅当 `n == 0` 且基种类等于 `k`(`any` 除外走精确字符串相等)。 + +**形状匹配**(维度段 → `n`,`d`): + +| 维度段 | 命中条件 | +|--------|---------| +| 空(`[]`)或 `[?]` | 恰 `n == 1`,长度任意 | +| `[d0,d1,…]` | 逗号项数 `== n`,且逐维:`?` 跳过、否则 `d[i] == di` | + +`[]` **等价** `[?]`——均为「恰一维、任意长」。字符串标注 `[]char/<编码>` 即一维字符序列。 + +> 规范注记:`[]` 恒为「恰一维」是 normative 规则。runtime 匹配器(`runtime/src/kindexpr.c`)已一致;layout 匹配器(`layout/src/kindexpr.rs`)当前放宽为「任意 rank ≥1」,为已裁决待修的实现偏差,须收敛至「恰一维」。 + +任一失配即 TypeError:装载期由 layout 报诊断,运行期写 vthread 错误并停机。 + +## 多态派发 + +- **native 算子**(如 `+`)内建多态,签名只做类型检查;分派在 C 算子内部按实参种类完成。 +- **扩展算子**(rwir,如 `numpy·add`)经扩展运行时拿到实参实际种类,按精确种类分派;高维形状由扩展自行处理。 +- **用户函数**(rwfunc)以并集声明接受集,函数体内用种类分支处理各分支。 + +## 语法冲突规避 + +签名以 `,` 分隔参数,形状维度段内也用 `,` 分隔维。签名解析器**跟踪方括号深度**:见 `[` 进形状态、见 `]` 退出;形状态内的 `,` 归维、态外的 `,` 归参数。类型表达式内不出现 `(` `)` `:` `->` 空格,故与签名外层结构无歧义。 + +## 锚例 + +- 标量并集、多维形状、动态维、字符串标注:`tutorial/10-types/`(`01-typed-map.kv`~`05-tuple-key.kv`)。 +- 嵌套 mapexpr 与元组键落盘 round-trip:`tutorial/10-types/04-nested-type.kv`、`05-tuple-key.kv`。 +- 变参 `...`:`print`/`println`/`min`/`max` 全 tutorial 广泛使用。 +"## -> /lib/kvlang/规范/类型系统/kindexpr签名类型表达式 +} diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\346\225\260\347\273\204\345\275\242\346\200\201.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\346\225\260\347\273\204\345\275\242\346\200\201.kv" new file mode 100644 index 00000000..d0e7781f --- /dev/null +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\346\225\260\347\273\204\345\275\242\346\200\201.kv" @@ -0,0 +1,109 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/类型系统/数组形态 { + r##"# 数组形态 + +kvlang 的数组有**两种物理形态**:**compact**(连续打包进单个 XValue)与 **stringkeymap**(散 key,每元素独立落库)。两形态由字面量括号选定,访问算子不同,但都被 `ndarray·*` 元数据算子统一观测。 + +## 括号规约 + +| 字面量 | 形态 | 落库 | 约束 | +|--------|------|------|------| +| `[e0, e1, …]` | compact | 元素连续打包进单个 XValue,head 种类=元素种类 | 定长、同种类;元素**不得**为变长(字符串字面量禁入) | +| `{v0, v1, …}` | stringkeymap | 每元素落 `base·i` 独立子 key,容器值 head 种类=`stringkeymap` | 变长/可增长;字符串数组等变长集合用此形式 | + +- compact 字面量降级为 `array(…)` 构造。变长字符串元素进 compact `[…]` 在 layout 语法检查期报错(`compact array [...] cannot hold variable-length string element`)。 +- stringkeymap 字面量降级为 `map(…)` 构造,只作赋值右值或 `for-in` 源。 + +## compact 形态 + +compact 数组是**单个 XValue**:head 种类为元素种类,维度 `dims` 落在 head 的 kindexpr 里,body 是连续的定宽元素字节。 + +```kv +a:[]int64 = [10, 20, 30, 40] // head kindexpr = [4]int64,body = 4×8 字节 +``` + +- head 种类 = 元素种类(此例 `int64`),**非** `array`;kindexpr 形如 `[4]int64`(见 `tutorial/04-ndarray/xv_meta.kv`)。 +- 字符串是 compact 的字符序列:`s:char/utf8 = "hi"` 的 kindexpr 为 `[2]char/utf8`。单个字符串是 compact;**字符串的数组**是变长集合,必须 stringkeymap。 + +### compact 元素访问 + +下标 `a[i]` 是 compact 元素访问:读降级为 `xv·at`,写(`a[i]=v` 或 `v -> a[i]`)降级为 `xv·set`。 + +```kv +a[1] -> e // 等价 xv·at(a, 1) -> e +a[2] = 99 // 等价 xv·set(a, 2, 99) -> a +99 -> a[0] // 右箭头下标写,等价 xv·set(a, 0, 99) -> a +``` + +`xv·at` / `xv·set` **仅接受 compact 数组**(维数非 0):对 stringkeymap 或标量报 TypeError。索引个数**必须**等于维数,按 row-major 折算扁平偏移;越界报 IndexError。写回保持 dims 不变。 + +### 多维 compact(tensor) + +多维 compact 由 `xv·reshape` 从一维铺开: + +```kv +m = xv·reshape([1, 2, 3, 4], 2, 2) // dims = [2,2] +7 -> m[1, 0] // 多维下标写 +m[0, 1] -> x // 多维下标读 +``` + +多维下标个数须等于维数(此例 2),按 row-major 折算(见 `tutorial/04-ndarray/subscript_write.kv`)。 + +### head 观测与重解释 + +| 算子 | 语义 | +|------|------| +| `xv·kindexpr(a)` | 返回 head 的 kindexpr 串(如 `[4]int64`) | +| `xv·bodylen(a)` | 返回 body 字节数 | +| `xv·reinterpret(a, "[]uint8")` | 原样保留 body 字节,只替换 kindexpr(`[3]int64` 24 字节 → `[24]uint8`) | + +## stringkeymap 形态 + +stringkeymap 数组的**容器值**是一个 head 种类为 `stringkeymap` 的 XValue(body 空,成员数落 head 的 dims),**每个元素**是独立子 key `base·i`: + +```kv +nums = {10, 20, 30, 40} // 每元素落 nums·0 … nums·3 +for (x in nums) { … } // 遍历散 key 元素 +names = {"apple", "banana", "cherry"} // 变长字符串数组必须 stringkeymap +``` + +散 key 元素以坐标段 `base·[i]` 访问(经 `kv·get`),或以 `for-in` / `kv·listlen` / `kv·listn` 遍历。坐标段支持多值键(含小数):`geo·[39.9,116.4] <- "Beijing"`,物理以字符串格式落 key(见 `tutorial/04-ndarray/geo_coord.kv`)。 + +## 两形态互转 + +| 算子 | 语义 | +|------|------| +| `array·scatter(a)` | compact → stringkeymap(散 key) | +| `array·compact(b)` | stringkeymap → compact | + +字面量初始化默认按括号定形态;`scatter`/`compact` 显式转换(见 `tutorial/04-ndarray/separated.kv`)。 + +## ndarray 元数据算子 + +三个算子统一观测数组形状,对两形态均适用: + +| 算子 | 语义 | +|------|------| +| `ndarray·numel(a)` | 元素总数(compact 读 head array_len;stringkeymap 读成员数) | +| `ndarray·dim(a)` | 维数(head ndim) | +| `ndarray·shape(a)` | 各维长度,返回一维 `int64` compact 数组 | + +```kv +a:[]int64 = [10, 20, 30, 40] +ndarray·numel(a) -> n // 4 +ndarray·dim(a) -> d // 1 +ndarray·shape(a) -> s // [4];s[0] = 4 +``` + +## 锚例 + +- compact 建/读/写/求和:`tutorial/04-ndarray/continuous.kv`。 +- head 种类与 kindexpr、reinterpret:`tutorial/04-ndarray/xv_meta.kv`、`xv_reinterpret.kv`。 +- numel/dim/shape、xv·at/set:`tutorial/04-ndarray/xv_shape.kv`。 +- 多维下标写、reshape:`tutorial/04-ndarray/subscript_write.kv`。 +- stringkeymap 字面量与遍历:`tutorial/04-ndarray/sparse_literal.kv`、`string_array.kv`。 +- 两形态互转:`tutorial/04-ndarray/separated.kv`。 +- 多值坐标段:`tutorial/04-ndarray/geo_coord.kv`。 +- 括号规约错误(compact 容变长串):`tutorial/error_cases/type_error/compact_string_array.kv`。 +"## -> /lib/kvlang/规范/类型系统/数组形态 +} diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\345\256\271\345\231\250.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\345\256\271\345\231\250.kv" new file mode 100644 index 00000000..c5be65b8 --- /dev/null +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\345\256\271\345\231\250.kv" @@ -0,0 +1,109 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/类型系统/容器 { + r##"# 容器 + +kvlang 的复合命名数据只有两种容器种类:**object**(异构命名成员)与 **stringkeymap**(map)。此外 **ptr**(软链接)是指向另一 key 的值形态,**struct** 是由声明原型克隆的 object 式容器。kvlang **没有** `dict` 种类。 + +## 容器 = 值 + memindex + +容器在 kvspace 中分两部分落库,`·`(U+00B7 中点)是唯一的 memindex 标记: + +- **容器值**:落在裸 base 键,body 空,保留 dims/只读位/vid,种类为 `object` 或 `stringkeymap`。 +- **成员**:`base·name` 是独立子 key,各自持成员值。 +- **memindex**:落在 `base·` 键(尾中点),种类为 `index`,其 body 是成员名索引矩阵,是成员枚举的权威来源。 + +memindex 的线格式为 dims = `[len, cap, M]` 的矩阵:`len` = 有效成员数、`cap` = 预留行数(`cap ≥ len`,满则翻倍扩容)、`M` = 成员名 UTF-8 字节最大长向上 8 对齐后的**行宽**;body 为 `cap × M` 字节,前 `len` 行是有序成员名(NUL 补齐),其余行全 NUL。容量内增删成员 body 长恒定、就地覆写。`M` 是行宽(行 stride),`cap` 是可翻倍的容量。 + +## object + +**object** 是异构命名成员容器(类 struct/record),成员名固定写在源码。 + +```kv +rec:object = {} // 空容器字面量必须带类型标注 +rec·name = "kv" // 成员写:写槽是完整成员键 rec·name +rec·ver = 1 +rec·ver -> v // 命名成员读 +``` + +对象字面量 `{k1=v1; k2=v2}`(key 为静态标识符)降级为 `obj(…)` 构造。 + +## stringkeymap + +**stringkeymap** 是一等 map 类型,kindexpr 为 `key·value`(见 [[kindexpr签名类型表达式]]):`[]char/utf8·int64` 即 `map[string]int64`,value 可递归嵌套(`[]char/utf8·[]char/utf8·int64`)。 + +```kv +m:[]char/utf8·int64 = {} // 空 map 同样须带类型标注 +m·a = 10 // 命名成员写 +kv·set(m, "b", 20) // 动态键写 +kv·get(m, "a") -> x // 动态键读;缺失返回 None +``` + +## 空容器字面量须带类型标注 + +`{}` 空容器字面量**必须**在赋值目标处带类型标注(`x:object = {}` 或 `x:[]char/utf8·int64 = {}`);无标注时 layout 报错——空字面量本身不足以推断落 object 还是 stringkeymap。 + +## 成员访问 + +| 语法 | 语义 | +|------|------| +| `base·name` | 静态键成员读/写 | +| `base·*k` | 动态键:变量 `k` 的值作成员名(用于局部容器) | +| `kv·get(base, k)` / `kv·set(base, k, v)` | 动态字符串键读/写 | + +容器成员一律走 `·`(或 `kv·get`/`kv·set`),**不得**用 `[]`;`[]` 只索引 compact 数组(见 [[数组形态]])。 + +### `base·name` 的 base 解析:按值优先、按名回退 + +`base·name`(读写同规则)中 base 的解析: + +1. **按值解引用**:base 持有非空字符串值(路径指针)→ 成员键 = `值(base)·name`。如 `"/n1" -> p` 后 `p·next` 解析为 `/n1·next`。 +2. **按名回退**:base 无值(或非字符串)→ 成员键 = `解析(base)·name`;解析帧感知:裸名 → `帧根/base`,`/` 开头 → 直通。 + +该规则让「局部结构体」(base 无值,按名)与「指针解引用」(base 存路径字符串,按值)共用一套语法。 + +## ptr(软链接) + +**ptr** 不是种类,而是 kindexpr 的前缀 `*`:ptr 值的 head kindexpr 为 `*` 加**目标的完整 kindexpr**,body 存**目标 key 路径**。ptr 携带目标的完整类型,赋值(Set)时据此做单跳类型检查。 + +跨函数共享的数据放绝对路径,指针变量存其路径字符串: + +```kv +/n1:object = {} +/n1·val = 1 +/n1·next = "/n2" // next 存目标路径(指针) +"/n1" -> p // 引号 = 路径串(指针) +p·val -> v // 按值解引用:读 /n1·val +``` + +## struct + +`struct` 声明注册一个原型节点于 `/lib/`(种类 `struct`),字段带类型标注与默认值: + +```kv +struct Point { + x:float64=0.0 + y:float64=0.0 +} +``` + +实例化 `Name{f=v}` 克隆原型子树、覆盖给定字段(其余取默认),并对每个字段做类型校验;实例是 object 式命名成员容器,成员经 `·` 访问。字段类型不符或写不存在的字段在 runtime 报 TypeError。 + +```kv +p = Point{x=3.0 y=4.0} +p·x -> a // 3.0 +q = Point{} // 全取默认:0.0, 0.0 +``` + +在签名中,结构类型以原型路径 `/lib/`(**structref** 类型表达式 atom)标注(见 [[kindexpr签名类型表达式]])。结构值可存进 map(int 键、struct 值)、以绝对路径指针连成链表/树/图(见 `tutorial/12-struct/`)。 + +> **实验性**:struct 的落盘 kind 表示(原型 kind `struct`、实例种类、structref 标注、有无独立实例常量)尚未定型,可能调整;上述为当前实现现状,不作为稳定契约。 + +## 锚例 + +- object 字面量与成员访问:`tutorial/05-dict/literal.kv`、`tutorial/10-types/01-typed-map.kv`。 +- stringkeymap 与动态键、缺失返 None:`tutorial/10-types/02-string-map.kv`、`05-dict/kv_has_string_key.kv`。 +- 嵌套 map 与元组键签名:`tutorial/10-types/04-nested-type.kv`、`05-tuple-key.kv`。 +- struct 声明/实例化/默认值/多类型字段:`tutorial/12-struct/00-point.kv`、`01-fields.kv`。 +- 指针解引用、局部结构体、链表/树/图:`tutorial/12-struct/03-linked-list.kv`~`07-list-local.kv`。 +"## -> /lib/kvlang/规范/类型系统/容器 +} diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" new file mode 100644 index 00000000..3a83f648 --- /dev/null +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" @@ -0,0 +1,80 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/layout语义/指令架构 { + r##"# 指令架构 + +layout 把每个函数体布进 kvspace 的一棵子树:**指令即路径**,每条指令占据一个二维坐标 `[s0, s1]`。本章界定该坐标系、opcode 与读写槽的角色、三种赋值书写形态,以及槽值的 XValue 编码。二维坐标的线格式(TLV、head kindexpr)见 [[指令布局格式]](kvspace 模型卷);本章只界定 layout 产出的槽位语义。 + +## 二维坐标系 `[s0, s1]` + +函数目录(`/lib/·/`,见 [[lib与rwir数据]])下,每条指令的每个槽是一个独立 KV key,key 名恒为坐标串 `[s0,s1]`。两轴含义: + +- **s0 轴(执行顺序轴)**——第几条指令。`s0 = 0` 保留给函数签名行;指令从 `s0 = 1` 起顺序编号(称 irseq)。 +- **s1 轴(参数轴)**——该槽的角色: + +| s1 | 角色 | 方向 | +|----|------|------| +| `s1 = 0` | **opcode**(操作码) | —— | +| `s1 = -1, -2, …` | **读参**(read slot,输入) | 调用方 → 被调方 | +| `s1 = +1, +2, …` | **写参**(write slot,输出) | 被调方 → 调用方 | + +铁律: + +- `[s0, 0]` **必须**是 opcode(操作符名或被调用的 rwir/rwfunc 名),**不得**放变量引用。 +- 读参在负轴、写参在正轴,符号即数据流方向:从负轴读入、在零轴执行、向正轴写出。 +- 参数数量**隐式编码**:runtime 沿 s1 轴向两侧扩展,遇空 key 即停,opcode 中不存 arity(见 [[执行模型]])。 + +示例:`A + B -> C` 布为 + +``` +[s0,0] = "+" opcode +[s0,-1] = "A" 第 1 读参 +[s0,-2] = "B" 第 2 读参 +[s0,1] = "C" 第 1 写参 +``` + +写参扇出(同一结果写入多个位置)以多个正轴槽表示:`a + b -> sum, backup` 布出 `[s0,1]="sum"`、`[s0,2]="backup"`。 + +## 三种赋值书写形态 + +赋值有三种等价书写,写槽约束完全一致: + +| 形态 | 写槽位置 | 例 | +|------|---------|-----| +| `expr -> writes` | 右 | `A + B -> C` | +| `writes <- expr` | 左 | `C <- A + B` | +| `writes = expr` | 左 | `C = A + B` | + +`=` 是 `<-` 的等价书写,**不是**表达式,**不得**嵌套于条件或实参中。三者布出的坐标完全相同——书写形态不改变布局。 + +**写槽必须是位置(location)**:裸名(帧内变量)、绝对路径(`/abs`)、成员写(`base·field` / `base·*key`)、下标写(`arr[idx]`)。字面量出现在写槽位置是错误,layout 报诊断(见 [[诊断]])。 + +## `=` 拷贝 opcode + +叶表达式写入写槽(拷贝)**必须**编码为显式 opcode `=`,被拷贝的值放读槽: + +``` +a -> b [s0,0]="=" [s0,-1]="a" [s0,1]="b" +42 -> x [s0,0]="=" [s0,-1]=42 [s0,1]="x" +``` + +opcode 位恒为操作码,故拷贝(opcode=`=`)与零参函数调用(`greet() -> x`,opcode=`greet`)在 KV 层无歧义。 + +## opcode 槽的 XValue kind + +opcode 槽 `[s0,0]` 的 kind 由 layout 按 opcode 类别决定: + +- 控制流与拷贝原语(`return` / `goto` / `br` / `call` / `=`)——kind `rwir`。 +- 其余(运算符、函数/rwir 调用目标)——kind `rwir|rwfunc` 并列。layout **不**静态判定该目标是 native builtin、扩展 rwir 还是用户 rwfunc;判定推迟到 runtime 查 `/lib/` 分派(见 [[lib与rwir数据]])。 + +## 读写槽的槽值编码 + +读/写槽的槽值按内容编码为 XValue: + +- 字面量(整数、浮点、`true`/`false`、字符串、绝对路径)——按其类型编码为对应 kind 的 XValue(`int64` / `float64` / `bool` / `char/*` …);字符串字面量在 KV 传输层以 `"` 前缀区分于变量名。 +- 变量名、标签等引用——kind `rwir`,body 即该名字符串。 + +## 增量覆盖 + +写函数前 layout **必须**先 `del_tree` 清除该函数子树,再重写:残留的旧槽会被 runtime 沿 s1 轴误读为真实参数。清除**仅限本函数子树**——多次 layout 各自覆盖其函数,**不得**整库删除,以支持增量布局(文件夹复制式合并)。 +"## -> /lib/kvlang/规范/layout语义/指令架构 +} diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\345\207\275\346\225\260.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\345\207\275\346\225\260.kv" new file mode 100644 index 00000000..21e8008e --- /dev/null +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\345\207\275\346\225\260.kv" @@ -0,0 +1,91 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/layout语义/函数 { + r##"# 函数 + +kvlang 有两种命名单元:**rwfunc**(有指令体的用户函数)与 **rwir 声明**(仅签名,绑定至扩展执行器)。两者对外都暴露相同的 `(读参) -> (写参)` 箭头接口。函数**没有返回值**,只有读参与写参。 + +## 读参与写参 + +| 参数 | 布局槽位 | 方向 | +|------|---------|------| +| **读参** | `[0,-1], [0,-2], …` | 调用方 → 被调方 | +| **写参** | `[0,+1], [0,+2], …` | 被调方 → 调用方 | + +`-> result` 是**写参的跨帧路径映射**,不是返回值:runtime 将子帧写参直写调用方目标位置(见 [[调用与返回]])。 + +调用时**写参 arity 必须全部匹配**(对齐 Go/Rust):`f() -> s` 对多写参函数是错误;不需要的写参**必须**用 `_` 显式丢弃。 + +## 参数类型必须标注 + +每个读参与写参**必须**声明类型(`name:type_expr`,type_expr 见 [[kindexpr签名类型表达式]])。缺类型标注是错误: + +``` +error: func f: param "x" has no type annotation — every parameter must declare its type +error: func f: return value "r" has no type annotation +``` + +末读参的 type_expr **可**加 `...` 声明变参(0..N 个同型实参)。变参**必须**是最后一个读参;写参**不得**变参。 + +## 写参初值 None + +写参在被调方帧内初值为 **None**(strict null)。函数体内**必须**先显式初始化写参再参与运算——对 None 做算术在 runtime 被拒。惯例以拷贝置零值起步(`0 -> acc`),此后写参在体内可读可写,退出时经箭头映射回调用方。 + +## 读参只读 + +读参是单向输入绑定。函数体内把读参裸名放入写槽(含 `for … in` 的迭代变量)会破坏数据流方向,layout 报错拒绝装载: + +``` +error: func f: read param "A" cannot be used as write slot (read params are read-only) +``` + +**签名诚实原则**:函数体内被写的参数**必须**声明在写参侧。 + +``` +// 非法:acc 被写却在读参侧 +rwfunc sum(arr:[]int64, acc:int64) -> (r:int64) { acc + arr[0] -> acc } +// 合法:acc 在写参侧,体内可读可写 +rwfunc sum(arr:[]int64) -> (acc:int64) { acc + arr[0] -> acc } +``` + +判定规则(实现):写槽含 `/`、`[`、`·` 者视为路径/下标/成员写,不计入本检查;但 `kv·set(base, …)` 的 base 命中读参裸名同样拒绝(成员目录被改写)。 + +## 参数同名规则 + +- **定义时**:读参与写参**不得**同名——`rwfunc f(A:int64) -> (A:int64)` 非法,报 `param "A" appears in both read-params and write-params`。 +- **调用时**:同一变量**可**同时出现在读槽与写槽——`inc(x) -> x` 合法,读写独立解析、互不冲突。 + +## 写槽校验 + +写槽(`->` 右 / `<-`、`=` 左)解析时,非法写槽产生警告(`warn`,不拒装载): + +- 字面量(数字/引号串开头)出现在写槽位置 → `unexpected token … in write slot position`。 +- 写槽后紧跟 `(`(同行函数调用)→ `function call … on same line as write slot`。 + +合法写槽:裸名、`/abs`、`base·名`、`base·*key`、`arr[idx]`。 + +## rwfunc 布局 + +rwfunc 布进 `/lib/·/`: + +1. `[0,0]`——签名槽,kind `rwfunc`,body `[nr:u16 LE][nw:u16 LE][各参 kindexpr 以 "\n" 连接]`,array_len = 指令条数。 +2. `/lib/·.src`——源码副本(kind `char`)。 +3. 每个命名参数——`funcDir/` 存 Ptr(kind `char`),指向其槽坐标串(读参 `[0,-j]`、写参 `[0,+j]`)。 +4. 指令体从 `[1,0]` 起(`[0,*]` 为签名行占用)。 + +写参不需要值的调用以 `_` 接收,`_` 写入帧内 `_` 槽、不影响语义。 + +## rwfunc 声明位置 + +rwfunc 应包裹在 `lib pkg { }` 内。裸顶层 rwfunc **可**声明,但产生提示(`info`)并登记到 `/lib/`(无 pkg): + +``` +info: rwfunc outside lib block — registering under /lib/; consider wrapping in 'lib pkgname { }' +``` + +裸顶层 rwfunc 名与 native builtin 同名是错误(`function "…" shadows builtin`)——须包裹进 lib 或改名。 + +## rwir 声明 + +`rwir name(读参) -> (写参)` 仅有签名、无体,绑定至扩展执行器。它布进 `/lib/`(kind `defrwir`),格式与 rwfunc 签名定义体一致、区别仅在 kind 与无指令体。详见 [[lib与rwir数据]]。 +"## -> /lib/kvlang/规范/layout语义/函数 +} diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\346\216\247\345\210\266\346\265\201.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\346\216\247\345\210\266\346\265\201.kv" new file mode 100644 index 00000000..bbe28e16 --- /dev/null +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\346\216\247\345\210\266\346\265\201.kv" @@ -0,0 +1,64 @@ +// 欢迎加入kvspace世界 +lib kvlang/规范/layout语义/控制流 { + r##"# 控制流 + +kvlang 的结构化控制流有 `if`/`else`/`while`/`for … in`/具名 block/`break`/`continue`/`return`。它们**只能**出现在 rwfunc 体内;顶层出现是错误: + +``` +error: top-level while is not supported — wrap in main() +``` + +`return` **无参数**——输出经写参传递;`return x` 报错。 + +## 降级为 goto/br(lower) + +layout 的 lower 阶段把结构化控制流降级为两条控制原语加具名作用域块(ScopeStmt): + +- `goto(label)`——无条件跳转。 +- `br(cond, then_label, else_label)`——按 cond 二路分支。 +- `break` → `goto` 到循环 exit 块;`continue` → `goto` 到循环 cond 块。 + +每个 `if`/`while`/`for` 展开为一组具名块(如 `_while_2`、`_do_3`、`_exit_4`、`_if_5`、`_then_6`、`_else_7`、`_merge_8`)。`else if` 链按嵌套 `if` 展开。开放路径尾部补 `return`(layout 保证每块以终结符 `return`/`goto`/`br` 收尾)。 + +## 布局为线性 irseq + +lower 之后,layout 把**所有**块体展平进函数目录下的**单一线性指令序列** `[1,0]…[N,0]`——**不建 scope 子目录**。goto/br 的跳转目标在布局时解析为**整数 irseq**(目标块首指令的 s0 序号),写入其读槽。 + +标签到 irseq 的映射另存于 `/lib/·/‥labels/

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 pZVbkuGaaAzR~2jbu{b6Rfto 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