manywaypark's Blog
개발, 검색, 함수

[WARN] maven encoding

tips & tricks 2011. 9. 26. 13:42 by manywaypark
문제
maven을 사용해서 빌드할 때 다음과 같은 무시무시한(?) 경고가 나온다면, 인코딩 설정이 제대로 안된 것이다.
내 경우는 맥을 사용했으므로 MacRoman으로 fallback 되었다는 이야기다.

$ mvn package or something
...
[WARNING] File encoding has not been set, using platform encoding MacRoman, i.e. build is platform dependent!
...
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
...

해결
기본적으로 platform에 종속적이게되므로, 소스/리소스의 인코딩을 하나로 통일하고 다음과 같이 사용한 인코딩을 pom.xml에 적시하면 문제가 해결된다.
<project>
.....
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
......
</project>

refs:
http://maven.apache.org/general.html
http://maven.apache.org/plugins/maven-resources-plugin/examples/encoding.html

happy hackin'

git merge

tips & tricks 2011. 9. 23. 15:50 by manywaypark
예전에 sqlite의 erlang connector관련해서 github에서 작업한 적이 있었다.
한참 방치하다가 들어가 보니 alexeyr님 및 다른 개발자들이 많이 발전시켜 놓은 상태였다(rebar 적용 등).
내쪽에 merge를 하고 싶었는데 문제는 내가 git에 별로 익숙치 않다는 것... Orz.
검색 및 삽질을 통해 merge하는 데에는 성공했는데, 역시 아직 손에 익지는 않은 듯하다.
일단 성공한 로그를 남겨둔다.
 
$ git clone git@github.com:mwpark/sqlite-erlang.git
$ cd sqlite-erlang
$ git branch # local branches
* master
$ git branch -a # all branches
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/gh-pages
  remotes/origin/master
$ git remote add alexeyr https://github.com/alexeyr/erlang-sqlite3.git
$ git remote -v
alexeyr https://github.com/alexeyr/erlang-sqlite3.git (fetch)
alexeyr https://github.com/alexeyr/erlang-sqlite3.git (push)
origin git@github.com:mwpark/sqlite-erlang.git (fetch)
origin git@github.com:mwpark/sqlite-erlang.git (push)
$ git checkout -b alexeyr/master
Switched to a new branch 'alexeyr/master'
$ git branch -r
  origin/HEAD -> origin/master
  origin/gh-pages
  origin/master
$ git pull alexeyr master:HEAD
$ git checkout master
NOTE: 여기서 conflict 생기면 add/rm 등을 해야함 (처음 checkout 시에 메시지 나오며, git status로 다시 확인 가능).
conflict 해결 후 다시 git checkout master 해서 branch 변경에 성공해야함.
$ git commit -m "merged https://github.com/alexeyr/erlang-sqlite3.git"
......
$ git push
Counting objects: 30, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (24/24), done.
Writing objects: 100% (26/26), 127.78 KiB, done.
Total 26 (delta 2), reused 16 (delta 0)
To git@github.com:mwpark/sqlite-erlang.git
   a2e6238..61e929f  master -> master

refs:
http://gitref.org/branching/#merge
http://markosullivan.ca/how-to-handle-a-pull-request-from-github/
http://www.viget.com/extend/i-have-a-pull-request-on-github-now-what/

happy hackin' 
Erlang의 풍부한 표현 방법을 보여주기 위한 간단한 예제를 만들었다.
lists:map에 전달하는 첫번째 파라미터(함수) 부분의 표현 방법을 보면 된다. 

