From cb1d1e8e4270072eede11e1ea997a50e85590b71 Mon Sep 17 00:00:00 2001
From: John Naylor <jcnaylor@gmail.com>
Date: Wed, 27 Dec 2017 18:29:43 +0700
Subject: [PATCH v5 12/13] Reduce indentation level

A previous commit removed a logical block level from Catalog.pm, but
kept the indentation for the sake of patch readability. Fix that here.

Separate out the pg_attribute logic of genbki.pl into its own function
and skip checking if the data is defined. This both narrows and shortens
the data writing loop of the script.
---
 src/backend/catalog/Catalog.pm | 223 ++++++++++++------------
 src/backend/catalog/genbki.pl  | 380 +++++++++++++++++++++--------------------
 2 files changed, 302 insertions(+), 301 deletions(-)

diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index a8a406a..49195dc 100644
--- a/src/backend/catalog/Catalog.pm
+++ b/src/backend/catalog/Catalog.pm
@@ -33,149 +33,148 @@ sub ParseHeader
 		'TransactionId' => 'xid',
 		'XLogRecPtr'    => 'pg_lsn');
 
-		my $declaring_attributes;
-		my %catalog;
-		$catalog{columns} = [];
-		$catalog{toasting} = [];
-		$catalog{indexing} = [];
-		my $is_varlen     = 0;
+	my $declaring_attributes;
+	my %catalog;
+	$catalog{columns} = [];
+	$catalog{toasting} = [];
+	$catalog{indexing} = [];
+	my $is_varlen     = 0;
 
-		open(my $ifh, '<', $input_file) || die "$input_file: $!";
+	open(my $ifh, '<', $input_file) || die "$input_file: $!";
 
