2009. 5. 3. 01:07

Trac 한글 번역에 참여하기

Trac이란 무엇인가?
일단 이 글을 읽으시는 분들은 Trac이 무엇을 하는 툴인지 모두 아실거라고 생각합니다.
하지만 혹시나 Trac이 뭔지 모르시는 분들을 위해서 간단하게 설명을 드리겠습니다.
 * 홈페이지 : http://trac.edgewall.org/
 * 파이썬(Python) 언어로 작성된 이슈 관리 시스템입니다.(Trac에서는 티켓이라고 표현합니다.)
 * 비슷한 툴로는 Mantis, Bugzilla 등이 있습니다.


Trac 번역 방법의 변경
초기의 Trac의 한글 번역은 파이썬 소스코드에 하드 코딩되어있는 스트링을
한글로직접 번역하는 형태로 진행되었습니다.
다음 URL이 KLDP.NET에서 진행되던 Trac 한글 번역 프로젝트 URL 입니다.
 * http://kldp.net/projects/trac-ko/
 * KLDP.NET에서 진행되던 Trac 한글 번역 프로젝트의 마지막 릴리즈는 0.10.4-ko 버전이 마지막 버전입니다.

최근의 Trac의 번역은 po 파일을 이용한 번역으로 변경되었습니다.

Trac의 마일스톤을 보시면 아시겠지만, Trac-0.12 버전에서 i18n과 localization 기능이 추가중에 있습니다.
 * http://trac.edgewall.org/milestone/0.12
 * 즉, Trac-0.12 버전에서는 각 언어별로 번역을 완벽하게 지원하겠다는 의미입니다.


현재 Trac에서의 한글 번역 상황
Trac-0.12 버전을 위한 한글 번역 상황은 다음 URL에서 확인하실 수 있습니다.
 * http://trac.edgewall.org/ticket/5477


Trac 한글 번역에 참가하는 방법
 * 최신의 한글 번역용 po 파일을 다운로드 받습니다.
   * http://trac.edgewall.org/browser/trunk/trac/locale/ko_KR/LC_MESSAGES

 * 번역을 하기 위해서 poEdit를 다운로드 받아서 설치합니다.
 * 이제 번역을 합니다.
 * 번역이 완료된 po 파일을 Trac-0.12 버전의 한글 번역과 관련있는 다음 티켓에 첨부파일로 첨부합니다.
   * http://trac.edgewall.org/ticket/5477


아직까지는 Trac-0.12 버전이나, Trac-0.12 버전을 위한 한글번역 상태가 그다지 좋지는 못한 것 같습니다.
하지만 많은 분들이 참여하셔서 좋게 만들면 되겠죠.. ^^;

올해안에 한글이 완벽하게 지원되는 Trac-0.12 버전의 릴리즈를 기다려봅니다.

참고 : 개발 버전의 Trac-0.12 버전에서 한글을 활성화하는 방법은 다음 문서를 참고하세요.
 * http://ktd2004.tistory.com/3
2009. 4. 28. 21:32

제가 항상 사용하는 파이어폭스(Firefox) 플러그인

FireGestures
마우스를 사용해서 파이어폭스를 컨트롤할 수 있는 플러그인입니다.
예전에는 All-In-One Gestures를 사용했습니다.
사용하다가 보니까 FireGestures가 더 낫더군요.


IE Tabs
웹을 돌아다니다 보면 인터넷 익스플로러에서만 동작하는 웹이 있죠.
ActiveX를 설치해야 된다거나 하는 사이트에서 IE 모드로 동작하도록 하는 플러그인입니다.
(물론 IE 모드에서는 파이어폭스의 다른 플러그인들이 동작하지 않습니다.)
윈도우 파이어폭스를 사용하는 사용자라면 반드시 설치해야겠죠.


Easy DragToGo
마우스로 링크를 드래그 앤 드랍하면 탭을 열어주는 플러그인입니다.
사용해 보시면 아시겠지만, 무척 편리한 플러그인입니다.


Download Statusbar
이름이 비슷한 Download status와 혼동하지 마세요..
한동안 Download status를 설치하고, 왜 동작이 이렇게 변했지라고 한참을 고민했었습니다.


Adblock Plus
광고를 막아주는 플러그인입니다.
웹페이지의 로딩 속도를 조금은 높여줄 수 있겠죠..


