Announcements

test

posted Mar 5, 2009, 5:28 AM by Unknown user

#include <stdarg.h>

int foo(char *fmt, ...) {
va_list ap;
int d;
int count=0;
char c, *p, *s;

va_start(ap, fmt);
while (*fmt)
switch(*fmt++) {
case '%':
if((*fmt) && (*(fmt) != '%'))
count++;
else if (*fmt)
fmt++;
break;
}
va_end(ap);
printf("%d", count);


va_start(ap, fmt);
va_end(ap);

return count;
}

int dup(char *v, ...)
{
va_list ap;
int d;
int count=0;
char c, *s;



va_start(ap, v);
va_end(ap);

}
int main()
{
char *p = "%d%s%d";
foo(p);
dup(p);

}

Objective-C 최상위 클래스

posted Jan 22, 2009, 7:43 PM by Unknown user   [ updated Jan 22, 2009, 7:47 PM ]

Objective-C는 컴파일러가 생성하는 객체의 구조에 접근 가능하게 하는 API를 제공한다. 이를 이용하면 GNU Objective-C의 Object나 MacOS X의 NSObject같은 최상위 클래스를 쉽게 작성할 수 있다. 반드시 그렇게 해야 할 이유는 없지만 말이다.

API를 사용하려면 다음의 파일들을 #include 해야 한다.

 

  • objc/objc.h
  • objc/objc-api.h
  • objc/objc-class.h (MacOS X)

 

Objective-C가 생성하는 모든 객체들은 헤더 부분에 클래스 객체에 대한 포인터를 가지며, 데이터 부분은 클래스 정의에 따라 달라지게 된다. 객체의 헤더 부분은 struct objc_object에 정의 되어 있다.

/* GNU Objective-C - objc/objc.h */

struct objc_object
{
    struct objc_class* class_pointer;
};

MacOS X에서는 class_pointer대신 isa라는 이름이 사용된다.

struct objc_class는 클래스 객체의 구조를 정의한다. 클래스 역시 객체이므로 메타클래스라고 하는 자신의 클래스 객체에 대한 포인터를 가지며, 크기, 이름, 부모 클래스등 생성할 객체에 대한 여러 가지 정보를 담고 있다.

/* GNU Objective-C - objc/objc.h */
 
struct objc_class
{
    struct objc_class* class_pointer;
    struct objc_class* super_class;
    const char* name;
    long version;
    unsigned long info;
    long instance_size;
    struct objc_ivar_list* ivars;
    struct objc_method_list* methods;
    struct sarray* dtable;
    struct objc_class* subclass_list;
    struct objc_class* sibling_class;
    struct objc_protocol_list *protocols; void* gc_object_type;
};

최상위 클래스는 클래스 포인터를 초기화 하고 객체의 생성과 소멸을 담당하는 메서드들을 제공해야 한다. GNU Objective-C의 Object처럼 alloc, init, free, new를 작성해보자.

/* Object.h */
 
#include <objc/objc.h>
#include <objc/objc-api.h>
#ifdef __APPLE__
#include <objc/objc-class.h>
#endif
 
@interface Object
{
    struct objc_class* isa;
}
 
+ (id) alloc;
+ (id) new;
- (id) init;
- (void) free;
 
@end
  • isa - 클래스 포인터
  • alloc - 객체가 필요한 메모리 공간을 할당한다.
  • free - 객체가 사용한 메모리 공간을 해제한다.
  • init - 객체를 초기화 한다.
  • new - [[object alloc] init]

 

alloc를 제외한 나머지는 다음과 같이 간단하게 구현될 수 있다.

/* Object.m */
 
#include "Object.m"
#include <stdlib.h>
 
@implementation Object
 
+ (id) alloc
{
    return alloc_object (self);
}
 
+ (id) new
{
    id obj = [self alloc];
    if (obj == nil) return nil;
    return [obj init];
}
 
- (id) init
{
    return self;
}
 
- (void) free
{
    if (self != nil) free (self);
}
@end
객체가 필요한 공간을 할당하려면 객체의 크기를 알아야 한다. 객체의 크기는 클래스의 instance_size 필드에 저장이 되는데, 실제 필요한 크기는 여기에 헤더부분(클래스포인터)의 크기를 포함해야 한다.
/* Object.m */
 