-		# Scan the input file.
-		while (<$ifh>)
+	# Scan the input file.
+	while (<$ifh>)
+	{
+
+		# Strip C-style comments.
+		s;/\*(.|\n)*\*/;;g;
+		if (m;/\*;)
 		{
 
-			# Strip C-style comments.
-			s;/\*(.|\n)*\*/;;g;
-			if (m;/\*;)
-			{
+			# handle multi-line comments properly.
+			my $next_line = <$ifh>;
+			die "$input_file: ends within C-style comment\n"
+			  if !defined $next_line;
+			$_ .= $next_line;
+			redo;
+		}
 
-				# handle multi-line comments properly.
-				my $next_line = <$ifh>;
-				die "$input_file: ends within C-style comment\n"
-				  if !defined $next_line;
-				$_ .= $next_line;
-				redo;
-			}
+		# Strip useless whitespace and trailing semicolons.
+		chomp;
+		s/^\s+//;
+		s/;\s*$//;
+		s/\s+/ /g;
 
-			# Strip useless whitespace and trailing semicolons.
-			chomp;
-			s/^\s+//;
-			s/;\s*$//;
-			s/\s+/ /g;
+		# Push the data into the appropriate data structure.
+		if (/^DECLARE_TOAST\(\s*(\w+),\s*(\d+),\s*(\d+)\)/)
+		{
+			my ($toast_name, $toast_oid, $index_oid) = ($1, $2, $3);
+			push @{ $catalog{toasting} },
+			  "declare toast $toast_oid $index_oid on $toast_name\n";
+		}
+		elsif (/^DECLARE_(UNIQUE_)?INDEX\(\s*(\w+),\s*(\d+),\s*(.+)\)/)
+		{
+			my ($is_unique, $index_name, $index_oid, $using) =
+			  ($1, $2, $3, $4);
+			push @{ $catalog{indexing} },
+			  sprintf(
+				"declare %sindex %s %s %s\n",
+				$is_unique ? 'unique ' : '',
+				$index_name, $index_oid, $using);
+		}
+		elsif (/^BUILD_INDICES/)
+		{
+			push @{ $catalog{indexing} }, "build indices\n";
+		}
+		elsif (/^CATALOG\(([^,]*),(\d+)\)/)
+		{
+			$catalog{catname} = $1;
+			$catalog{relation_oid} = $2;
 
-			# Push the data into the appropriate data structure.
-			if (/^DECLARE_TOAST\(\s*(\w+),\s*(\d+),\s*(\d+)\)/)
-			{
-				my ($toast_name, $toast_oid, $index_oid) = ($1, $2, $3);
-				push @{ $catalog{toasting} },
-				  "declare toast $toast_oid $index_oid on $toast_name\n";
-			}
-			elsif (/^DECLARE_(UNIQUE_)?INDEX\(\s*(\w+),\s*(\d+),\s*(.+)\)/)
+			$catalog{bootstrap} = /BKI_BOOTSTRAP/ ? ' bootstrap' : '';
+			$catalog{shared_relation} =
+			  /BKI_SHARED_RELATION/ ? ' shared_relation' : '';
+			$catalog{without_oids} =
+			  /BKI_WITHOUT_OIDS/ ? ' without_oids' : '';
+			$catalog{rowtype_oid} =
+			  /BKI_ROWTYPE_OID\((\d+)\)/ ? " rowtype_oid $1" : '';
+			$catalog{schema_macro} = /BKI_SCHEMA_MACRO/ ? 1 : 0;
+			$declaring_attributes = 1;
+		}
+		elsif ($declaring_attributes)
+		{
+			next if (/^{|^$/);
+			if (/^#/)
 			{
-				my ($is_unique, $index_name, $index_oid, $using) =
-				  ($1, $2, $3, $4);
-				push @{ $catalog{indexing} },
-				  sprintf(
-					"declare %sindex %s %s %s\n",
-					$is_unique ? 'unique ' : '',
-					$index_name, $index_oid, $using);
+				if (/^#ifdef\s+CATALOG_VARLEN/)
+				{
+					$is_varlen = 1;
+				}
+				next;
 			}
-			elsif (/^BUILD_INDICES/)
+			if (/^}/)
 			{
-				push @{ $catalog{indexing} }, "build indices\n";
+				undef $declaring_attributes;
 			}
-			elsif (/^CATALOG\(([^,]*),(\d+)\)/)
+			else
 			{
-				$catalog{catname} = $1;
-				$catalog{relation_oid} = $2;
+				my %column;
+				my @attopts = split /\s+/, $_;
+				my $atttype = shift @attopts;
+				my $attname = shift @attopts;
+				die "parse error ($input_file)"
+				  unless ($attname and $atttype);
 
-				$catalog{bootstrap} = /BKI_BOOTSTRAP/ ? ' bootstrap' : '';
-				$catalog{shared_relation} =
-				  /BKI_SHARED_RELATION/ ? ' shared_relation' : '';
-				$catalog{without_oids} =
-				  /BKI_WITHOUT_OIDS/ ? ' without_oids' : '';
-				$catalog{rowtype_oid} =
-				  /BKI_ROWTYPE_OID\((\d+)\)/ ? " rowtype_oid $1" : '';
-				$catalog{schema_macro} = /BKI_SCHEMA_MACRO/ ? 1 : 0;
-				$declaring_attributes = 1;
-			}
-			elsif ($declaring_attributes)
-			{
-				next if (/^{|^$/);
-				if (/^#/)
+				if (exists $RENAME_ATTTYPE{$atttype})
 				{
-					if (/^#ifdef\s+CATALOG_VARLEN/)
-					{
-						$is_varlen = 1;
-					}
-					next;
+					$atttype = $RENAME_ATTTYPE{$atttype};
 				}
-				if (/^}/)
+				if ($attname =~ /(.*)\[.*\]/)    # array attribute
 				{
-					undef $declaring_attributes;
+					$attname = $1;
+					$atttype .= '[]';
 				}
-				else
+
+				$column{type} = $atttype;
+				$column{name} = $attname;
+				if ($is_varlen)
 				{
-					my %column;
-					my @attopts = split /\s+/, $_;
-					my $atttype = shift @attopts;
-					my $attname = shift @attopts;
-					die "parse error ($input_file)"
-					  unless ($attname and $atttype);
+					$column{is_varlen} = 1;
+				}
 
-					if (exists $RENAME_ATTTYPE{$atttype})
+				foreach my $attopt (@attopts)
+				{
+					if ($attopt eq 'BKI_FORCE_NULL')
 					{
-						$atttype = $RENAME_ATTTYPE{$atttype};
+						$column{forcenull} = 1;
 					}
-					if ($attname =~ /(.*)\[.*\]/)    # array attribute
+					elsif ($attopt eq 'BKI_FORCE_NOT_NULL')
 					{
-						$attname = $1;
-						$atttype .= '[]';
+						$column{forcenotnull} = 1;
 					}
-
-					$column{type} = $atttype;
-					$column{name} = $attname;
-					if ($is_varlen)
+					elsif ($attopt =~ /BKI_DEFAULT\((\S+)\)/)
 					{
-						$column{is_varlen} = 1;
+						$column{default} = $1;
 					}
-
-					foreach my $attopt (@attopts)
+					elsif ($attopt =~ /BKI_ABBREV\((\S+)\)/)
 					{
-						if ($attopt eq 'BKI_FORCE_NULL')
-						{
-							$column{forcenull} = 1;
-						}
-						elsif ($attopt eq 'BKI_FORCE_NOT_NULL')
-						{
-							$column{forcenotnull} = 1;
-						}
-						elsif ($attopt =~ /BKI_DEFAULT\((\S+)\)/)
-						{
-							$column{default} = $1;
-						}
-						elsif ($attopt =~ /BKI_ABBREV\((\S+)\)/)
-						{
-							$column{abbrev} = $1;
-						}
-						else
-						{
-							die
-"unknown column option $attopt on column $attname";
-						}
+						$column{abbrev} = $1;
+					}
+					else
+					{
+						die "unknown column option $attopt on column $attname";
+					}
 
-						if ($column{forcenull} and $column{forcenotnull})
-						{
-							die "$attname is forced both null and not null";
-						}
+					if ($column{forcenull} and $column{forcenotnull})
+					{
+						die "$attname is forced both null and not null";
 					}
-					push @{ $catalog{columns} }, \%column;
 				}
+				push @{ $catalog{columns} }, \%column;
 			}
 		}
-		close $ifh;
+	}
+	close $ifh;
 	return \%catalog;
 }
 
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index c15ed20..640dc9e 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -252,215 +252,140 @@ foreach my $catname (@catnames)
 		print $bki "open $catname\n";
 	}
 
-	if (defined $catalog_data{$catname})
-	{
-
-		# Ordinary catalog with a data file
-		foreach my $row (@{ $catalog_data{$catname} })
-		{
-			my %bki_values = %$row;
-
-			# Perform required substitutions on fields
-			foreach my $column (@$schema)
-			{
-				my $attname = $column->{name};
-				my $atttype = $column->{type};
-
-				# Substitute constant values we acquired above.
-				# (It's intentional that this can apply to parts of a field).
-				$bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g;
-				$bki_values{$attname} =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g;
-
-				# Replace reg* columns' values with OIDs.
-				if ($atttype eq 'regproc')
-				{
-					# If we don't have a unique value to substitute,
-					# just do nothing (regprocin will complain).
-					my $procoid = $regprocoids{ $bki_values{$attname} };
-					$bki_values{$attname} = $procoid
-					  if defined($procoid) && $procoid ne 'MULTIPLE';
-				}
-				elsif ($atttype eq 'regam')
-				{
-					my $amoid = $regamoids{ $bki_values{$attname} };
-					$bki_values{$attname} = $amoid
-					  if defined($amoid);
-				}
-				elsif ($atttype eq 'regopf')
-				{
-					my $opfoid = $regopfoids{ $bki_values{$attname} };
-					$bki_values{$attname} = $opfoid
-					  if defined($opfoid);
-				}
-				elsif ($atttype eq 'regoper')
-				{
-					my $operoid = $regoperoids{ $bki_values{$attname} };
-					$bki_values{$attname} = $operoid
-					  if defined($operoid);
-				}
-				elsif ($atttype eq 'regtype')
-				{
-					my $typeoid = $regtypeoids{ $bki_values{$attname} };
-					$bki_values{$attname} = $typeoid
-					  if defined($typeoid);
-				}
-			}
-
-			# We can't do regtype lookups in a general way for
-			# pg_proc, so do special handling here.
-			if ($catname eq 'pg_proc')
-			{
-
-				# prorettype
-				# Note: We could handle this automatically by using the
-				# 'regtype' alias, but then we would have to teach
-				# emit_pgattr_row() to change the attribute type back to
-				# oid. Since we have to treat pg_proc differently anyway,
-				# just do the type lookup manually here.
-				my $rettypeoid = $regtypeoids{ $bki_values{prorettype}};
-				$bki_values{prorettype} = $rettypeoid
-				  if defined($rettypeoid);
-
-				# proargtypes
-				if ($bki_values{proargtypes})
-				{
-					my @argtypenames = split /\s+/, $bki_values{proargtypes};
-					my @argtypeoids;
-					foreach my $argtypename (@argtypenames)
-					{
-						my $argtypeoid  = $regtypeoids{$argtypename};
-						push @argtypeoids, $argtypeoid;
-					}
-					$bki_values{proargtypes} = join(' ', @argtypeoids);
-				}
-
-				# proallargtypes
-				if ($bki_values{proallargtypes} ne '_null_')
-				{
-					$bki_values{proallargtypes} =~ s/[{}]//g;
-					my @argtypenames = split /,/, $bki_values{proallargtypes};
-					my @argtypeoids;
-					foreach my $argtypename (@argtypenames)
-					{
-						my $argtypeoid  = $regtypeoids{$argtypename};
-						push @argtypeoids, $argtypeoid;
-					}
-					$bki_values{proallargtypes} =
-						'{' . join(',', @argtypeoids) . '}';
-				}
-			}
-
-			# Store OID symbols for later.
-			if (exists $bki_values{oid_symbol})
-			{
-				if (!@tables_with_oid_symbols
-				    or $tables_with_oid_symbols[-1] ne $catname)
-				{
-					push @tables_with_oid_symbols, $catname;
-					$oid_symbols{$catname} = [];
-				}
-
-				push @{ $oid_symbols{$catname} },
-				  sprintf "#define %s %s",
-				    $bki_values{oid_symbol}, $bki_values{oid};
-			}
-
-			# Add quotes where necessary.
-			quote_bki_values(\%bki_values, $schema);
-
-			# Write to postgres.bki
-			bki_insert(\%bki_values, @attnames);
-
-			# Write comments to postgres.description and
-			# postgres.shdescription
-			if (defined $bki_values{descr})
-			{
-				printf $descr "%s\t%s\t0\t%s\n",
-				  $bki_values{oid}, $catname, $bki_values{descr};
-			}
-			if (defined $bki_values{shdescr})
-			{
-				printf $shdescr "%s\t%s\t%s\n",
-				  $bki_values{oid}, $catname, $bki_values{shdescr};
-			}
-		}
-	}
 	if ($catname eq 'pg_attribute')
 	{
+		gen_pg_attribute($schema, @attnames);
+	}
 
-		# For pg_attribute.h, we generate data entries ourselves.
-		foreach my $table_name (@catnames)
-		{
-			my $table = $catalogs{$table_name};
+	# Ordinary catalog with a data file
+	foreach my $row (@{ $catalog_data{$catname} })
+	{
+		my %bki_values = %$row;
 
-			# Currently, all bootstrapped relations also need schemapg.h
-			# entries, so skip if the relation isn't to be in schemapg.h.
-			next if !$table->{schema_macro};
+		# Perform required substitutions on fields
+		foreach my $column (@$schema)
+		{
+			my $attname = $column->{name};
+			my $atttype = $column->{type};
 
-			$schemapg_entries{$table_name} = [];
-			push @tables_needing_macros, $table_name;
+			# Substitute constant values we acquired above.
+			# (It's intentional that this can apply to parts of a field).
+			$bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g;
+			$bki_values{$attname} =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g;
 
-			# Generate entries for user attributes.
-			my $attnum       = 0;
-			my $priornotnull = 1;
-			my @user_attrs   = @{ $table->{columns} };
-			foreach my $attr (@user_attrs)
+			# Replace reg* columns' values with OIDs.
+			if ($atttype eq 'regproc')
+			{
+				# If we don't have a unique value to substitute,
+				# just do nothing (regprocin will complain).
+				my $procoid = $regprocoids{ $bki_values{$attname} };
+				$bki_values{$attname} = $procoid
+				  if defined($procoid) && $procoid ne 'MULTIPLE';
+			}
+			elsif ($atttype eq 'regam')
+			{
+				my $amoid = $regamoids{ $bki_values{$attname} };
+				$bki_values{$attname} = $amoid
+				  if defined($amoid);
+			}
+			elsif ($atttype eq 'regopf')
+			{
+				my $opfoid = $regopfoids{ $bki_values{$attname} };
+				$bki_values{$attname} = $opfoid
+				  if defined($opfoid);
+			}
+			elsif ($atttype eq 'regoper')
+			{
+				my $operoid = $regoperoids{ $bki_values{$attname} };
+				$bki_values{$attname} = $operoid
+				  if defined($operoid);
+			}
+			elsif ($atttype eq 'regtype')
 			{
-				$attnum++;
-				my %row;
-				$row{attnum}   = $attnum;
-				$row{attrelid} = $table->{relation_oid};
+				my $typeoid = $regtypeoids{ $bki_values{$attname} };
+				$bki_values{$attname} = $typeoid
+				  if defined($typeoid);
+			}
+		}
+
+		# We can't do regtype lookups in a general way for
+		# pg_proc, so do special handling here.
+		if ($catname eq 'pg_proc')
+		{
 
-				emit_pgattr_row(\%row, $schema, $attr, $priornotnull);
-				$priornotnull &= ($row{attnotnull} eq 't');
+			# prorettype
+			# Note: We could handle this automatically by using the
+			# 'regtype' alias, but then we would have to teach
+			# emit_pgattr_row() to change the attribute type back to
+			# oid. Since we have to treat pg_proc differently anyway,
+			# just do the type lookup manually here.
+			my $rettypeoid = $regtypeoids{ $bki_values{prorettype}};
+			$bki_values{prorettype} = $rettypeoid
+			  if defined($rettypeoid);
 
-				# If it's bootstrapped, put an entry in postgres.bki.
-				if ($table->{bootstrap})
+			# proargtypes
+			if ($bki_values{proargtypes})
+			{
+				my @argtypenames = split /\s+/, $bki_values{proargtypes};
+				my @argtypeoids;
+				foreach my $argtypename (@argtypenames)
 				{
-					bki_insert(\%row, @attnames);
+					my $argtypeoid  = $regtypeoids{$argtypename};
+					push @argtypeoids, $argtypeoid;
 				}
-
-				# Store schemapg entries for later.
-				emit_schemapg_row(\%row, $schema);
-				push @{ $schemapg_entries{$table_name} },
-				  sprintf "{ %s }",
-				    join(', ', grep { defined $_ } @row{@attnames});
+				$bki_values{proargtypes} = join(' ', @argtypeoids);
 			}
 
-			# Generate entries for system attributes.
-			# We only need postgres.bki entries, not schemapg.h entries.
-			if ($table->{bootstrap})
+			# proallargtypes
+			if ($bki_values{proallargtypes} ne '_null_')
 			{
-				$attnum = 0;
-				my @SYS_ATTRS = (
-					{ name => 'ctid',     type => 'tid' },
-					{ name => 'oid',      type => 'oid' },
-					{ name => 'xmin',     type => 'xid' },
-					{ name => 'cmin',     type => 'cid' },
-					{ name => 'xmax',     type => 'xid' },
-					{ name => 'cmax',     type => 'cid' },
-					{ name => 'tableoid', type => 'oid' });
-				foreach my $attr (@SYS_ATTRS)
+				$bki_values{proallargtypes} =~ s/[{}]//g;
+				my @argtypenames = split /,/, $bki_values{proallargtypes};
+				my @argtypeoids;
+				foreach my $argtypename (@argtypenames)
 				{
-					$attnum--;
-					my %row;
-					$row{attnum}        = $attnum;
-					$row{attrelid}      = $table->{relation_oid};
-					$row{attstattarget} = '0';
+					my $argtypeoid  = $regtypeoids{$argtypename};
+					push @argtypeoids, $argtypeoid;
+				}
+				$bki_values{proallargtypes} =
+					'{' . join(',', @argtypeoids) . '}';
+			}
+		}
+
+		# Store OID symbols for later.
+		if (exists $bki_values{oid_symbol})
+		{
+			if (!@tables_with_oid_symbols
+				or $tables_with_oid_symbols[-1] ne $catname)
+			{
+				push @tables_with_oid_symbols, $catname;
+				$oid_symbols{$catname} = [];
+			}
 
-					emit_pgattr_row(\%row, $schema, $attr, 1);
+			push @{ $oid_symbols{$catname} },
+			  sprintf "#define %s %s",
+				$bki_values{oid_symbol}, $bki_values{oid};
+		}
 
-					# Omit the oid column if the catalog doesn't have them
-					next
-					  if $table->{without_oids}
-						  && $row{attname} eq 'oid';
+		# Add quotes where necessary.
+		quote_bki_values(\%bki_values, $schema);
 
-					bki_insert(\%row, @attnames);
-				}
-			}
+		# Write to postgres.bki
+		bki_insert(\%bki_values, @attnames);
+
+		# Write comments to postgres.description and
+		# postgres.shdescription
+		if (defined $bki_values{descr})
+		{
+			printf $descr "%s\t%s\t0\t%s\n",
+			  $bki_values{oid}, $catname, $bki_values{descr};
+		}
+		if (defined $bki_values{shdescr})
+		{
+			printf $shdescr "%s\t%s\t%s\n",
+			  $bki_values{oid}, $catname, $bki_values{shdescr};
 		}
 	}
-
 	print $bki "close $catname\n";
 }
 
