블로깅 툴 변경

2007년을 맞아 블로깅 툴을 변경합니다. 기존에 사용하던 Wordpress가 사용하기에 부족한 것은 아니지만 좀 지겨워지기도 하고 계속 사용하던 wp-dokuwiki plugin의 무게에 점점 부담도 가고 해서요. 무거운 plug-in을 쓰다보니 스킨 하나 변경하기도 쉽지 않더군요.

무엇보다 블로그의 성격을 좀 가볍게 바꿔보려고 합니다. ^^

Tattertools, MovableType등과 비교해 보다가 결국 Textpattern으로 결정했습니다. 결정적으로 Textpattern의 한 스킨에 들어 있던 다음글에 넘어갔습니다. ^^

, if you have been using something else such as WordPress you are just going to find TXP different. There is no getting away from that fact. It doesn't look the same, it doesn't feel the same and it certainly doesn't work in the same way. It will take time for you to get used to it, but when you do, when that penny drops, you're going to wonder why all software isn't made this well. Seriously. And also remember that TXP is a CMS. It is not pure blogging software. It can be used for all kinds of different sites, even ones that don't have blogs. Yes I know. Sounds weird eh? No blog!

Textpattern에는 Wordpress나 MovableType을 포함한 몇개의 블로깅 툴에서 글을 import하는 기능이 있는데 여기서 작성한 문서들은 대부분 wp-dokuwiki로 작성한 문서라 별 소용이 없네요.

그래서 이전 blog/ 디렉토리 대신 blog-v2/ 디렉토리에 Textpattern을 설치했습니다. blog/ 디렉토리는 그대로 놔둘 것이기 때문에 기존 글들의 링크는 그대로 유지됩니다.

feed 관련해서는 feedburner에 등록된 주소를 그대로 blog-v2/ 의 것으로 변경할 예정입니다. 따라서 feedburner 주소를 가지고 계신 분들은 그대로 두시면 됩니다.

왠지 새 툴을 사용하려니 조금 설레는군요. :-)

Solaris 10 x86 in VMWare

얼마전 VMWare에서 solaris 10을 설치하고 vmware-tools를 설치하면 네트웍이 안된다는 내용을 쓴적이 있는데 잘못된 내용이었습니다. -_-;

vmware-tools를 설치할 때 나오는 내용을 꼼꼼히 읽어보면 나오는 내용이었네요. /etc 디렉토리의 *.pcn0 파일들을 *.vmxnet0 로 mv 해주면 됩니다.

매번 리눅스에서 vmware-tools 설치하면서 엔터만 쳐대는 버릇이 들어서 내용을 읽어볼 생각을 못했네요. -_-;

C file’s orientation 2.

이전글에서 했던 추측은 정답과는 거리가 멀었군요. c.l.c.m.에 올린 글의 답변을 보니 제가 stream의 state에 대한 생각을 전혀 안했었네요. -_-;

문제가 되었던 g++ 3.4.3, solaris 10-x86 환경에서는 현재 imbue되어 있는 locale로는 출력할 수 없는 character set을 만나면 state의 fail bit을 셋하게 되어 있었습니다. 이후 operation들은 현재 상태가 good()이 아니므로 모두 실패한 것이었습니다.

따라서 이전글에서 보았던 다음 코드들의 결과는 다음과 같이 다시 해석되어야 합니다.

 
wcout << L"aaaa" << endl;
wcout << L"한글bbbb" << endl;
wcout << L"cccc" << endl;
// result
aaaa
 
 
wcout << L"aaaa" << endl;
wcout << L"한글bbbb" << endl;
wcout << "cccc" << endl; // changed to byte-string literal
 
// result
aaaa
 
 
wcout << L"aaaa" << endl;
wcout << L"한글bbbb" << endl;
cout << "cccc" << endl; // changed to cout
 
// result
aaaa
cccc
 

"한글" 문자열 출력이 실패하면서 wcout의 state의 fail bit이 set됩니다. 따라서 이후 wcout에 대한 operation들은 모두 실패하게 됩니다. 하지만 마지막 경우의 cout은 wcout과는 전혀 다른 stream이므로 문자열이 정상적으로 출력되었던 것입니다.

결과 확인을 위해 다음 코드로 확인했습니다.

 
wcout << L"aaaa" << endl;
wcout << L"한글bbbb" << endl;
cout << "cccc" << endl; // changed to cout
cout << wcout.fail() << endl;
cout << cout.fail() << endl;
wcout.clear();
wcout << "cccc" << endl;
 
// result
aaaa
cccc
1
0
cccc
 

