月別アーカイブ: 2014年1月

Arrays of Arrays

動的配列みたいなワード検索するとよく見かける C 言語コード

#include <stdio.h>

#define MAX_LENGTH 1024

int
main (int argc, char** argv) {

    int count,i;
    char** arg;
    count = 3;
    /* 開始 */
    arg = (char**)malloc(sizeof(char*) * count);
    i = 0;
	for (i; i<count; i++) {
        arg[i] = (char*)malloc(sizeof(char) * MAX_LENGTH);
        sprintf(arg[i], "malloc %03d", i);
    }
    /* printf と破棄 */
    i = 0;
    for (i; i<count; i++) {
        printf("%s\n", arg[i]);
        free(arg[i]);
    }
    free(arg);
    return 0;
}

c_aoa

これだと gcc は盛大に Warning を吐いてくれるのね。
ポインタのポインタが配列の配列だと認識できないのかな?
先頭要素のポインタを一つ分オフセットすれば次の要素のポインタ…
って今なら普通に解るけどスゲェ理屈だよな。

minipoli で使っている C++ 式というか new でなら問題無い。
TCHAR を使っているし解りづらいので少し書き換えて。

#include <stdio.h>

const int MAX_LENGTH = 1024;

int
main (int argc, char** argv) {

    int count = 3;
    // 開始
    char** arg = new char* [count];
	for (int i=0; i<count; i++) {
        arg[i] = new char[MAX_LENGTH];
        sprintf(arg[i], "new %03d", i);
    }
    // cout と破棄
    for (int i=0; i<count; i++) {
        printf("%s\n", arg[i]);
        delete[] arg[i];
    }
    delete[] arg;
    return 0;
}

C++ なのに何故 stdio なんだよとあの頃の自分にツッコミしたい。
VisualStudio でプログラミングを始めるとそうなっちゃうんだよなぁ。
Linux で C++ は実用面では避けたいんだが、gtkmm ワカンネエし。

GLib に GArray というものがあるので使ってみる。

#include <glib.h>

#define MAX_LENGTH 1024

int
main (int argc, char** argv) {

    GArray* array;
    gchar   c[MAX_LENGTH];
    gint    count, i;

    count = 3;
    /* 開始 */
    array = g_array_new(TRUE, TRUE, sizeof (gchar*));
    i = 0;
    for (i; i<count; i++) {
        g_sprintf(c, "GArray %03d", i);
        gchar* temp;
        temp = g_strdup(c);
        g_array_append_val(array, temp);
    }
    /* printf 破棄は不要 */
    i = 0;
    for (i; i<array->len; i++) {
        g_print("%s\n", g_array_index(array, gchar*, i));
    }
    /* 第二引数 TRUE で中身も破棄 */
    g_array_free(array, TRUE);
    return 0;
}

そうか、あらかじめポインタの領域が確保されているわけじゃないもんな。
一度新な領域を確保してポインタを入れる必要があるわけだ。
公式サンプルコードなら簡単だけど成形するとなると一手間掛かる。
GLib のほうが面倒臭いなんて初めて見た。

うーん、どれもイマイチだ。
次は GList でも調べるか。

Here Document

ヒアドキュメントが便利なのでもう少し調べる。
Y901x のインストールスクリプトで使っているから経験はあるのだが。

ヒアドキュメント – Wikipedia

シェルスクリプトはバッククォーテーションでコマンドも使えるのか。

#!/bin/sh

func() {
    echo バッククオートで関数も使える
}
shstr=シェルスクリプト
hdstr=ヒアドキュメント

cat << __EOS__
${shstr}で$hdstrは今更だけど
最初の改行は無視される、最後は echo や cat が改行する
エスケープ文字 \\ は有効
記号は\$とバッククオートを除いて <'"{[+=~ と普通に使える
`func`
__EOS__

自作関数でもいいようだ。

# output
シェルスクリプトでヒアドキュメントは今更だけど
最初の改行は無視される、最後は echo や cat が改行する
エスケープ文字 \ は有効
記号は$とバッククオートを除いて <'"{[+=~ と普通に使える
バッククオートで関数も使える

これはもしかして PHP でも関数が使えるかも。

<?php

function func() { return "関数"; }
$plstr = "Perl";
$shstr = "シェルスクリプト";

echo <<< __EOS__
PHP は${shstr}や $plstr 同様に利用できる
最初と最後の改行は無視されるので最後は一行開けるとよし
エスケープ文字 \\ は有効
記号は\$を除いて <'"{[+=~` と普通に使える
`func` って PHP にこんな機能はもともと無いよ!

