C

거믄마루 2013. 1. 10. 10:20

일전에 osxfuse sshfs 마운트 한글 문제를 해결하면서 다음과 같은 옵션이 필요하다고 했었는데


 -omodules=iconv,from_code=utf-8,to_code=utf-8-mac

옵션을 보다보니 이런 옵션을 처리하려면 어떻게 했을까하는 생각이 들었다.

위와 같은 옵션처리 방식은 -o 옵션 하나에서 

"키=값" 또는 "키" 형태 옵션리스트를 쉼표(,)를 구분자로 하여 하나이상 가질 수 있고

또한 -o 옵션 자체도 여러번 중복처리될 수 있어야 한다.

내친김에 어제 저녁에 구현을 했다.

다음은 구현된 코드이다.


 #include <stdio.h>
#include <string.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
    int opt;
    char *ptr;
    char *so, *eo;

    int help = 0;

    while ((opt = getopt(argc, argv, "o:h")) != -1)
    {
        switch (opt)
        {
        case 'h':
            help = 1;
            break;

        case 'o':

            for (so = optarg; so && *so; so = eo)
            {
                if ((eo = strchr(so, ',')))
                {
                    *eo = 0;
                    eo += 1;

                    if ((ptr = strchr(so, '=')))
                    {
                        *ptr = 0;
                
                        printf("\"%s\": \"%s\"\n", so, ptr + 1);
                    }
                    else
                    {
                        printf("\"%s\": \"%s\"\n", so, "--NULL--");
                    }
                }
                else if ((eo = strchr(so, '=')))
                {
                    *eo = 0;
                    eo += 1;
                    printf("\"%s\": \"%s\"\n", so, eo);
                    eo = NULL;
                }
                else
                {
                    printf("\"%s\": \"%s\"\n", so, "--NULL--");
                    eo = NULL;
                }
            }

            break;
        }
    }

    if (help)
    {
        printf("HELP\n");
    }

    return 0;
}


프로그램이 그렇게 어려운 편은 아니므로 자세한 설명은 하지 않는다.

하지만 질문은 언제나 환영이다.

프로그램을 이해할 수 있다면 응용하는 것은 어렵지 않을 것이다.

프로그램의 일부나 전체를 게재하거나 사용하시려 할때는 반드시 출처를 밝혀주세요~

자신의 프로그램 코드에서 다른이의 코드를 인용 또는 사용할 때 출처를 밝히는 저의 예를 들면 다음과 같아요.

제가 작성한 웹서버에서 실제 사용된 예입니다...


 
/*
 * URL 엔코딩을 평문화하는 아래 코드는 부끄럽게도 다른 소스코드에서 참조를 했다
 *      물론 항상 다른 소스를 참조하기는 하지만...
 *      참조한곳: http://www.geekhideout.com/urlcode.shtml
 *      저자는 누구인지 알 수 없어서 밝힐 수 가 없는 것에 대해 양해를 구한다.
 *      그대로 갖다 쓰지는 않았고 여러 번의 함수처리를 거치는 것을
 *      테이블(int conv[]) 기반으로 처리하여 훨씬 더 빠르게 동작할 수 있도록 수정하였다.
 *
 *      2012-08-17
 */

int
url_decode(char *buf, char *target)
{
    char *ptr;
    int conv[256] =
    {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0 - 15 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 16 - 31 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 32 - 47 */

         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,  /* 48 - 63 */

        -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 64 - 79 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 80 - 95 */

        -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 96 - 111 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 112 - 127 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 128 - 143 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 144 - 159 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 160 - 175 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 176 - 191 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 192 - 207 */


        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 208 - 223 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 224 - 239 */

        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 240 - 255 */
    };

    if (buf == NULL)
    {
        return 1;
    }

    if (target == NULL)
    {
        ptr = buf;
    }
    else
    {
        ptr = target;
    }

    while (*buf)
    {
        if (*buf == '%')
        {
            if ((*(buf + 1) && conv[0 + (unsigned char)*(buf + 1)] >= 0) && (*(buf + 2) && conv[0 + (unsigned char)*(buf + 2)] >= 0))
            {
                *ptr++ = (conv[0 + (unsigned char)*(buf + 1)] << 4) | conv[0 + (unsigned char)*(buf + 2)];
                buf += 2;
            }
        }
        else if (*buf == '+')
        {
            *ptr++ = ' ';
        }
        else
        {
            *ptr++ = *buf;
        }

        buf++;
    }

    *ptr = 0;

    return 0;
}