예상대로 clear()를 호출하여 state를 good() 상태로 만들어주면 다시 wcout으로도 정상적으로 출력됨을 확인할 수 있습니다. stream의 state와 cout, wcout의 관계를 생각하지 못해 전혀 엉뚱한 추측을 했었네요. 부끄럽습니다. *-_-*

추가로 "korean" locale을 imbue()해서 출력을 해보려고 했는데 지원을 안하더군요. -_-

그리고 이전 글에서 한글외의 모든 문자가 정상적으로 출력되었던 Redhat환경의 경우는 한글 출력을 할 수 없더라도 fail bit을 set하지 않아 한글외의 문자들이 정상적으로 출력되었던 것이었습니다.

C file’s orientation.

이전글의 마지막에서 언급했던 문제는 XMLCPP 라이브러리의 문제는 아니었습니다. 정확한 이유는 아직 찾지 못했지만 내용은 대략 다음과 같습니다.

C에서 각 stream들은 orientation이라는 것을 가지고 있습니다. 어떤 stream에 대해 처음 사용된 I/O 함수의 타입에 따라 그 stream은 byte-oriented나 wide-oriented가 됩니다. 일단 orientation이 적용되고 나면 다른 타입의 orientation용 I/O 함수는 적용되지 않습니다.1

이 orientation을 바꿀 수 있는 함수는 frepoen과 fwide 두개뿐입니다.

cin, cout, wcin, wcout과 같이 predefine된 C++ standard stream들은 위와 동일한 규칙을 따릅니다. 간단히 말하자면 char 버전과 wchar_t 버전의 함수들은 섞어서 쓸 수 없다는 얘기지요.

XMLCPP 에서 발생했던 문제는 wcout만을 사용하는데 ascii 범위를 벗어나는 문자를 출력하면 그 문자뿐 아니라 그 이후 아무 것도 출력되지 않는 문제였습니다. 이 경우 exception도 발생하지 않고요. -_-;

다음과 같은 코드로 문제를 재현할 수 있습니다. (g++ 3.4.3, solaris 10-x86)

 
wcout << L"aaaa" << endl;
wcout << L"한글bbbb" << endl;
wcout << L"cccc" << endl;
 
// result
aaaa
 

비슷한 코드로 좀 더 시험을 해보았지요.

 
wcout << L"aaaa" << endl;
wcout << L"한글bbbb" << endl;
wcout << "cccc" << endl; // changed to byte-string literal
 
// result
aaaa
 
 
wcout << L"aaaa" << endl;
wcout << L"한글bbbb" << endl;
cout << "cccc" << endl; // changed to cout
 
// result
aaaa
cccc
 

이 결과를 가지고 제가 해석한 원인은 다음과 같습니다.

  1. 먼저 wcout으로 L"aaaa"를 출력할때 wide-가 아닌 byte-oriented C function을 사용합니다. 이로 인해 내부 file(여기서는 stdout)의 orientation은 byte-로 셋팅됩니다.
  2. 일단 내부 file의 orientation이 byte-로 정해졌으므로 이후 모든 wcout 은 거부되고 cout만 처리됩니다.
  3. 여기서 처음의 wcout은 내부 file의 orientation이 정해지지 않았을 때이므로 그냥 수행되는 것으로 보입니다.

Redhat의 g++에서는 어떤 경우에 대해서도 모든 라인이 출력이 됩니다. 다만 wcout을 사용하는 경우에는 "한글"은 출력되지 않습니다. 이는 shell이 UTF-8을 지원하기 때문입니다. 즉, cout을 쓰면 그냥 8-bit 문자로 간주하여 file에 쓰게 되고 이것은 shell에 의해 UTF-8로 해석됨으로 정상적으로 한글이 보이게 됩니다. 따라서 redhat의 g++은 file의 orientation에 대한 규칙을 지키지 않는 것으로 보입니다.

어떤 것이 standard-ly correct(?)한 것인지 모르겠어서 c.l.c.m.에 일단 질문을 등록해 놓았습니다. :-)


  1. C99 7.19.2.4 [back]

The devil’s in the details.

정말 오랫만에 글을 쓰네요. XMLCPP 라이브러리 만드는데 재미를 붙여서 잠시 글쓰기를 안했더니 금방 글쓰기가 귀찮아지네요. 아니면 두려워진건지도... -_-;

최근에 했던 일은 XMLCPP에 autoconf를 적용하는 것이었습니다. autoconf란 소스 코드 패키지를 다양한 Posix-like 시스템에서 build할 수 있도록 도와주는 shell script를 만들어주는 도구입니다. 보통 소스 코드로 된 패키지를 구하면 하는 configure, make, make install의 과정이 대부분 autoconf가 만들어준 것들입니다.

