facter 1.5.9 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of facter might be problematic. Click here for more details.
- data/CHANGELOG +39 -0
- data/LICENSE +11 -13
- data/README.md +24 -0
- data/bin/facter +2 -2
- data/conf/redhat/facter.spec +5 -2
- data/conf/solaris/pkginfo +1 -1
- data/install.rb +1 -1
- data/lib/facter.rb +12 -15
- data/lib/facter/Cfkey.rb +11 -11
- data/lib/facter/application.rb +3 -4
- data/lib/facter/architecture.rb +13 -0
- data/lib/facter/domain.rb +20 -0
- data/lib/facter/facterversion.rb +9 -0
- data/lib/facter/fqdn.rb +11 -0
- data/lib/facter/hardwareisa.rb +12 -0
- data/lib/facter/hardwaremodel.rb +13 -0
- data/lib/facter/hostname.rb +13 -0
- data/lib/facter/id.rb +13 -0
- data/lib/facter/interfaces.rb +9 -0
- data/lib/facter/ipaddress.rb +24 -0
- data/lib/facter/ipaddress6.rb +35 -40
- data/lib/facter/iphostnumber.rb +11 -0
- data/lib/facter/kernel.rb +11 -0
- data/lib/facter/kernelmajversion.rb +10 -0
- data/lib/facter/kernelrelease.rb +13 -0
- data/lib/facter/kernelversion.rb +12 -0
- data/lib/facter/lsb.rb +13 -12
- data/lib/facter/lsbmajdistrelease.rb +12 -0
- data/lib/facter/macaddress.rb +21 -0
- data/lib/facter/macosx.rb +13 -11
- data/lib/facter/manufacturer.rb +13 -0
- data/lib/facter/memory.rb +35 -18
- data/lib/facter/netmask.rb +9 -0
- data/lib/facter/network.rb +12 -0
- data/lib/facter/operatingsystem.rb +13 -0
- data/lib/facter/operatingsystemrelease.rb +17 -0
- data/lib/facter/path.rb +9 -0
- data/lib/facter/physicalprocessorcount.rb +53 -4
- data/lib/facter/processor.rb +14 -1
- data/lib/facter/ps.rb +12 -0
- data/lib/facter/puppetversion.rb +10 -0
- data/lib/facter/rubysitedir.rb +10 -0
- data/lib/facter/rubyversion.rb +9 -0
- data/lib/facter/selinux.rb +9 -0
- data/lib/facter/ssh.rb +9 -11
- data/lib/facter/timezone.rb +9 -0
- data/lib/facter/uptime.rb +11 -0
- data/lib/facter/uptime_days.rb +9 -0
- data/lib/facter/uptime_hours.rb +9 -0
- data/lib/facter/uptime_seconds.rb +14 -0
- data/lib/facter/util/collection.rb +5 -1
- data/lib/facter/util/fact.rb +1 -3
- data/lib/facter/util/loader.rb +1 -0
- data/lib/facter/util/macosx.rb +0 -11
- data/lib/facter/util/memory.rb +1 -13
- data/lib/facter/util/resolution.rb +12 -3
- data/lib/facter/util/virtual.rb +1 -1
- data/lib/facter/virtual.rb +49 -3
- data/lib/facter/vlans.rb +10 -0
- data/lib/facter/xendomains.rb +11 -0
- data/spec/fixtures/uptime/sysctl_kern_boottime_big_endian +0 -0
- data/spec/fixtures/uptime/{sysctl_kern_boottime → sysctl_kern_boottime_little_endian} +0 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/interfaces_spec.rb +2 -5
- data/spec/unit/memory_spec.rb +3 -1
- data/spec/unit/operatingsystem_spec.rb +2 -0
- data/spec/unit/physicalprocessorcount_spec.rb +40 -0
- data/spec/unit/util/fact_spec.rb +11 -11
- data/spec/unit/util/loader_spec.rb +4 -0
- data/spec/unit/util/resolution_spec.rb +20 -2
- data/spec/unit/util/uptime_spec.rb +6 -1
- data/spec/unit/util/virtual_spec.rb +1 -0
- data/spec/unit/virtual_spec.rb +34 -4
- metadata +133 -135
- data/COPYING +0 -339
- data/README +0 -8
- data/README.rst +0 -26
- data/TODO +0 -4
- data/lib/facter/util/#uptime.rb# +0 -64
data/lib/facter/iphostnumber.rb
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# Fact: iphostnumber
|
2
|
+
#
|
3
|
+
# Purpose: On selected versions of Darwin, returns the host's IP address.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# Uses either the scutil program to get the localhost name, or parses output
|
7
|
+
# of ifconfig for a MAC address.
|
8
|
+
#
|
9
|
+
# Caveats:
|
10
|
+
#
|
11
|
+
|
1
12
|
Facter.add(:iphostnumber) do
|
2
13
|
confine :kernel => :darwin, :kernelrelease => "R6"
|
3
14
|
setcode do
|
data/lib/facter/kernel.rb
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# Fact: kernel
|
2
|
+
#
|
3
|
+
# Purpose: Returns the operating system's name.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# Uses Ruby's rbconfig to find host_os, if that is a Windows derivative, the
|
7
|
+
# returns 'windows', otherwise returns "uname -s" verbatim.
|
8
|
+
#
|
9
|
+
# Caveats:
|
10
|
+
#
|
11
|
+
|
1
12
|
Facter.add(:kernel) do
|
2
13
|
setcode do
|
3
14
|
require 'rbconfig'
|
@@ -1,3 +1,13 @@
|
|
1
|
+
# Fact: kernelmajversion
|
2
|
+
#
|
3
|
+
# Purpose: Return the operating system's release number's major value.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# Takes the first 2 elements of the kernel version as delimited by periods.
|
7
|
+
#
|
8
|
+
# Caveats:
|
9
|
+
#
|
10
|
+
|
1
11
|
Facter.add("kernelmajversion") do
|
2
12
|
setcode do
|
3
13
|
Facter.value(:kernelversion).split('.')[0..1].join('.')
|
data/lib/facter/kernelrelease.rb
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# Fact: kernelrelease
|
2
|
+
#
|
3
|
+
# Purpose: Return the operating system's release number.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On AIX returns the output from the "oslevel -s" system command.
|
7
|
+
# On Windows based systems, uses the win32ole gem to query Windows Management
|
8
|
+
# for the 'Win32_OperatingSystem' value.
|
9
|
+
# Otherwise uses the output of "uname -r" system command.
|
10
|
+
#
|
11
|
+
# Caveats:
|
12
|
+
#
|
13
|
+
|
1
14
|
Facter.add(:kernelrelease) do
|
2
15
|
setcode 'uname -r'
|
3
16
|
end
|
data/lib/facter/kernelversion.rb
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# Fact: kernelversion
|
2
|
+
#
|
3
|
+
# Purpose: Return the operating system's kernel version.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On Solaris and SunOS based machines, returns the output of "uname -v".
|
7
|
+
# Otherwise returns the 'kernerlversion' fact up to the first '-'. This may be
|
8
|
+
# the entire 'kernelversion' fact in many cases.
|
9
|
+
#
|
10
|
+
# Caveats:
|
11
|
+
#
|
12
|
+
|
1
13
|
Facter.add("kernelversion") do
|
2
14
|
setcode do
|
3
15
|
Facter['kernelrelease'].value.split('-')[0]
|
data/lib/facter/lsb.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
+
# Fact: lsb
|
2
|
+
#
|
3
|
+
# Purpose: Return Linux Standard Base information for the host.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# Uses the lsb_release system command and parses the output with a series of
|
7
|
+
# regular expressions.
|
8
|
+
#
|
9
|
+
# Caveats:
|
10
|
+
# Only works on Linux (and the kfreebsd derivative) systems.
|
11
|
+
# Requires the lsb_release program, which may not be installed by default.
|
12
|
+
# Also is as only as accurate as that program outputs.
|
13
|
+
|
1
14
|
## lsb.rb
|
2
15
|
## Facts related to Linux Standard Base (LSB)
|
3
|
-
##
|
4
|
-
## This program is free software; you can redistribute it and/or
|
5
|
-
## modify it under the terms of the GNU General Public License
|
6
|
-
## as published by the Free Software Foundation (version 2 of the License)
|
7
|
-
## This program is distributed in the hope that it will be useful,
|
8
|
-
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
-
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
-
## GNU General Public License for more details.
|
11
|
-
## You should have received a copy of the GNU General Public License
|
12
|
-
## along with this program; if not, write to the Free Software
|
13
|
-
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
|
14
|
-
##
|
15
16
|
|
16
17
|
{ "LSBRelease" => %r{^LSB Version:\t(.*)$},
|
17
18
|
"LSBDistId" => %r{^Distributor ID:\t(.*)$},
|
@@ -1,3 +1,15 @@
|
|
1
|
+
# Fact: lsbmajdistrelease
|
2
|
+
#
|
3
|
+
# Purpose: Returns the major version of the operation system version as gleaned
|
4
|
+
# from the lsbdistrelease fact.
|
5
|
+
#
|
6
|
+
# Resolution:
|
7
|
+
# Parses the lsbdistrelease fact for numbers followed by a period and
|
8
|
+
# returns those, or just the lsbdistrelease fact if none were found.
|
9
|
+
#
|
10
|
+
# Caveats:
|
11
|
+
#
|
12
|
+
|
1
13
|
# lsbmajdistrelease.rb
|
2
14
|
#
|
3
15
|
require 'facter'
|
data/lib/facter/macaddress.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# Fact: macaddress
|
2
|
+
#
|
3
|
+
# Purpose:
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
#
|
7
|
+
# Caveats:
|
8
|
+
#
|
9
|
+
|
1
10
|
require 'facter/util/macaddress'
|
2
11
|
|
3
12
|
Facter.add(:macaddress) do
|
@@ -12,6 +21,18 @@ Facter.add(:macaddress) do
|
|
12
21
|
end
|
13
22
|
end
|
14
23
|
|
24
|
+
Facter.add(:macaddress) do
|
25
|
+
confine :operatingsystem => "Solaris"
|
26
|
+
setcode do
|
27
|
+
ether = []
|
28
|
+
output = Facter::Util::Resolution.exec("/usr/bin/netstat -np")
|
29
|
+
output.each_line do |s|
|
30
|
+
ether.push($1) if s =~ /(?:SPLA)\s+(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})/
|
31
|
+
end
|
32
|
+
ether[0]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
15
36
|
Facter.add(:macaddress) do
|
16
37
|
confine :operatingsystem => %w{FreeBSD OpenBSD}
|
17
38
|
setcode do
|
data/lib/facter/macosx.rb
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# Fact: macosx
|
2
|
+
#
|
3
|
+
# Purpose:
|
4
|
+
# Returns a number of Mac specific facts, from system profiler and
|
5
|
+
# sw_vers.
|
6
|
+
#
|
7
|
+
# Resolution:
|
8
|
+
# Uses util/macosx.rb to do the fact reconnaissance, then outputs them
|
9
|
+
# preceded by 'sp_'
|
10
|
+
#
|
11
|
+
# Caveats:
|
12
|
+
#
|
13
|
+
|
1
14
|
#
|
2
15
|
# macosx.rb
|
3
16
|
# Additional Facts coming from Mac OS X system_profiler command
|
@@ -5,17 +18,6 @@
|
|
5
18
|
# Copyright (C) 2007 Jeff McCune
|
6
19
|
# Author: Jeff McCune <jeff.mccune@northstarlabs.net>
|
7
20
|
#
|
8
|
-
# This program is free software; you can redistribute it and/or
|
9
|
-
# modify it under the terms of the GNU General Public License
|
10
|
-
# as published by the Free Software Foundation (version 2 of the License)
|
11
|
-
# This program is distributed in the hope that it will be useful,
|
12
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
-
# GNU General Public License for more details.
|
15
|
-
# You should have received a copy of the GNU General Public License
|
16
|
-
# along with this program; if not, write to the Free Software
|
17
|
-
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
|
18
|
-
|
19
21
|
# Jeff McCune
|
20
22
|
# There's a lot more information coming out of system_profiler -xml
|
21
23
|
# We could add quite a bit more, but I didn't want to overload facter
|
data/lib/facter/manufacturer.rb
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# Fact: manufacturer
|
2
|
+
#
|
3
|
+
# Purpose: Return the hardware manufacturer information about the hardware.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On OpenBSD, queries sysctl values, via a util class.
|
7
|
+
# On SunOS Sparc, uses prtdiag via a util class.
|
8
|
+
# On Windows, queries the system via a util class.
|
9
|
+
# Uses the 'util/manufacturer.rb' for fallback parsing.
|
10
|
+
#
|
11
|
+
# Caveats:
|
12
|
+
#
|
13
|
+
|
1
14
|
# manufacturer.rb
|
2
15
|
# Facts related to hardware manufacturer
|
3
16
|
#
|
data/lib/facter/memory.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# Fact: memory
|
2
|
+
#
|
3
|
+
# Purpose: Return information about memory and swap usage.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On Linuxes, uses Facter::Memory.meminfo_number from
|
7
|
+
# 'facter/util/memory.rb'
|
8
|
+
# On AIX, parses "swap -l" for swap values only.
|
9
|
+
# On OpenBSD, it parses "swapctl -l" for swap values, vmstat via a module for
|
10
|
+
# free memory, and "sysctl hw.physmem" for maximum memory.
|
11
|
+
# On Solaris, use "swap -l" for swap values, and parsing prtconf for maximum
|
12
|
+
# memory, and again, the vmstat module for free memory.
|
13
|
+
#
|
14
|
+
# Caveats:
|
15
|
+
# Some BSD platforms aren't covered at all. AIX is missing memory values.
|
16
|
+
#
|
17
|
+
|
1
18
|
# memory.rb
|
2
19
|
# Additional Facts for memory/swap usage
|
3
20
|
#
|
@@ -23,30 +40,30 @@ end
|
|
23
40
|
Facter.add("SwapSize") do
|
24
41
|
confine :kernel => :Darwin
|
25
42
|
setcode do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
43
|
+
swap = Facter::Util::Resolution.exec('sysctl vm.swapusage')
|
44
|
+
swaptotal = 0
|
45
|
+
if swap =~ /total = (\S+)/ then swaptotal = $1; end
|
46
|
+
swaptotal
|
30
47
|
end
|
31
48
|
end
|
32
49
|
|
33
50
|
Facter.add("SwapFree") do
|
34
51
|
confine :kernel => :Darwin
|
35
52
|
setcode do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
53
|
+
swap = Facter::Util::Resolution.exec('sysctl vm.swapusage')
|
54
|
+
swapfree = 0
|
55
|
+
if swap =~ /free = (\S+)/ then swapfree = $1; end
|
56
|
+
swapfree
|
40
57
|
end
|
41
58
|
end
|
42
59
|
|
43
60
|
Facter.add("SwapEncrypted") do
|
44
61
|
confine :kernel => :Darwin
|
45
62
|
setcode do
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
63
|
+
swap = Facter::Util::Resolution.exec('sysctl vm.swapusage')
|
64
|
+
encrypted = false
|
65
|
+
if swap =~ /\(encrypted\)/ then encrypted = true; end
|
66
|
+
encrypted
|
50
67
|
end
|
51
68
|
end
|
52
69
|
|
@@ -57,9 +74,9 @@ if Facter.value(:kernel) == "AIX" and Facter.value(:id) == "root"
|
|
57
74
|
if dev =~ /^\/\S+\s.*\s+(\S+)MB\s+(\S+)MB/
|
58
75
|
swaptotal += $1.to_i
|
59
76
|
swapfree += $2.to_i
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
63
80
|
Facter.add("SwapSize") do
|
64
81
|
confine :kernel => :aix
|
65
82
|
setcode do
|
@@ -154,9 +171,9 @@ if Facter.value(:kernel) == "SunOS"
|
|
154
171
|
if dev =~ /^\/\S+\s.*\s+(\d+)\s+(\d+)$/
|
155
172
|
swaptotal += $1.to_i / 2
|
156
173
|
swapfree += $2.to_i / 2
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
160
177
|
Facter.add("SwapSize") do
|
161
178
|
confine :kernel => :sunos
|
162
179
|
setcode do
|
data/lib/facter/netmask.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# Fact: netmask
|
2
|
+
#
|
3
|
+
# Purpose: Returns the netmask for the main interfaces.
|
4
|
+
#
|
5
|
+
# Resolution: Uses the facter/util/netmask library routines.
|
6
|
+
#
|
7
|
+
# Caveats:
|
8
|
+
#
|
9
|
+
|
1
10
|
# netmask.rb
|
2
11
|
# Find the netmask of the primary ipaddress
|
3
12
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
data/lib/facter/network.rb
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# Fact: network
|
2
|
+
#
|
3
|
+
# Purpose:
|
4
|
+
# Get IP, network and netmask information for available network
|
5
|
+
# interfacs.
|
6
|
+
#
|
7
|
+
# Resolution:
|
8
|
+
# Uses 'facter/util/ip' to enumerate interfaces and return their information.
|
9
|
+
#
|
10
|
+
# Caveats:
|
11
|
+
#
|
12
|
+
|
1
13
|
require 'facter/util/ip'
|
2
14
|
|
3
15
|
Facter::Util::IP.get_interfaces.each do |interface|
|
@@ -1,3 +1,16 @@
|
|
1
|
+
# Fact: operatingsystem
|
2
|
+
#
|
3
|
+
# Purpose: Return the name of the operating system.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# If the kernel is a Linux kernel, check for the existence of a selection of
|
7
|
+
# files in /etc/ to find the specific flavour.
|
8
|
+
# On SunOS based kernels, return Solaris.
|
9
|
+
# On systems other than Linux, use the kernel value.
|
10
|
+
#
|
11
|
+
# Caveats:
|
12
|
+
#
|
13
|
+
|
1
14
|
require 'facter/lsb'
|
2
15
|
|
3
16
|
Facter.add(:operatingsystem) do
|
@@ -1,3 +1,20 @@
|
|
1
|
+
# Fact: operatingsystemrelease
|
2
|
+
#
|
3
|
+
# Purpose: Returns the release of the operating system.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
# On RedHat derivatives, returns their '/etc/<variant>-release' file.
|
7
|
+
# On Debian, returns '/etc/debian_version'.
|
8
|
+
# On Ubuntu, parses '/etc/issue' for the release version.
|
9
|
+
# On Suse, derivatives, parses '/etc/SuSE-release' for a selection of version
|
10
|
+
# information.
|
11
|
+
# On Slackware, parses '/etc/slackware-version'.
|
12
|
+
#
|
13
|
+
# On all remaining systems, returns the 'kernelrelease' value.
|
14
|
+
#
|
15
|
+
# Caveats:
|
16
|
+
#
|
17
|
+
|
1
18
|
Facter.add(:operatingsystemrelease) do
|
2
19
|
confine :operatingsystem => %w{CentOS Fedora oel ovs RedHat MeeGo}
|
3
20
|
setcode do
|
data/lib/facter/path.rb
CHANGED
@@ -1,7 +1,56 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Fact: physicalprocessorcount
|
2
|
+
#
|
3
|
+
# Purpose: Return the number of physical processors.
|
4
|
+
#
|
5
|
+
# Resolution:
|
6
|
+
#
|
7
|
+
# Attempts to use sysfs to get the physical IDs of the processors. Falls
|
8
|
+
# back to /proc/cpuinfo and "physical id" if sysfs is not available.
|
9
|
+
#
|
10
|
+
# Caveats:
|
11
|
+
#
|
12
|
+
Facter.add('physicalprocessorcount') do
|
13
|
+
confine :kernel => :linux
|
3
14
|
|
4
|
-
|
5
|
-
|
15
|
+
setcode do
|
16
|
+
sysfs_cpu_directory = '/sys/devices/system/cpu' # This should always be there ...
|
17
|
+
|
18
|
+
if File.exists?(sysfs_cpu_directory)
|
19
|
+
#
|
20
|
+
# We assume that the sysfs file system has the correct number of entries
|
21
|
+
# under the "/sys/device/system/cpu" directory and if so then we process
|
22
|
+
# content of the file "physical_package_id" located inside the "topology"
|
23
|
+
# directory in each of the per-CPU sub-directories.
|
24
|
+
#
|
25
|
+
# As per Linux Kernel documentation and the file "cputopology.txt" located
|
26
|
+
# inside the "/usr/src/linux/Documentation" directory we can find following
|
27
|
+
# short explanation:
|
28
|
+
#
|
29
|
+
# (...)
|
30
|
+
#
|
31
|
+
# 1) /sys/devices/system/cpu/cpuX/topology/physical_package_id:
|
32
|
+
#
|
33
|
+
# physical package id of cpuX. Typically corresponds to a physical
|
34
|
+
# socket number, but the actual value is architecture and platform
|
35
|
+
# dependent.
|
36
|
+
#
|
37
|
+
# (...)
|
38
|
+
#
|
39
|
+
lookup_pattern = "#{sysfs_cpu_directory}" +
|
40
|
+
"/cpu*/topology/physical_package_id"
|
41
|
+
|
42
|
+
Dir.glob(lookup_pattern).collect { |f| Facter::Util::Resolution.exec("cat #{f}")}.uniq.size
|
43
|
+
|
44
|
+
else
|
45
|
+
#
|
46
|
+
# Try to count number of CPUs using the proc file system next ...
|
47
|
+
#
|
48
|
+
# We assume that /proc/cpuinfo has what we need and is so then we need
|
49
|
+
# to make sure that we only count unique entries ...
|
50
|
+
#
|
51
|
+
str = Facter::Util::Resolution.exec("grep 'physical.\\+:' /proc/cpuinfo")
|
52
|
+
|
53
|
+
if str then str.scan(/\d+/).uniq.size; end
|
6
54
|
end
|
55
|
+
end
|
7
56
|
end
|