__EOS__;
/* output
PHP はシェルスクリプトや Perl 同様に利用できる
最初と最後の改行は無視されるので最後は一行開けるとよし
エスケープ文字 \ は有効
記号は$を除いて <'"{[+=~` と普通に使える
`func` って PHP にこんな機能はもともと無いよ!
*/
?>

んなわけないか。
ところで PHP のヒアドキュメントは最後を改行しなくて最初戸惑った。
よく考えたら echo, cat, print() が改行していただけだった。
PHP の echo は改行しないもんね。

Perl や Lua って Fedora に最初から入っているけど使ったことが無いな。
余程のことがないかぎり今後も使うことは無いと思うけど。
GNOME は以前 JavaScript を押していたけど今はどうなんだろう?

// Gjs
// imports /usr/share/gjs-1.0/format.js

const Format = imports.format;

String.prototype.format = Format.format;

let jstr = "\
JavaScript はエスケープで強引な改行しか手段が無い\n\
更に%s機能は無い\n\
しかし %s ならこんなことができる\n\
%%s, %%d, %%x, %%f のみ";

print(jstr.format("文字列フォーマット", "Gjs"));
/*
JavaScript はエスケープで強引な改行しか手段が無い
更に文字列フォーマット機能は無い
しかし Gjs ならこんなことができる
%s, %d, %x, %f のみ
*/

これだものな。
面倒臭くなってブン投げたのは筆者だけではないと思う。

#include <stdio.h>

#define CSTR "\
%s は\n\
説明不要だよね\n"

int
main (int argc, char ** argv) {
	printf (CSTR, "C 言語");
	return 0;
}
/*
C 言語 は
説明不要だよね
*/

C のほうが簡単なんて洒落にもならん。
プラス記号で成形するのって最初は分かり易いのでいいと思うが。

#!/usr/bin/env python3

DOCSTR = """{0} はお馴染 {1}
最初と最後の改行も有効だけど print が最後を改行する
{2}
{1} は \\ エスケープが有効"""

def func():
    return "関数は format で実行すれば文字列さ"

print(DOCSTR.format("Python", "docstring", func()))

''' output
Python はお馴染 docstring
最初と最後の改行も有効だけど print が最後を改行する
関数は format で実行すれば文字列さ
docstring は \ エスケープが有効
'''

あぁ楽チン、やっぱりコレだよコレ!

しかしやっぱりヒアドキュメントに変数を直書きできたほうが便利。
それには $ 記号を変数に利用する言語しか無理なんだろうな。
と思っていました。

// Vala

const string DOCSTR = """Python と同じ
%s も使える、でも ''' は使えない
何故か \\ エスケープ\nは使えない
""";

string func() { return "無理"; }

