xcal テスト

3ヶ月表示オプションを拡張する

オプションチェッククラスを眺めていたら”-3″や”+3″についても、”-m”同様に任意の年月に対する表示が簡単にできると気づきました。1ヶ月表示と3ヶ月表示の差はcalendarColsという表示月数の設定値のみ。さらに”-3″だけは表示開始月を1ヶ月前倒ししているだけなので、これら3つのスイッチはひとまとめに処理してしまいましょう。

class checkOption {
    private var arguments: [String]
    private var calendarRaws: Int
    private var calendarCols: Int
    private var weekFormat: Bool
    private var startYear: Int
    private var startMonth: Int
    private var adjustMonth: Int
    init(arguments: [String], calendarRaws: Int = 1, calendarCols: Int = 1, weekFormat: Bool = false,
            startYear: Int = 0, startMonth: Int = 0, adjustMonth: Int = 0) {
        self.arguments = arguments
        self.calendarRaws = calendarRaws
        self.calendarCols = calendarCols
        self.weekFormat = weekFormat
        self.startYear = startYear
        self.startMonth = startMonth
        self.adjustMonth = adjustMonth
    }
    func checkSwitch() {
        if arguments.count != 1 {
            switch arguments[1] {
            case "-y":
                calendarRaws = 4
                calendarCols = 3
                startMonth = 1
                if arguments.count == 3 {
                    startYear = Int(arguments[2])!
                }
            case "-m", "-3", "+3":
                if arguments.count == 3 {
                    startMonth = Int(arguments[2])!
                }
                if arguments.count == 4 {
                    startMonth = Int(arguments[2])!
                    startYear = Int(arguments[3])!
                }
                if arguments[1] != "-m" {
                    calendarCols = 3
                }
                if arguments[1] == "-3" {
                    adjustMonth = -1
                }
            case "-w":
                weekFormat = true
            default:
                calendarRaws = 0
                calendarCols = 0
            }
        }
    }
    func getCalendarRaws() -> Int {
        self.checkSwitch()
        return calendarRaws
    }
    func getCalendarCols() -> Int {
        self.checkSwitch()
        return calendarCols
    }
    func getWeekFormat() -> Bool {
        self.checkSwitch()
        return weekFormat
    }
    func getStartYear() -> Int {
        self.checkSwitch()
        return startYear
    }
    func getStartMonth() -> Int {
        self.checkSwitch()
        return startMonth
    }
    func getAdjustMonth() -> Int {
        self.checkSwitch()
        return adjustMonth
    }
}

“-3″表示の際に少しだけトリッキーなことをしていたのを仕様変更したので、”-3″のテストがエラーになりました。

オプションチェックテストエラー

この部分を修正するために、ほんの少しだけメインプログラムをいじりました。

7行目でd_flagのメンバーにadjustを、そして63行目でオプションチェックを追加し、70行目から73行目の3ヶ月表示ルーチンを書き換えています。