이 외에도 정말 많은 파이어폭스 플러그인이 존재합니다.
다음 사이트를 방문하셔서 한 번 둘러보시는 것도 괜찮을 것 같네요..
https://addons.mozilla.org/ko/firefox

2009. 4. 28. 21:21

우분투 9.04 키보드 설정

1. 우분투 9.04 한글 키보드 설정
시스템/기본 설정/키보드
  • 키배치의 키보드 모델을 일본 106키로 되어있는 것을 한글 106키로 변경합니다.
  • 키배치의 키배치를 대한민국으로 변경


2. 우분투 9.04 한글 SCIM 설정
프론트엔트/전체 설정
  • 전환키에서 Shift+Space 추가(저는 한영전환에 Shift+space를 사용합니다.
  • 끄기에 Ctrl+[, ESC 키를 추가합니다.
끄기에 추가하는 내용은 ESC키를 눌렀을 때,
한글 입력모드에서 자동으로 영문모드로 변환되게 하기 위해서입니다.
2009. 4. 27. 23:21

doxygen 초간단 사용법

소스코드 문서화 프로그램 doxygen의 초간단 사용법을 적어볼까 합니다.

 

doxygen을 사용한 소스코드의 문서화는 다음과 같은 절차로 이루어집니다.

  1. 문서화할 소스코드(C 파일들)가 있다
  2. doxygen을 다운로드 받는다
  3. doxygen용 설정파일(Doxyfile)을 생성한다.
  4. doxygen용 설정파일(Doxyfile)을 내 환경에 맞게 편집한다.
  5. doxygen을 실행한다.

 

 

자 그럼 각 단계별로 살펴볼까요.

 

문서화할 소스코드(C 파일들)가 있다.

  • 기존에 소스코드가 있다면, 문서화할 수 있습니다.
  • 하지만 완벽한 문서화를 위해서는 소스코드에 doxygen이 인식할 수 있도록 주석이 달려있어야 합니다.
  • 하지만 doxygen용 주석이 달려있지 않아도 문서화된 결과물은 확인할 수 있습니다.

 

 

doxygen을 다운로드 받는다.

  • http://www.stack.nl/~dimitri/doxygen/
  • doxygen 홈페이지에서 해당 OS에 맞는 설치파일이나 압축 파일을 다운로드 받아서 설치하거나 압축을 풀고 PATH가 연결된 디렉토리에 넣어두면 됩니다.

 

 

doxygen용 설정파일을 생성한다.

  • doxygen용 설정파일의 이름은 특별히 주어지지 않으면 Doxyfile입니다.
  • 기존에 doxygen으로 문서화를 진행하던 프로젝트 혹은 소스코드라면 doxygen용 설정파일인 Doxyfile이 있을 것입니다.
  • 이전 버전의 doxygen용 설정파일을 현재 사용하고 있는 doxygen용 설정파일로 업그레이드하기

 

doxygen -u [configName]

 

 

 

기존에 doxygen용 설정파일이 없어서 새롭게 doxygen용 설정파일인 Doxyfile을 만들기

 

doxygen -g [configName]

 

 

 

 

doxygen용 설정파일(Doxyfile)을 내 환경에 맞게 편집한다.

생성된 Doxyfile을 텍스트 편집기로 열어보면 수많은 설정항목들이 있습니다.

(모두 영어로 되어있고, 정말 많습니다. ^^;)

각 항목들은 영어를 이해하시던지, 매뉴얼을 참고하셔야 합니다.

지금은 Doxyfile을 그대로 사용하는 것으로 하죠.

 

 

이제 doxygen을 실행해서 소스코드의 문서를 생성합니다.

 

doxygen

 

 

 

이제 소스코드에 대한 문서가 생성되었습니다. ^^;

이 글은 스프링노트에서 작성되었습니다.

2008. 11. 16. 12:07

main 함수의 정확한 선언

int main(void);

int main(int argc, char *argv[]);
int main(int argc, char **argv);

/* argv 데이타와 주소를 변경하고 싶지 않을 때 */
int main(int argc, const char * const argv[]);
int main(int argc, const char * const * argv);



명령행 데이타를 argc, argv 형태로 변환하는 함수
#include <stdio.h>
#include <string.h>

/*! \brief 최대한 받아들이는 argument 갯수 */
#define MAX_ARG         10

/*! \brief argv용 버퍼의 최대 크기 */
#define MAX_CMDLEN      256


/*! \brief 입력된 명령행 버퍼를 argc, argv 형태로 변환하는 함수
 *
 * \param buf : 명령행으로 입력된 버퍼 포인터
 * \param argv [OUT] : 변환된 argv 형태의 포인터 배열
 *
 * \return argc 값 */
int parse_argument( const char *buf, char *argv[])
{
    int i,j;
    char ch;
    int len;
    int argc;
    int firstChar;

    /* 외부에서 포인터로 접근하기 위한 static 배열 */
    static char argv_buf[MAX_CMDLEN+1];

    len = strlen( buf);

    argc = 0;
    firstChar = 1;
    for( i=0,j=0; i<len; ++i) {
        ch = buf[i];

        /* 공백 문자다. 하나의 argument 끝 */
        if( ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
            if( firstChar == 0) {
                argv_buf[j] = '\0';

                ++j;
                ++argc;

                argv[argc] = NULL;

                firstChar = 1;

                if( j == MAX_CMDLEN || argc == MAX_ARG) {
                    break;
                }
            }
            continue;
        }

        if( firstChar == 1) {
            argv[argc] = &argv_buf[j];
            firstChar = 0;
        }
        argv_buf[j] = ch;
        ++j;
        if( j == MAX_CMDLEN) {
            argv_buf[j] = '\0';
            break;
        }
    }
    if( firstChar == 0) {
        argv_buf[j] = '\0';

        ++argc;

        argv[argc] = NULL;
    }

    return argc;
}


/*! \brief 테스트 함수 */
void CTestDlg::TestFunc(void)
{
    int i;

    const char *input = "  aaaaaaaaa abc 333 444 555 777 bbbbbbbb  ";

    int argc;
    char *argv[MAX_ARG];

    argc = parse_argument( input, argv);

    printf("argc : %d\n", argc);
    for( i=0; i<argc; i++) {
        printf("%d : %s\n", i, argv[i]);
    }

    printf("argv[argc] : %d\n", argv[argc]);
}




main 함수의 두번째 인자(argv)가 왜 const가 아닌가?
 * 다음 테스트 프로그램을 돌려보자.
int main(int argc, char *argv[])
{
    int i;

    printf("argc : %d\n", argc);
    for( i=0; i<argc, ++i) {
        printf("%d : %s\n", i, argv[i]);
    }

    strcpy( argv[0], "0123456789012345678901234567890123456789012345678901234567890123456789");

    printf("argc : %d\n", argc);
    for( i=0; i<argc, ++i) {
        printf("%d : %s\n", i, argv[i]);
    }
}

 * 이 테스트 프로그램을 위 parse_argument 함수에 적용해보면 똑 같은 결과가 나옴을 알 수 있다.
 * 즉, 내부 구현이 비슷함을 알 수 있다.


표준에서의 main 함수의 두번째 인자의 const 여부
 * C99에서의 언급
The parameters argc and argv and the strings pointed to by the argv array shall
be modifiable by the program, and retain their last-stored values between
program startup and program termination.

* C90 그리고 C++98 에서의 언급
   * C++은 C90에 기초하고, C90 표준을 subset로 가지고 있다.
In C90 it is mentioned:


"Program startup"

The function called at program startup is named main . The
implementation declares no prototype for this function. It can be
defined with no parameters:

int main(void) { /*...*/ }

or with two parameters (referred to here as argc and argv , though any
names may be used, as they are local to the function in which they are
declared):

int main(int argc, char *argv[]) { /*...*/ }


If they are defined, the parameters to the main function shall obey
the following constraints:

* The value of argc shall be nonnegative.

* argv[argc] shall be a null pointer.

* If the value of argc is greater than zero, the array members
argv[0] through argv[argc-1] inclusive shall contain pointers to
strings, which are given implementation-defined values by the host
environment prior to program startup. The intent is to supply to the
program information determined prior to program startup from elsewhere
in the hosted environment. If the host environment is not capable of
supplying strings with letters in both upper-case and lower-case, the
implementation shall ensure that the strings are received in
lower-case.

* If the value of argc is greater than zero, the string pointed to by
argv[0] represents the program name ;argv[0][0] shall be the null
character if the program name is not available from the host
environment. If the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent the program
parameters .

* The parameters argc and argv and the strings pointed to by the argv
array shall be modifiable by the program, and retain their
last-stored values between program startup and program termination.

2008. 7. 9. 19:41

Subversion의 commit과 Trac 연동하기...(Subversion, Trac, post-commit, trac-post-commit-hook)


Subversion에서 commit하면 자동으로 Trac의 티켓 닫기
일단 다음과 같이 가정합니다.
  • Subversion 저장소 : /var/TEST
  • Trac 저장소 : /var/TEST.TRAC

Subversion의 post-commit 훅 스크립트
  • /var/TEST/hooks/post-commit 스크립트 파일
  • 원래의 파일 이름은 post-commit.tmpl 입니다. 이 파일의 이름을 post-commit 으로 변경하고, 실행 속성을 주어야 합니다.

SVNLOOK=/usr/local/bin/svnlook

REPOS="$1"
REV="$2"

LOG=`$SVNLOOK log -r "$REV" "$REPOS"`
AUTHOR=`$SVNLOOK author -r "$REV" "$REPOS"`
DIRS="`$SVNLOOK dirs-changed -r "$REV" "$REPOS"`"

$REPOS/hooks/trac-post-commit-hook.py -p /var/TEST.TRAC -r "$REV" -u "$AUTHOR" -m "$LOG"



Trac의 trac-post-commit-hook.py 파일
  • 사용하고 있는 trac의 소스에 보면 contrib/trac-post-commit-hook 파일이 있습니다.
  • 이 파일을 /var/TEST/hooks 디렉토리에 복사합니다. 이 위치는 post-commit 파일에 명시된 위치와 동일합니다.


주의 사항
  • 위에서 언급한 두개의 파일은 모두 실행 속성을 가지고 있어야 한다.


Subversion commit시에 Trac의 티켓에 영향을 미치도록 commit message 작성하기
다음과 같은 동작을 수행할 수 있습니다.
  • 티켓 자동으로 닫기
  • 티켓에 자동으로 comment 추가하기
trac-post-commit-hook.py 파일을 보면 다음과 같이 설명이 자세히 나와있습니다.

# It searches commit messages for text in the form of:
#   command #1
#   command #1, #2
#   command #1 & #2
#   command #1 and #2
#
# Instead of the short-hand syntax "#1", "ticket:1" can be used as well, e.g.:
#   command ticket:1
#   command ticket:1, ticket:2
#   command ticket:1 & ticket:2
#   command ticket:1 and ticket:2
#
# In addition, the ':' character can be omitted and issue or bug can be used
# instead of ticket.
#
# You can have more then one command in a message. The following commands
# are supported. There is more then one spelling for each command, to make
# this as user-friendly as possible.
#
#   close, closed, closes, fix, fixed, fixes
#     The specified issue numbers are closed with the contents of this
#     commit message being added to it.
#   references, refs, addresses, re, see
#     The specified issue numbers are left in their current status, but
#     the contents of this commit message are added to their notes.
#
# A fairly complicated example of what you can do is with a commit message
# of:
#
#    Changed blah and foo to do this or that. Fixes #10 and #12, and refs #12.
#
# This will close #10 and #12, and add a note to #12.

즉, Subversion commit 메시지에 특정 스트링을 넣으면, Trac의 티켓이 자동으로 변경됩니다.

Subversion commit과 함께 5, 10번 티켓을 닫을려면 다음과 같이 사용할 수 있다.
"close" 대신에 "closed", "closes", "fix", "fixed", "fixes" 등을 사용할 수도 있다.

close #5, #10
close #5 & #10
close #5 and #10
close ticket:5, ticket:10



Subversion commit과 함께 commit 메시지를 5번, 10번 티켓의 comment로 추가하려면...
"refs" 대신에 "references", "addresses", "re", "see"등을 사용할 수도 있다.

refs #5, #10
refs #5, #10
refs #5 & #10
refs #5 and #10
refs ticket:5, ticket:10


자. 이제 Subversion에서 commit을 하면, 자동으로 Trac의 관련 티켓이 닫히거나, comment가 추가되게 됩니다.


참고로 말씀 드립니다.
오늘 서점에 갔다가 "윈도우 프로젝트 필수 유틸리티"란 책을 보았습니다.
이 책에 윈도우 환경에서 Subversion과 Trac을 연동하는 방법이 아주 잘 설명되었습니다.
참고하시기 바립니다.
2008. 6. 25. 21:55

세계 시간 확인하기

프로그래밍을 작성하다보면 세계 시간을 확인해야할 때가 많습니다.
  • 물론 global market을 염두에 두었을때겠죠.


그런 경우에 사용하면 좋을 것 같은 사이트를 하나 소개해 드리겠습니다.


이 사이트가 제공하는 기능들을 살펴보겠습니다.
  • 먼저 각 나라/도시별로 현재시간(localtime)을 알려줍니다.
  • 물론 해당 지역의 DST(Daylight Saving Time, Summer Time)여부도 알 수가 있습니다.
  • 그리고 DST가 언제 시작되고, 언제 끝나는지도 알 수가 있습니다.
  • 각 지역의 현재 날씨도 알려줍니다.

시간과 관련된 몇가지 용어를 말씀드리면 다음과 같습니다.
GMT : 영국에 있는 그리니치 천문대에서의 LocalTime입니다. 이 시간은 UTC와 동일합니다.

UTC : 세계 표준 시간입니다. 전 세계 어디에서나 완전히 일치하는 유일한 시간이죠

LocalTime : 각 지역별 시간입니다. 한국은 오전 9시면, 영국은 자정이죠.

DST : Daylight Saving Time 혹은 Summer Time이라고도 합니다.
해가 길때, 시간을 당겨서 활용하는 방법입니다.
각 나라마다, DST를 적용하거나/적용하지 않고, 적용하는 시기도 다 틀립니다.
그리고 DST에 적용되는 시간도 틀리죠.
2008. 6. 25. 12:52

MoinMoin 1.7 버전이 릴리즈되었습니다.

제가 개인적으로 사용하고 있는 Wiki가 MoinMoin입니다.

MoinMoin 1.7 버전도 릴리즈되었습니다.
 * http://moinmo.in/
2008. 6. 25. 12:48

Subversion, TortoiseSVN 1.5 버전이 드디어 릴리즈 되었습니다.

Subversion과 TortoiseSVN이 1.4 버전이 릴리즈된 이후에 약 2년만에 1.5 버전이 드디어 릴리즈되었습니다.

자세한 릴리즈내용은 다음을 참고하시면 되겠습니다.
 * http://subversion.tigris.org/svn_1.5_releasenotes.html
 * http://tortoisesvn.tigris.org/tsvn_1.5_releasenotes.html

1.5 버전에서 많은 것이 개선되고, 추가되었습니다.
결론은 1.5 버전을 사용하는 것이 좋겠죠.. ^^;
2008. 5. 16. 20:17

bool 타입을 지원하지 않는 컴파일러에서 bool 타입 사용하기

이글의 내용은 Effective C++에서 가져왔습니다.(제 기억이 맞다면요 ^^;)


지금 내가 사용하는 컴파일러가 bool 타입을 지원하지 않는다면

다음과 같은 방법으로 bool 타입을 만들어 사용할 수 있습니다.

  • 열거형 타입으로 bool 타입을 만드는 방법
  • typedef를 사용해서 bool 타입을 만드는 방법


열거형 타입으로 bool 타입을 만드는 방법
typedef enum bool { false, true} bool;

bool b;
b = true;


typedef를 사용해서 bool 타입을 만드는 방법
typedef int bool;
#define true   1
#define false 0

bool b;
b = true;



이제 위에서 언급한 두 가지 방법의 장점과 단점을 보도록 하죠.

열거형 타입으로 bool 타입을 만드는 방법의 장점과 단점
C++에서 함수의 매개변수가 bool 인지 int인지에 따라 함수를 오버로딩할 수 있습니다.
하지만 단점은 비교 연산자는 bool 이 아닌 int를 반환한다는 것입니다.
따라서 열거형으로 정의한 bool을 사용해서 작성된 코드(함수를 오버로딩했을 때)가 나중에 제대로된 bool을 지원하는 컴파일러에서 오동작을 일으킬 수 있습니다.
int f(bool);
int f(int);

int a = 3;
f(a);         // int f(int)가 호출됩니다.

bool b = true;
f(b);         // int f(bool)이 호출됩니다.

f( 3 < 2);   // int f(bool)이 아닌 int f(int)가 호출됩니다.



typedef를 사용해서 bool 타입을 만드는 방법의 장점과 단점
전통적인 C와 C++의 의미구조와 호환이 됩니다.
나중에 bool을 실제 지원하는 컴파일러를 사용해도 열거형을 사용할 때와 같은 문제가 없습니다.
단점은 int와 bool에 대해서 함수 오버로딩을 할 수 없다는 것입니다.


둘중에 어떤 방법을 사용할지는 개발자에게 달려있겠죠.. ^^;