@@ -608,6 +533,83 @@ sub quote_bki_values
 	}
 }
 
+# For pg_attribute.h, we generate data entries ourselves.
+sub gen_pg_attribute
+{
+	my $schema = shift;
+	my @attnames = @_;
+
+	foreach my $table_name (@catnames)
+	{
+		my $table = $catalogs{$table_name};
+
+		# Currently, all bootstrapped relations also need schemapg.h
+		# entries, so skip if the relation isn't to be in schemapg.h.
+		next if !$table->{schema_macro};
+
+		$schemapg_entries{$table_name} = [];
+		push @tables_needing_macros, $table_name;
+
+		# Generate entries for user attributes.
+		my $attnum       = 0;
+		my $priornotnull = 1;
+		my @user_attrs   = @{ $table->{columns} };
+		foreach my $attr (@user_attrs)
+		{
+			$attnum++;
+			my %row;
+			$row{attnum}   = $attnum;
+			$row{attrelid} = $table->{relation_oid};
+
+			emit_pgattr_row(\%row, $schema, $attr, $priornotnull);
+			$priornotnull &= ($row{attnotnull} eq 't');
+
+			# If it's bootstrapped, put an entry in postgres.bki.
+			if ($table->{bootstrap})
+			{
+				bki_insert(\%row, @attnames);
+			}
+
+			# Store schemapg entries for later.
+			emit_schemapg_row(\%row, $schema);
+			push @{ $schemapg_entries{$table_name} },
+			  sprintf "{ %s }",
+				join(', ', grep { defined $_ } @row{@attnames});
+		}
+
+		# Generate entries for system attributes.
+		# We only need postgres.bki entries, not schemapg.h entries.
+		if ($table->{bootstrap})
+		{
+			$attnum = 0;
+			my @SYS_ATTRS = (
+				{ name => 'ctid',     type => 'tid' },
+				{ name => 'oid',      type => 'oid' },
+				{ name => 'xmin',     type => 'xid' },
+				{ name => 'cmin',     type => 'cid' },
+				{ name => 'xmax',     type => 'xid' },
+				{ name => 'cmax',     type => 'cid' },
+				{ name => 'tableoid', type => 'oid' });
+			foreach my $attr (@SYS_ATTRS)
+			{
+				$attnum--;
+				my %row;
+				$row{attnum}        = $attnum;
+				$row{attrelid}      = $table->{relation_oid};
+				$row{attstattarget} = '0';
+
+				emit_pgattr_row(\%row, $schema, $attr, 1);
+
+				# some catalogs don't have oids
+				next
+				  if $table->{without_oids}
+					  && $row{attname} eq 'oid';
+
+				bki_insert(\%row, @attnames);
+			}
+		}
+	}
+}
 
 # Given the schema of pg_attribute, generate an entry for it using information
 # about the attribute it describes.  Any value that is not handled here
-- 
2.7.4