static struct objc_object* alloc_object (struct objc_class* class)
{
    size_t size;
    struct objc_object* obj;
 
    /* 객체가 필요로 하는 공간의 크기 */
    size = sizeof(struct objc_object) + class->instance_size;
 
    /* 공간을 할당한다 */
    obj = (struct objc_object*)calloc(1, size);
    if (obj == NULL) return nil;
 
    /* MacOS X는 class_pointer대신 isa라는 이름을 사용하므로 #ifdef로 처리한다 */
#ifdef __APPLE__
    obj->isa = class;
#else
    obj->class_pointer = class;
#endif
    return obj;
}

MacOS X는 추가적으로 forward:sel:메서드를 필요로 한다.

#ifdef __APPLE__
- (id) forward: (SEL)sel: (marg_list)args
{
    return self;
}
#endif

이제 위에서 만든 최상위 클래스를 사용해 보도록 하자.

#include "Object.h"
#include <stdio.h>
 
@interface Child: Object
{
    int a;
}
 
- (id) init;
- (void) print;
@end
 
@implementation Child
- (id) init
{
    [super init];
    a = 2871;
    return self;
}
 
- (void) print
{
    printf ("a = %d\n", a);
}
 
@end
 
int main ()
{
    id t;
 
    t = [[Child alloc] init]; /* 개체를 생성하고 초기화 한다 */
    [t print]; /* print메시지를 보낸다 */
    [t free]; /* 개체를 없앤다 */
    return 0;
}
 

AWK/Calling Functions [ Samples ]

posted May 25, 2008, 2:48 AM by Unknown user   [ updated Feb 16, 2009, 7:15 PM ]

[ Top ] [ Samples ]

DESCRIPTION

This program demonstrates how to use qse_awk_rtx_call().

SOURCE

 7 #include <qse/awk/awk.h>
8 #include <qse/utl/stdio.h>
9
10 static const qse_char_t* src = QSE_T(
11 "function init() { a = 20; }"
12 "function main() { a++; }"
13 "function fini() { print a; }"
14 );
15
16 static const qse_char_t* f[] =
17 {
18 QSE_T("init"),
19 QSE_T("main"),
20 QSE_T("main"),
21 QSE_T("main"),
22 QSE_T("main"),
23 QSE_T("fini"),
24 };
25
26 int main ()
27 {
28 qse_awk_t* awk = QSE_NULL;
29 qse_awk_rtx_t* rtx = QSE_NULL;
30 int ret, i;
31
32 /* create a main processor */
33 awk = qse_awk_opensimple ();
34 if (awk == QSE_NULL)
35 {
36 qse_fprintf (QSE_STDERR, QSE_T("error: cannot open awk\n"));
37 ret = -1; goto oops;
38 }
39
40 /* don't allow BEGIN, END, pattern-action blocks */
41 qse_awk_setoption (awk, qse_awk_getoption(awk) & ~QSE_AWK_PABLOCK);
42
43 ret = qse_awk_parsesimple (
44 awk,
45 QSE_AWK_PARSE_STRING, src, /* parse AWK source in a string */
46 QSE_NULL /* no parse output */
47 );
48 if (ret == -1)
49 {
50 qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"),
51 qse_awk_geterrmsg(awk));
52 goto oops;
53 }
54
55 /* create a runtime context */
56 rtx = qse_awk_rtx_opensimple (
57 awk,
58 QSE_NULL /* no console files */
59 );
60 if (rtx == QSE_NULL)
61 {
62 qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"),
63 qse_awk_geterrmsg(awk));
64 ret = -1; goto oops;
65 }
66
67 /* invoke functions as indicated in the array f */
68 for (i = 0; i < QSE_COUNTOF(f); i++)
69 {
70 ret = qse_awk_rtx_call (rtx, f[i], QSE_NULL, 0);
71 if (ret == -1)
72 {
73 qse_fprintf (QSE_STDERR, QSE_T("%d error: %s\n"),
74 i, qse_awk_rtx_geterrmsg(rtx));
75 goto oops;
76 }
77 }
78
79 oops:
80 /* destroy a runtime context */
81 if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
82 /* destroy the processor */
83 if (awk != QSE_NULL) qse_awk_close (awk);
84 return ret;
85 }

1-3 of 3