왠지 configure하는 패키지들은 멋있어 보여 저도 한번 써보고 싶었는데 기회가 그간 없었지요. 일단 책을 보고 따라하기 하여 뚝딱뚝딱 적용을 했습니다. 이걸 적용하는데도 꽤나 까다로웠지요. 다음은 책에 나온 예제들에는 없어 헤맨 몇가지 사항들입니다.

  • $includedir 이 아니라 $includedir/xmlcpp 디렉토리에 헤더 파일을 install 하고 싶다.
  • make dist시에 tests 디렉토리 밑의 *.xml 파일도 tar되어야 한다. 하지만 install되진 않아야 한다.
  • make check시에 boost_unittest_framework으로 작성한 unit test가 수행되어야 한다.
  • --with-iconv 옵션을 추가한다.
  • boost 라이브러리 존재 여부를 검사해야 한다.

그래도 여기까지 작업 하고 나서 configure 실행시키면 쭈욱 올라가는 check list들을 보니 뿌듯하더군요. 이제 다음 단계로 제가 코딩한 Ubuntu 환경이 아닌 다른 환경에서도 정말 동작하는지 확인하기로 했습니다.

먼저 Redhat. 정말 다를게 없어보였습니다. 같은 리눅스라 그냥 되려니 생각했는데 make test하니 에러가 와장창 나더군요. ㅜㅜ

차이점은 gcc 버전... 검색해보니 특정 버전의 libstdc++.a 에 버그가 있더군요. fstream에 있는 버그인데 이로 인해 StreamCharDecoder에서 사용한 fs.readsome() 함수가 전혀 파일을 읽지 못했던 것이었습니다. 그래서 readsome()과 peek()를 사용하던 것을 바로 read(), gcount(), clear()를 사용하는 것으로 수정해서 Redhat으로의 포팅(? 좀더 정확히는 g++ 3.2.3으로의 포팅)은 성공.

다음으로 제가 access할 수 있는 Posix-like 시스템으로는 SunOS5.8과 윈도우에 설치한 Cygwin, MinGW등이 있었습니다. 그래서 다음으로 시도한 것이 SunOS 5.8. 이건 바로 포기가 되더군요. -_-;

XMLCPP는 XML 파싱을 위해 boost의 spirit 라이브러리를 사용하는데 boost의 문서를 읽어보니 저희 SunOS에 설치되어 있는 Sun WorkShop 6 update 2에 대해 다음과 같은 note가 있더군요.

The most recent reports seem to imply that this release is “hopeless for Boost”, but patches and workarounds are welcome.

다음은 Cygwin과 MinGW들에 도전해 보았습니다만 이것도 역시 포기... 이유는... Cygwin과 MinGW에서는 wstring과 wcout이 없답니다. ㅜㅜ

이러고 보니 성공한 플랫폼은 겨우 Ubuntu와 Redhat... 거의 똑같은 리눅스 두개... -_-; 하나는 더 있어야겠다 싶어 VMWare에 Solaris10을 인스톨하고 관련 개발 툴들을 인스톨했습니다. (회사에서 눈치를 봐가며 설치하느라 사흘이나 걸렸습니다. 게다가 OS 인스톨 다하고 다른 프로그램들 다 깔아 놓으면 네트웍이 안되는 바람에 세번이나 다시 OS를 깔았답니다. 원인은 Solaris 10용 vmware-tools는 버그가 있고 아직 수정된 버전은 없다는 것. ㅜㅜ)

결국 Solaris 10에서 g++을 사용하여 configure 성공... 이때도 그냥 configure로는 되지 않았고 --with-gnu-ld를 사용해야 되더군요. (끝까지 발목을 잡는 녀석들... -_-;)

떨리는 마음으로 make... 성공! make test... ... 성공!!! 비록 같은 g++을 사용한 것이지만 정말 기쁘더군요. 이제 그만 해야지 하는 마음으로 samples 디렉토리에 있는 xmlprint 프로그램으로 tests 디렉토리에 있는 utf8test.xml 파일을 읽어 보았습니다. 이게 왠일... ascii 범위를 벗어나는 문자가 시작되는 부분까지만 출력하고 중단되어버리더군요. ㅜㅜ

첫째로 든 생각은 또 실패했다는 oTL, 둘째로는 unit test들이 부족했나? 잘못 만들어졌나?라는 생각...

여기까지가 어제까지의 상태입니다. 이런 것들을 겪다보니 제목의 "The devil's in the details"라는 말이 자연스럽게 생각나더군요. -_-

내일부터 다시 Solaris 10으로의 포팅(?)에 도전해 볼 생각입니다. 해결되면 Solaris 10의 g++과 Linux의 g++의 차이점을 알게 되겠죠? 아님 또 버그? ㅜㅜ