int main (string[] args) {
    string one = "Vala";
    string tow = "ヒアドキュメント";
    stdout.printf(@"$one は実は@\"\"を使って$towもどきが利用できる
ですが$${one}みたいなブレース表記はダメみたい
最初と最後の改行も有効、エスケープ文字 \\ は有効
記号は$$と\"を除いて <'{[+=~` と普通に使える
`func` は当然不可能\n\n");
    //
    stdout.printf(DOCSTR, "docstring");
    return 0;
}
/* output
Vala は実は@""を使ってヒアドキュメントもどきが利用できる
ですが${one}みたいなブレース表記はダメみたい
最初と最後の改行も有効、エスケープ文字 \ は有効
記号は$と"を除いて <'{[+=~` と普通に使える
`func` は当然不可能

Python と同じ
docstring も使える、でも ''' は使えない
何故か \\ エスケープ\nは使えない
*/

Vala はやってくれました。
おかげで解った、滅茶苦茶使い辛いということを。
これなら docstring 方式のほうがいいや。

最後に、Gedit の色分けってスゴすぎる!

gedit

まさかこの Vala の $ 変数を見分けて色分けするとは思わなかった。
PHP 部分と HTML 部分をしっかり見分けるとかは知っていたが。
どの言語でもヒアドキュメント内でマズい記号を打つと即座に色が変わる。
これがデフォルトエディタって GNOME 恐るべしだよ。

PHP

サイト整理はひとまず一段落。
内容の書き換えだけでなく久々に PHP をやったので少し覚書。

今まで sakura サーバーに上げた奴と local で動作が違う場合があったが

<?
    // sakura はコレで PHP 処理をする設定になっている
?>
<?php
    // local で動かしている httpd は PHP 宣言必須な設定
?>

こんな単純なことだった、<?php としたら当然のように同じ動作に。
何故今まで気が付かなかったのだろう、私ってほんとバカ。

AdSense を localhost で表示させない手段も変更。
表示確認で幾度もリロードするし誤クリックしてしまうのも防ぎたいので。

google.txt みたいなファイルを用意し AdSense スクリプトを書き込む。
ソレを Web に上げ local ファイルは違う内容にして都度読み込みコードに。
というかなり苦しい手段をずっと使っていたけど

<?php
$sitename = "L'Isola di Niente";
$hostname = $_SERVER['SERVER_NAME'];
$foottext = "Copyright(C) sasakima-nao All rights reserved 2002 --- 2014.";

if ($hostname == "localhost") {
    $google = <<< __EOF__
    // local 用 HTML
__EOF__;
} else {
    $google = <<< __EOF__
    // AdSense 表示スクリプト
__EOF__;
}
?>

http://localhost かどうかで振り分けすればいいジャン!
これで Web 上と local の構成をまったく同じにしても問題なくなった。

そんなわけで今までヘッダ部分はこんな感じにしていたけど

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width" />
<title><?php print($title); ?> - L'Isola di Niente</title>
<link href="../style.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div align="center">
<img alt="L'Isola di Niente" src="../img/banner1.gif" /><br />
<?php print(file_get_contents("../google.txt")); ?>
<div class="mainBlock">
<div class="entry"><a href="/">L'Isola di Niente</a> &raquo; <?php print($title); ?></div>

ヒアドキュメントというものがあったのさ。

<?php
require_once("../theme/vars.php");
echo <<< __EOF__
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width" />
<title>$title - $sitename</title>
<link href="../style.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div align="center">
<img alt="$sitename" src="../img/banner1.gif" /><br />
$google
<div class="mainBlock">
<div class="entry"><a href="/">$sitename</a> &raquo; $title</div>
__EOF__;
?>

Gedit のかなり優秀な色分け表示が台無しになってしまうのが難点。
しかし変数を自由に直書きできる魅力は捨て難い。

んでカテゴリ毎に点在させていたヘッダは共通ファイルを読み込むように。
サイト名を変更する場合も変数一つ変更すれば全ページに適用される。
SyntaxHighlighter 部分だけはカテゴリ別読み込みにしているけど。

ウチは三階層あるので三つ用意したが一つにまとめたいな…
CMS ツールなら単層にできるけど自力でやりたい。

こんなことイイな、できたらイイな。
を実現するのがプログラミングの楽しみですから。
PHP も自力で色々やってみると面白い、今年は Web メインかな。

GNOME Developer Platform Demos

GNOME Developer Platform Demos

ナイスなページ発見。
GNOME プロジェクトは何時の間かにこんなのを作っていた。

JavaScript はもう Gjs にしなさいみたい。
C, C++, Vala は Anjuta を使うのを前提にしているんだなぁ。

しかし Python だけ妙に詳しくて笑う。

インストールはこんな方法があるのか、autoreconf なんて知らなかった。
しかし print に括弧が無い、Python2 でまだいいよってことですか。
試したら本当にインストールできたけど…
先頭に #!/usr/bin/env python が無いので動かないwwwww
わざと?

Tutorial for beginners (Python)

アプリケーションメニュー(GMenu)はこうやればよかったのか。
GtkSwitch の notify::active なんて devhelp に載っていないんですけど…
とにかく参考になるわ、筆者はビギナー達の一人だったのか。

Python3 urllib

今日 Python3 で URI デコードをやろうとした。

Python 3 Porting Guide ? Porting to Python 3 v1 documentation
Python2 との違い一覧を作ってくれている人がいる、アリガトメルシー。
urllib.unquote は urllib.parse.unquote なのね。

#!/usr/bin/env python3

import urllib
print(dir(urllib))

''' output
['__builtins__', '__cached__', '__doc__', '__file__', '__initializing__', '__loader__', '__name__', '__package__', '__path__']
'''

import urllib.parse
print(dir(urllib))

''' output
['__builtins__', '__cached__', '__doc__', '__file__', '__initializing__', '__loader__', '__name__', '__package__', '__path__', 'parse']
'''

なんだこりゃ…

quote

当然そうなるよな、何故だ?
/usr/lib64/python3.3/urllib
を覗いてみると

urllib_zerobyte

__init__.py が 0 byte だとこういう動作になるってことなのか。
なるほど、多分どこかでこの知識が役に立つだろう。

#!/usr/bin/env python3

import urllib.parse
from gi.repository import GLib

uri = "file:///path/to/My%20Waifu.jpg"

path = urllib.parse.unquote(uri)
print(path) #=> file:///path/to/My Waifu.jpg

path, host = GLib.filename_from_uri(uri)
print(path) #=> /path/to/My Waifu.jpg

ただ unquote だと file:/// とかは普通に残るんだよな。
ホスト名があった場合(LAN 上ファイル等)も面倒だし。
Linux なら GLib を使ったほうがいいや。
こんな楽な手段を知っているので Python モジュールの知識が全然無いというのも考え物だな。