by_...
function은  리스트를 입력받아 각 요소가 홀수인지 짝수인지 판별한다 (에러 처리 포함).
@spec (by_...([integer() | any()]) -> [odd | even | error].

기본적으로 유념해야 할 것은,
  • if는 guard expression을 사용하고, case는 pattern matching을 사용한다.
  • if는 마지막에 truecase는 마지막에 underscore(_) 또는 Any를 사용하여 default(catch all) 조건을 만든다.
  • guard의 and는 comma(,)이고, or는 semicolon(;)이다.

자세한 것은 코드 참조.

%%% -*- mode: erlang; tab-width: 4; indent-tabs-mode: nil -*-
%%%-------------------------------------------------------------------
%%% File    : expressions.erl
%%% Author  : M.W. Park <manywaypark@gmail.com>
%%% Description : an erlang example (to explain expressions)
%%%               ref: http://www.erlang.org/doc/reference_manual/expressions.html
%%%
%%% Created : 2011-09-22 목요일 by M.W. Park
%%%-------------------------------------------------------------------

-module(expressions).
%% -export([]).
%% -import(, []).
-compile(export_all).

%% using guard inside 'if'
by_if(L) when is_list(L) ->
    lists:map(fun(X) ->
                      if
                          is_integer(X),
                          X rem 2 =:= 0 -> even;
                          is_integer(X) -> odd;
                          true          -> error
                      end
              end,
              L).

%% nested 'case'
by_case(L) when is_list(L) ->
    lists:map(fun(X) ->
                      case is_integer(X) of
                          true ->
                              case X rem 2 of
                                  0 -> even;
                                  _ -> odd
                              end;
                          _ -> error
                      end
              end,
              L).

%% 'case' w/ guards
by_case_with_guard(L) when is_list(L) ->
    lists:map(fun(X) ->
                      case X of
                          _ when is_integer(X),
                                 X rem 2 =:= 0 -> even;
                          _ when is_integer(X) -> odd;
                          _                    -> error
                      end
              end,
              L).

%% 'case' w/ exception
%% 'rem' operator may throw an exception.
by_case_with_ex(L) when is_list(L) ->
    lists:map(fun(X) ->
                      try 
                          case X rem 2 of
                              0 -> even;
                              _ -> odd
                          end
                      catch
                          _:_ -> error
                      end
              end,
              L).

%% pattern matching functions
'what?'(X) when is_integer(X), X rem 2 =:= 0 ->
    even;
'what?'(X) when is_integer(X) ->
    odd;
'what?'(_) ->
    error.

%% passing function name as a parameter
by_passing_fun(L) when is_list(L) ->
    lists:map(fun 'what?'/1, L).

%% anonymous function w/ guards
by_anonymous_fun(L) when is_list(L) ->
    lists:map(fun(X) when is_integer(X),
                          X rem 2 =:= 0 -> even;
                 (X) when is_integer(X) -> odd;
                 (_)                    -> error
              end,
              L).

%% mixture of anonymous function w/ a guard and 'case'
by_mix(L) when is_list(L) ->
    lists:map(fun(X) when is_integer(X) ->
                      case X rem 2 of
                          0 -> even;
                          _ -> odd
                      end;
                 (_) -> error
              end,
              L).

%%%-------------------------------------------------------------------
%%% Unit Tests
%%%-------------------------------------------------------------------
-include_lib("eunit/include/eunit.hrl").

-define(BASIC(FunName), ?_assertEqual([odd, even], FunName(lists:seq(1, 2)))).
-define(ERROR(FunName), ?_assertEqual([error, error], FunName([0.1, atom]))). 

by_if_test_() ->
    [
     ?BASIC(by_if),
     ?ERROR(by_if)
    ].

by_case_test_()->
    [
     ?BASIC(by_case),
     ?ERROR(by_case)
    ].

by_case_with_guard_test_() ->
    [
     ?BASIC(by_case_with_guard),
     ?ERROR(by_case_with_guard)
    ].

by_case_with_ex_test_() ->
    [
     ?BASIC(by_case_with_ex),
     ?ERROR(by_case_with_ex)
    ].

by_passing_fun_test_() ->
    [
     ?BASIC(by_passing_fun),
     ?ERROR(by_passing_fun)
    ].

by_anonymous_fun_test_() ->
    [
     ?BASIC(by_anonymous_fun),
     ?ERROR(by_anonymous_fun)
    ].

by_mix_test_() ->
    [
     ?BASIC(by_mix),
     ?ERROR(by_mix)
    ].

happy hackin'
Erlang Opcode
참고 문서에는 otp_src_R14B01/lib/compiler/src/beam_opcodes.erl에 있다고 설명하고있으나,
최신 소스에는 otp/dialyzer/test/options1_SUITE_data/src/compiler/beam_opcodes.erl에 있고 주석에 보면 beam_makeops를 이용해서 만들어졌다고 되어있다.
beam_makeopsotp/erts/emulator/utils에 있고 perl script이다.

erlang source(.erl)을 assembly code(.S)로 컴파일 할 수 있는데 아래처럼 compile flag에 "+'S'"를 추가 하면 된다.
파일 내용을 확인해보면 opcode들이 난무(?)한다. 
$ erlc "+'S'" foo.erl

BEAM file format
TBD - 아래 링크 참고

happy hackin'
 
refs:

maven에 3rd party jar 추가하기

tips & tricks 2011. 8. 12. 17:21 by manywaypark
local repository(~/.m2/repository)에 jar를 추가한다.
mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
    -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>


ref: http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html

happy hackin'
 
결론부터 말하자면 복합키는 지원안된다 (erlang mnesia composite key 쯤으로 구글링하면 많이 나온다).
키에 tuple을 써서 비슷하게 만들 수 있다.
아래와 같이 레코드를 정의하고 쓰면 된다.
-record(id, {name=[], phone=[]}).
-record(person,  {pkey=#id{}, addr=[], note=[]}).

index 추가하면 되는 줄로 알고... 몇년전에 삽질했던 것을 오늘 또 했다. Orz...
다시 몇년 후를 기약(?)하며 오늘은 기록으로 남겨둔다.

happy hackin'

문제:
Qt의 QFile::copy()는 Windows와 Symbian에서만 native copy를 사용해 구현되어있다(2011-07-20 기준).
http://bugreports.qt.nokia.com/browse/QTBUG-10369
http://bugreports.qt.nokia.com/browse/QTBUG-10337
따라서 다른 platform에서 copy()를 사용하면 복사된 파일이 copy() 수행 시점의 timestamp를 가지게 된다.

해결:
지금 내 경우에는 생성시간의 유지가 중요한 상황이므로 다음과 같이 간단하게 회피하는 QFileFixed class를 만들어서 해결했다.

// file: QFileFixed.h

//! \author manywaypark at gmail.com http://manywaypark.tistory.com
 

class QFileFixed : public QFile

{

public:

    QFileFixed(const QString &name);

#if !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN))

    bool copy(const QString &newName);

    static bool copy(const QString &fileName, const QString &newName);

private:

    static void copyFileTime(const QFileInfo &srcInfo, const QString &dstPath);

#endif

};


// file: QFileFixed.cpp

//! \author manywaypark at gmail.com http://manywaypark.tistory.com


#if !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN))

#include <sys/time.h>

#endif


QFileFixed::QFileFixed(const QString &name)

    : QFile(name)

{}


#if !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN))

bool QFileFixed::copy(const QString &newName){

    bool r(QFile::copy(newName));

    if (r) copyFileTime(QFileInfo(*this), newName);

    return r;

}


bool QFileFixed::copy(const QString &fileName, const QString &newName)

{

    bool r(QFile::copy(fileName, newName));

    if (r) copyFileTime(QFileInfo(fileName), newName);

    return r;

}


void QFileFixed::copyFileTime(const QFileInfo &srcInfo, const QString &dstPath)

{

    QDateTime access(srcInfo.lastRead());

    QDateTime created(srcInfo.created()); /* created == modification?? */

    struct timeval time[2];

    time[0].tv_sec = access.toTime_t();

    time[0].tv_usec = access.time().msec() * 1000; /* millisecond to microsecond */

    time[1].tv_sec = created.toTime_t();

    time[1].tv_usec = created.time().msec() * 1000; /* millisecond to microsecond */

    int r = utimes(dstPath.toAscii().constData(), time);


    Q_ASSERT(r == 0);

}

#endif // !(defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)


Windows와 Mac OSX에서 테스트되었고, 내가 필요한 파일 생성 시간 유지는 잘 되는 것을 확인했다.

happy hackin'

문제
원래 Qt에서 단축키 추가는 너무 쉽다. 아래와 같이 하면 그냥 잘 된다.
action.setShortcut(QKeySequence(Qt::ALT + Qt::Key_C));
다만 문제는 MainWindow에서만 잘 된다는 것...   Orz
구글링을 해봐도 오래된 질문만 있고 답변은 없었다.

해결
처음에는 keyPressEvent 쪽에서 처리하는 다소 지저분한 방법을 쓰려했으나,
영 내키지 않던 차에 Qt Help에서 힌트를 얻을 수 있었다.
QShortcut이라는 클래스가 있었던 것이다.
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_C), parent);
connect(shortcut, SIGNAL(activated()),
        &action, SLOT(trigger()));

동작은 잘 하는데 메뉴 등에 표시를 위해서는 action.setShortcut()도 해주어야한다.

happy hackin'

국가란 무엇인가 - 유시민

독서/일반 2011. 6. 15. 11:44 by manywaypark
개인을 중심에 놓고 보면 최고의 도덕적 이상은 이타성이다. 그러나 사회는 여러 면에서 어쩔 수 없이, 도덕성이 높은 사람들이 결코 도덕적으로 승인하지 않을 방법을 사용해서라도, 종국적으로 정의를 추구해야한다. 이 두 도덕적 입장은 서로 배타적이지 않으며, 양자 사이의 모순도 절대적이지는 않다. 하지만 그렇다고 쉽게 조화되는 것도 아니다.
- 라인홀트 니버, 도덕적 인간과 비도덕적 사회

"유시민, 국가란 무엇인가"에서 인용한 것을 재인용 
1. 설치
# apt-get install apache2 libapache2-svn subversion
 
2. 설정
2-1. svn repository 생성
# mkdir /var/lib/svn
# svnadmin create /var/lib/svn/[prj_name]
# chown -R www-data 
/var/lib/svn/[prj_name] 

2-2. /etc/apache2/mods-available/dav_svn.conf 수정
# dav_svn.conf - w/ ldap auth
# 2011-06-14 by manywaypark
<Location /svn>
  DAV svn

  SVNParentPath /var/lib/svn

  <LimitExcept OPTIONS REPORT>
    AuthType Basic
    AuthBasicProvider ldap
    AuthzLDAPAuthoritative on
    AuthName "SVN Authentication"
    AuthLDAPURL "ldap://localhost:389/ou=people,dc=localdomain?uid"
    AuthLDAPGroupAttribute memberUid
    AuthLDAPGroupAttributeIsDN off
    require ldap-group cn=svnusers,ou=group,dc=localdomain
  </LimitExcept>
</Location> 

2-3. apache 서버 설정 변경 및 재시작
# cd /etc/apache2/mods-enabled
# ln -s ../mods-available/ldap.load ldap.load
# ln -s ../mods-available/authnz_ldap.load authnz_ldap.load
# /etc/init.d/apache2 restart

3. 동작 확인
웹 브라우저나 SVN client에 http://[server-ip]/svn/[prj_name]을 입력해서 repository를 확인한다.
(repository를 보여주기전에 로그인 과정이 나와야한다.)

happy hackin'


 
1 ··· 15 16 17 18 19 20 21 ··· 31 
분류 전체보기 (306)
잡담 (20)
함수형 언어 (65)
emacs (16)
java (18)
tips & tricks (154)
사랑 (1)
가사 (0)
독서 (4)
mobile (6)
비함수형 언어 (2)

공지사항

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

05-14 13:33