#! /usr/bin/swift
import Foundation
let month_odr: [String] = ["January", "Febrary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
let week_odr: [[String]] = [["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], ["日","月","火","水","木","金","土"]]
let esc = (fg_bk:"\u{001B}[0;30m", fg_mg:"\u{001B}[0;35m", bg_wt:"\u{001B}[1;47m", bg_gy:"\u{001B}[0;47m")
var curr = (year:0, month:0, day:0, week_m:0, week_y:0)
var d_flag = (raws:0, cols:0, week:false, year:0, month:0, adjust:0, je:0)
// シェル変数名を指定すると値を返す関数
func getEnvironmentVar(name: String) -> String? {
	guard let rawValue = getenv(name) else { return nil }
	return String(utf8String: rawValue)
}
// Date型の引数を受け取り、DateComponents型を返す関数
func getCalComp(date: Date) -> DateComponents {
    let cal: NSCalendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
    let components: DateComponents = cal.components([.year, .month, .day, .weekday,
                                                        .weekOfYear, .weekOfMonth], from:date)
    return components
}
// 一日始まりのDateComponents型の引数を受け取り、その月の配列を返す関数
func getCalendar(components: DateComponents) -> (cal_seq: [String], dayorder: Int, totaldays: Int) {
    var endofmonth: [Int] = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    var cal_seq: [String] = week_odr[d_flag.je]
    if (components.year! % 4) == 0 && (components.year! % 100) != 0 || (components.year! % 400) == 0 {
        endofmonth[2]+=1
    }
    for _ in 0..<42 {
        cal_seq.append("  ")
    }
    var datestring: String
    for var i in 1..<endofmonth[components.month!]+1 {
        if i < 10 {
            datestring = " \(i)"
        } else {
            datestring = "\(i)"
        }
        if components.year! == curr.year && components.month! == curr.month && i == curr.day {
            datestring = "\(esc.bg_gy)\(datestring)\(esc.bg_wt)"
        }
        cal_seq[ (6 + i) + (components.weekday! - 1) ] = datestring
    }
    var dayorder = curr.day
    var totaldays = 0
    for var i in 0..<curr.month {
        dayorder += endofmonth[i]
    }
    for var i in 1..<12+1 {
        totaldays += endofmonth[i]
    }
    return (cal_seq, dayorder, totaldays)
}
// 実質プログラムの始まり
if getEnvironmentVar(name:"LANG") == "ja_JP.UTF-8" {
	d_flag.je = 1
}
let arguments: [String] = CommandLine.arguments
var chkopt = checkOption(arguments: arguments)
d_flag.raws = chkopt.getCalendarRaws()
d_flag.cols = chkopt.getCalendarCols()
d_flag.week = chkopt.getWeekFormat()
d_flag.year = chkopt.getStartYear()
d_flag.month = chkopt.getStartMonth()
d_flag.adjust = chkopt.getAdjustMonth()
let now: Date = Date()
var cal_comp: DateComponents = getCalComp(date:now)
curr = (cal_comp.year!, cal_comp.month!, cal_comp.day!, cal_comp.weekOfMonth!, cal_comp.weekOfYear!)
if d_flag.year != 0 {
    cal_comp.year = d_flag.year
}
if d_flag.month != 0 {
    cal_comp.month = d_flag.month
}
cal_comp.month! += d_flag.adjust
cal_comp.day = 1
var sequence: [String] = []
var header: String = ""
var header_y: String = ""
var header_m: [String] = ["", "", "", "", "", "", "", "", "", "", "", ""]
var footer: String = ""
var limit = d_flag.raws * d_flag.cols
for var i in 0..<limit {
    var calen: Date = Calendar.current.date(from:cal_comp)!
    cal_comp = getCalComp(date:calen)
    var thismonth = getCalendar(components:cal_comp)
    sequence += thismonth.cal_seq
    footer += "(\(thismonth.dayorder)/\(thismonth.totaldays))\n"
    if (d_flag.cols == 3 && i == 1) || (d_flag.cols == 1 && i == 0) {
        header_y += "\(cal_comp.year!)"
    }
    if d_flag.je == 1 {
        header_m[i] = "\(cal_comp.month!)月"
    } else {
        header_m[i] = "\(month_odr[cal_comp.month! - 1])"
    }
    cal_comp.month!+=1
}
var length: Int
if d_flag.cols == 3 {
    length = (65 - header_y.characters.count) / 2
    for var i in 0..<length+1 {
        header_y = " " + header_y
    }
    print("\(header_y)\n")
}
var hol: [Int] = [0, 6]
for var l in 0..<d_flag.raws {
    if d_flag.cols == 3 {
        for var i in 0..<d_flag.cols {
            length = (21 - header_m[i + 3 * l].characters.count - d_flag.je) / 2
            for var j in 0..<length {
                header_m[i + 3 * l] = " " + header_m[i + 3 * l]
            }
            length = 22 - header_m[i + 3 * l].characters.count - d_flag.je
            for var j in 0..<length {
                header_m[i + 3 * l] = header_m[i + 3 * l] + " "
            }
            header += header_m[i + 3 * l]
        }
    } else {
        header = "\(header_m[0]) \(header_y)"
        length = (21 - header.characters.count - d_flag.je) / 2
        for var j in 0..<length {
            header = " " + header
        }
    }
    print(header)
    header = ""
    for var i in 0..<7 {
        if !(d_flag.week) || ((d_flag.week) && ((i == 0) || (i == curr.week_m))) {
            for var j in 0..<d_flag.cols {
                for var k in 0..<7 {
                    for l in hol{
                        if l == k {
                            print(esc.fg_mg, terminator:"")
                        }
                    }
                    print("\(sequence[i * 7 + ((j + 3 * l) * 49 + k)])\(esc.fg_bk) ", terminator:"")
                }
                print(" ", terminator:"")
            }
            print("\n", terminator:"")
        }
    }
    if (d_flag.week) {
        print("US Week \(curr.week_y) \(footer)")
    }
}

今年のゴールデンウイークはどんな並びだろう?とか、年末年始の休暇はどうなるだろう?などということがわかりやすくなりました!☆*:.。. o(≧▽≦)o .。.:*☆

拡張3ヶ月表示結果