[BACK]Return to acpidebug.c CVS log [TXT][DIR] Up to [local] / sys / dev / acpi

Annotation of sys/dev/acpi/acpidebug.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: acpidebug.c,v 1.15 2007/02/06 18:56:31 jordan Exp $ */
        !             2: /*
        !             3:  * Copyright (c) 2006 Marco Peereboom <marco@openbsd.org>
        !             4:  *
        !             5:  * Permission to use, copy, modify, and distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17:
        !            18: #include <machine/db_machdep.h>
        !            19: #include <ddb/db_command.h>
        !            20: #include <ddb/db_output.h>
        !            21: #include <ddb/db_extern.h>
        !            22: #include <ddb/db_lex.h>
        !            23:
        !            24: #include <machine/bus.h>
        !            25: #include <sys/malloc.h>
        !            26:
        !            27: #include <dev/acpi/acpireg.h>
        !            28: #include <dev/acpi/acpivar.h>
        !            29: #include <dev/acpi/amltypes.h>
        !            30: #include <dev/acpi/acpidebug.h>
        !            31: #include <dev/acpi/dsdt.h>
        !            32:
        !            33: void db_aml_disline(uint8_t *, int, const char *, ...);
        !            34: void db_aml_disint(struct aml_scope *, int, int);
        !            35: uint8_t *db_aml_disasm(struct aml_node *, uint8_t *, uint8_t *, int, int);
        !            36:
        !            37: extern int aml_pc(uint8_t *);
        !            38: extern struct aml_scope *aml_pushscope(struct aml_scope *, uint8_t *, uint8_t *, struct aml_node *);
        !            39: extern struct aml_scope *aml_popscope(struct aml_scope *);
        !            40: extern uint8_t *aml_parsename(struct aml_scope *);
        !            41: extern uint8_t *aml_parseend(struct aml_scope *);
        !            42: extern int aml_parselength(struct aml_scope *);
        !            43: extern int aml_parseopcode(struct aml_scope *);
        !            44:
        !            45: extern const char *aml_mnem(int opcode, uint8_t *);
        !            46: extern const char *aml_args(int opcode);
        !            47: extern const char *aml_getname(uint8_t *);
        !            48: extern const char *aml_nodename(struct aml_node *);
        !            49:
        !            50: const char             *db_aml_objtype(struct aml_value *);
        !            51: const char             *db_opregion(int);
        !            52: int                    db_parse_name(void);
        !            53: void                   db_aml_dump(int, u_int8_t *);
        !            54: void                   db_aml_showvalue(struct aml_value *);
        !            55: void                   db_aml_walktree(struct aml_node *);
        !            56:
        !            57: const char             *db_aml_fieldacc(int);
        !            58: const char             *db_aml_fieldlock(int);
        !            59: const char             *db_aml_fieldupdate(int);
        !            60:
        !            61: extern struct aml_node aml_root;
        !            62:
        !            63: /* name of scope for lexer */
        !            64: char                   scope[80];
        !            65:
        !            66: const char *
        !            67: db_opregion(int id)
        !            68: {
        !            69:        switch (id) {
        !            70:        case 0:
        !            71:                return "SystemMemory";
        !            72:        case 1:
        !            73:                return "SystemIO";
        !            74:        case 2:
        !            75:                return "PCIConfig";
        !            76:        case 3:
        !            77:                return "Embedded";
        !            78:        case 4:
        !            79:                return "SMBus";
        !            80:        case 5:
        !            81:                return "CMOS";
        !            82:        case 6:
        !            83:                return "PCIBAR";
        !            84:        }
        !            85:        return "";
        !            86: }
        !            87: void
        !            88: db_aml_dump(int len, u_int8_t *buf)
        !            89: {
        !            90:        int             idx;
        !            91:
        !            92:        db_printf("{ ");
        !            93:        for (idx = 0; idx < len; idx++)
        !            94:                db_printf("%s0x%.2x", idx ? ", " : "", buf[idx]);
        !            95:        db_printf(" }\n");
        !            96: }
        !            97:
        !            98: void
        !            99: db_aml_showvalue(struct aml_value *value)
        !           100: {
        !           101:        int             idx;
        !           102:
        !           103:        if (value == NULL)
        !           104:                return;
        !           105:
        !           106:        if (value->node)
        !           107:                db_printf("[%s] ", aml_nodename(value->node));
        !           108:
        !           109:        switch (value->type & ~AML_STATIC) {
        !           110:        case AML_OBJTYPE_OBJREF:
        !           111:                db_printf("refof: %x {\n", value->v_objref.index);
        !           112:                db_aml_showvalue(value->v_objref.ref);
        !           113:                db_printf("}\n");
        !           114:                break;
        !           115:        case AML_OBJTYPE_NAMEREF:
        !           116:                db_printf("nameref: %s\n", value->v_nameref);
        !           117:                break;
        !           118:        case AML_OBJTYPE_INTEGER:
        !           119:                db_printf("integer: %llx %s\n", value->v_integer,
        !           120:                    (value->type & AML_STATIC) ? "(static)" : "");
        !           121:                break;
        !           122:        case AML_OBJTYPE_STRING:
        !           123:                db_printf("string: %s\n", value->v_string);
        !           124:                break;
        !           125:        case AML_OBJTYPE_PACKAGE:
        !           126:                db_printf("package: %d {\n", value->length);
        !           127:                for (idx = 0; idx < value->length; idx++)
        !           128:                        db_aml_showvalue(value->v_package[idx]);
        !           129:                db_printf("}\n");
        !           130:                break;
        !           131:        case AML_OBJTYPE_BUFFER:
        !           132:                db_printf("buffer: %d ", value->length);
        !           133:                db_aml_dump(value->length, value->v_buffer);
        !           134:                break;
        !           135:        case AML_OBJTYPE_DEBUGOBJ:
        !           136:                db_printf("debug");
        !           137:                break;
        !           138:        case AML_OBJTYPE_MUTEX:
        !           139:                db_printf("mutex : %llx\n", value->v_integer);
        !           140:                break;
        !           141:        case AML_OBJTYPE_DEVICE:
        !           142:                db_printf("device\n");
        !           143:                break;
        !           144:        case AML_OBJTYPE_EVENT:
        !           145:                db_printf("event\n");
        !           146:                break;
        !           147:        case AML_OBJTYPE_PROCESSOR:
        !           148:                db_printf("cpu: %x,%x,%x\n",
        !           149:                    value->v_processor.proc_id,
        !           150:                    value->v_processor.proc_addr,
        !           151:                    value->v_processor.proc_len);
        !           152:                break;
        !           153:        case AML_OBJTYPE_METHOD:
        !           154:                db_printf("method: args=%d, serialized=%d, synclevel=%d\n",
        !           155:                    AML_METHOD_ARGCOUNT(value->v_method.flags),
        !           156:                    AML_METHOD_SERIALIZED(value->v_method.flags),
        !           157:                    AML_METHOD_SYNCLEVEL(value->v_method.flags));
        !           158:                break;
        !           159:        case AML_OBJTYPE_FIELDUNIT:
        !           160:                db_printf("%s: access=%x,lock=%x,update=%x pos=%.4x "
        !           161:                    "len=%.4x\n",
        !           162:                    aml_mnem(value->v_field.type, NULL),
        !           163:                    AML_FIELD_ACCESS(value->v_field.flags),
        !           164:                    AML_FIELD_LOCK(value->v_field.flags),
        !           165:                    AML_FIELD_UPDATE(value->v_field.flags),
        !           166:                    value->v_field.bitpos,
        !           167:                    value->v_field.bitlen);
        !           168:
        !           169:                db_aml_showvalue(value->v_field.ref1);
        !           170:                db_aml_showvalue(value->v_field.ref2);
        !           171:                break;
        !           172:        case AML_OBJTYPE_BUFFERFIELD:
        !           173:                db_printf("%s: pos=%.4x len=%.4x ",
        !           174:                    aml_mnem(value->v_field.type, NULL),
        !           175:                    value->v_field.bitpos,
        !           176:                    value->v_field.bitlen);
        !           177:
        !           178:                db_aml_dump(aml_bytelen(value->v_field.bitlen),
        !           179:                    value->v_field.ref1->v_buffer +
        !           180:                    aml_bytepos(value->v_field.bitpos));
        !           181:
        !           182:                db_aml_showvalue(value->v_field.ref1);
        !           183:                break;
        !           184:        case AML_OBJTYPE_OPREGION:
        !           185:                db_printf("opregion: %s,0x%llx,0x%x\n",
        !           186:                    db_opregion(value->v_opregion.iospace),
        !           187:                    value->v_opregion.iobase,
        !           188:                    value->v_opregion.iolen);
        !           189:                break;
        !           190:        default:
        !           191:                db_printf("unknown: %d\n", value->type);
        !           192:                break;
        !           193:        }
        !           194: }
        !           195:
        !           196: const char *
        !           197: db_aml_objtype(struct aml_value *val)
        !           198: {
        !           199:        if (val == NULL)
        !           200:                return "nil";
        !           201:
        !           202:        switch (val->type) {
        !           203:        case AML_OBJTYPE_INTEGER+AML_STATIC:
        !           204:                return "staticint";
        !           205:        case AML_OBJTYPE_INTEGER:
        !           206:                return "integer";
        !           207:        case AML_OBJTYPE_STRING:
        !           208:                return "string";
        !           209:        case AML_OBJTYPE_BUFFER:
        !           210:                return "buffer";
        !           211:        case AML_OBJTYPE_PACKAGE:
        !           212:                return "package";
        !           213:        case AML_OBJTYPE_DEVICE:
        !           214:                return "device";
        !           215:        case AML_OBJTYPE_EVENT:
        !           216:                return "event";
        !           217:        case AML_OBJTYPE_METHOD:
        !           218:                return "method";
        !           219:        case AML_OBJTYPE_MUTEX:
        !           220:                return "mutex";
        !           221:        case AML_OBJTYPE_OPREGION:
        !           222:                return "opregion";
        !           223:        case AML_OBJTYPE_POWERRSRC:
        !           224:                return "powerrsrc";
        !           225:        case AML_OBJTYPE_PROCESSOR:
        !           226:                return "processor";
        !           227:        case AML_OBJTYPE_THERMZONE:
        !           228:                return "thermzone";
        !           229:        case AML_OBJTYPE_DDBHANDLE:
        !           230:                return "ddbhandle";
        !           231:        case AML_OBJTYPE_DEBUGOBJ:
        !           232:                return "debugobj";
        !           233:        case AML_OBJTYPE_NAMEREF:
        !           234:                return "nameref";
        !           235:        case AML_OBJTYPE_OBJREF:
        !           236:                return "refof";
        !           237:        case AML_OBJTYPE_FIELDUNIT:
        !           238:        case AML_OBJTYPE_BUFFERFIELD:
        !           239:                return aml_mnem(val->v_field.type, NULL);
        !           240:        }
        !           241:
        !           242:        return ("");
        !           243: }
        !           244:
        !           245: void
        !           246: db_aml_walktree(struct aml_node *node)
        !           247: {
        !           248:        while (node) {
        !           249:                db_aml_showvalue(node->value);
        !           250:                db_aml_walktree(node->child);
        !           251:
        !           252:                node = node->sibling;
        !           253:        }
        !           254: }
        !           255:
        !           256: int
        !           257: db_parse_name(void)
        !           258: {
        !           259:        int             t, rv = 1;
        !           260:
        !           261:        memset(scope, 0, sizeof scope);
        !           262:        do {
        !           263:                t = db_read_token();
        !           264:                if (t == tIDENT) {
        !           265:                        if (strlcat(scope, db_tok_string, sizeof scope) >=
        !           266:                            sizeof scope) {
        !           267:                                printf("Input too long\n");
        !           268:                                goto error;
        !           269:                        }
        !           270:                        t = db_read_token();
        !           271:                        if (t == tDOT)
        !           272:                                if (strlcat(scope, ".", sizeof scope) >=
        !           273:                                    sizeof scope) {
        !           274:                                        printf("Input too long 2\n");
        !           275:                                        goto error;
        !           276:                                }
        !           277:                }
        !           278:        } while (t != tEOL);
        !           279:
        !           280:        if (!strlen(scope)) {
        !           281:                db_printf("Invalid input\n");
        !           282:                goto error;
        !           283:        }
        !           284:
        !           285:        rv = 0;
        !           286: error:
        !           287:        /* get rid of the rest of input */
        !           288:        db_flush_lex();
        !           289:        return (rv);
        !           290: }
        !           291:
        !           292: /* ddb interface */
        !           293: void
        !           294: db_acpi_showval(db_expr_t addr, int haddr, db_expr_t count, char *modif)
        !           295: {
        !           296:        struct aml_node *node;
        !           297:
        !           298:        if (db_parse_name())
        !           299:                return;
        !           300:
        !           301:        node = aml_searchname(&aml_root, scope);
        !           302:        if (node)
        !           303:                db_aml_showvalue(node->value);
        !           304:        else
        !           305:                db_printf("Not a valid value\n");
        !           306: }
        !           307:
        !           308: void
        !           309: db_acpi_disasm(db_expr_t addr, int haddr, db_expr_t count, char *modif)
        !           310: {
        !           311:        struct aml_node *node;
        !           312:
        !           313:        if (db_parse_name())
        !           314:                return;
        !           315:
        !           316:        node = aml_searchname(&aml_root, scope);
        !           317:        if (node && node->value && node->value->type == AML_OBJTYPE_METHOD) {
        !           318:                db_aml_disasm(node, node->value->v_method.start,
        !           319:                    node->value->v_method.end, -1, 0);
        !           320:        } else
        !           321:                db_printf("Not a valid method\n");
        !           322: }
        !           323:
        !           324: void
        !           325: db_acpi_tree(db_expr_t addr, int haddr, db_expr_t count, char *modif)
        !           326: {
        !           327:        db_aml_walktree(aml_root.child);
        !           328: }
        !           329:
        !           330: void
        !           331: db_acpi_trace(db_expr_t addr, int haddr, db_expr_t count, char *modif)
        !           332: {
        !           333:        struct aml_scope *root;
        !           334:        int idx;
        !           335:        extern struct aml_scope *aml_lastscope;
        !           336:
        !           337:        for (root=aml_lastscope; root && root->pos; root=root->parent) {
        !           338:                db_printf("%.4x Called: %s\n", aml_pc(root->pos),
        !           339:                    aml_nodename(root->node));
        !           340:                for (idx = 0; idx<root->nargs; idx++) {
        !           341:                        db_printf("  arg%d: ", idx);
        !           342:                        db_aml_showvalue(&root->args[idx]);
        !           343:                }
        !           344:                for (idx = 0; root->locals && idx < AML_MAX_LOCAL; idx++) {
        !           345:                        if (root->locals[idx].type) {
        !           346:                                db_printf("  local%d: ", idx);
        !           347:                                db_aml_showvalue(&root->locals[idx]);
        !           348:                        }
        !           349:                }
        !           350:        }
        !           351: }
        !           352:
        !           353: void
        !           354: db_aml_disline(uint8_t *pos, int depth, const char *fmt, ...)
        !           355: {
        !           356:        va_list ap;
        !           357:        char line[128];
        !           358:
        !           359:        db_printf("%.6x: ", aml_pc(pos));
        !           360:        while (depth--)
        !           361:                db_printf("  ");
        !           362:
        !           363:        va_start(ap, fmt);
        !           364:        vsnprintf(line, sizeof(line), fmt, ap);
        !           365:        db_printf(line);
        !           366:        va_end(ap);
        !           367: }
        !           368:
        !           369: void
        !           370: db_aml_disint(struct aml_scope *scope, int opcode, int depth)
        !           371: {
        !           372:        switch (opcode) {
        !           373:        case AML_ANYINT:
        !           374:                db_aml_disasm(scope->node, scope->pos, scope->end, -1, depth);
        !           375:                break;
        !           376:        case AMLOP_BYTEPREFIX:
        !           377:                db_aml_disline(scope->pos, depth, "0x%.2x\n",
        !           378:                    *(uint8_t *)(scope->pos));
        !           379:                scope->pos += 1;
        !           380:                break;
        !           381:        case AMLOP_WORDPREFIX:
        !           382:                db_aml_disline(scope->pos, depth, "0x%.4x\n",
        !           383:                    *(uint16_t *)(scope->pos));
        !           384:                scope->pos += 2;
        !           385:                break;
        !           386:        case AMLOP_DWORDPREFIX:
        !           387:                db_aml_disline(scope->pos, depth, "0x%.8x\n",
        !           388:                    *(uint32_t *)(scope->pos));
        !           389:                scope->pos += 4;
        !           390:                break;
        !           391:        case AMLOP_QWORDPREFIX:
        !           392:                db_aml_disline(scope->pos, depth, "0x%.4llx\n",
        !           393:                    *(uint64_t *)(scope->pos));
        !           394:                scope->pos += 8;
        !           395:                break;
        !           396:        }
        !           397: }
        !           398:
        !           399: uint8_t *
        !           400: db_aml_disasm(struct aml_node *root, uint8_t *start, uint8_t *end,
        !           401:     int count, int depth)
        !           402: {
        !           403:        int idx, opcode, len, off=0;
        !           404:        struct aml_scope *scope;
        !           405:        uint8_t *name, *pos;
        !           406:        const char *mnem, *args;
        !           407:        struct aml_node *node;
        !           408:        char *tmpstr;
        !           409:
        !           410:        if (start == end)
        !           411:                return end;
        !           412:
        !           413:        scope = aml_pushscope(NULL, start, end, root);
        !           414:        while (scope->pos < scope->end && count--) {
        !           415:                pos = scope->pos;
        !           416:                start = scope->pos;
        !           417:                opcode = aml_parseopcode(scope);
        !           418:
        !           419:                mnem = aml_mnem(opcode, scope->pos);
        !           420:                args = aml_args(opcode);
        !           421:
        !           422:                if (*args == 'p') {
        !           423:                        end = aml_parseend(scope);
        !           424:                        args++;
        !           425:                }
        !           426:                node = scope->node;
        !           427:                if (*args == 'N') {
        !           428:                        name = aml_parsename(scope);
        !           429:                        node = aml_searchname(scope->node, name);
        !           430:                        db_aml_disline(pos, depth, "%s %s (%s)\n",
        !           431:                            mnem, aml_getname(name), aml_nodename(node));
        !           432:                        args++;
        !           433:                } else if (mnem[0] != '.') {
        !           434:                        db_aml_disline(pos, depth, "%s\n", mnem);
        !           435:                }
        !           436:                while (*args) {
        !           437:                        pos = scope->pos;
        !           438:                        switch (*args) {
        !           439:                        case 'k':
        !           440:                        case 'c':
        !           441:                        case 'D':
        !           442:                        case 'L':
        !           443:                        case 'A':
        !           444:                                break;
        !           445:                        case 'i':
        !           446:                        case 't':
        !           447:                        case 'S':
        !           448:                        case 'r':
        !           449:                                scope->pos = db_aml_disasm(node, scope->pos,
        !           450:                                    scope->end, 1, depth+1);
        !           451:                                break;
        !           452:                        case 'T':
        !           453:                        case 'M':
        !           454:                                scope->pos = db_aml_disasm(node, scope->pos,
        !           455:                                    end, -1, depth+1);
        !           456:                                break;
        !           457:                        case 'I':
        !           458:                                /* Special case: if */
        !           459:                                scope->pos = db_aml_disasm(node, scope->pos,
        !           460:                                    end, -1, depth+1);
        !           461:                                if (scope->pos >= scope->end)
        !           462:                                        break;
        !           463:                                if (*scope->pos == AMLOP_ELSE) {
        !           464:                                        ++scope->pos;
        !           465:                                        end = aml_parseend(scope);
        !           466:                                        db_aml_disline(scope->pos, depth, "Else\n");
        !           467:                                        scope->pos = db_aml_disasm(node, scope->pos,
        !           468:                                            end, -1, depth+1);
        !           469:                                }
        !           470:                                break;
        !           471:                        case 'N':
        !           472:                                name = aml_parsename(scope);
        !           473:                                db_aml_disline(pos, depth+1, "%s\n", aml_getname(name));
        !           474:                                break;
        !           475:                        case 'n':
        !           476:                                off = (opcode != AMLOP_NAMECHAR);
        !           477:                                name = aml_parsename(scope);
        !           478:                                node = aml_searchname(scope->node, name);
        !           479:                                db_aml_disline(pos, depth+off, "%s <%s>\n",
        !           480:                                               aml_getname(name),
        !           481:                                               aml_nodename(node));
        !           482:
        !           483:                                if (!node || !node->value ||
        !           484:                                    node->value->type != AML_OBJTYPE_METHOD)
        !           485:                                        break;
        !           486:
        !           487:                                /* Method calls */
        !           488:                                for (idx = 0;
        !           489:                                     idx < AML_METHOD_ARGCOUNT(node->value->v_method.flags);
        !           490:                                     idx++) {
        !           491:                                        scope->pos = db_aml_disasm(node, scope->pos,
        !           492:                                            scope->end, 1, depth+1);
        !           493:                                }
        !           494:                                break;
        !           495:                        case 'b':
        !           496:                                off = (opcode != AMLOP_BYTEPREFIX);
        !           497:                                db_aml_disint(scope, AMLOP_BYTEPREFIX, depth+off);
        !           498:                                break;
        !           499:                        case 'w':
        !           500:                                off = (opcode != AMLOP_WORDPREFIX);
        !           501:                                db_aml_disint(scope, AMLOP_WORDPREFIX, depth+off);
        !           502:                                break;
        !           503:                        case 'd':
        !           504:                                off = (opcode != AMLOP_DWORDPREFIX);
        !           505:                                db_aml_disint(scope, AMLOP_DWORDPREFIX, depth+off);
        !           506:                                break;
        !           507:                        case 's':
        !           508:                                db_aml_disline(pos, depth, "\"%s\"\n", scope->pos);
        !           509:                                scope->pos += strlen(scope->pos)+1;
        !           510:                                break;
        !           511:                        case 'B':
        !           512:                                tmpstr = malloc(16 * 6 + 1, M_DEVBUF, M_WAITOK);
        !           513:                                for (idx = 0; idx < min(end-scope->pos, 8); idx++)
        !           514:                                        snprintf(tmpstr+idx*6, 7, "0x%.2x, ",
        !           515:                                            scope->pos[idx]);
        !           516:                                db_aml_disline(pos, depth+1, "ByteList <%s>\n", tmpstr);
        !           517:                                free(tmpstr, M_DEVBUF);
        !           518:                                scope->pos = end;
        !           519:                                break;
        !           520:                        case 'F':
        !           521:                                off = 0;
        !           522:                                while (scope->pos < end) {
        !           523:                                        len = 0;
        !           524:                                        pos = scope->pos;
        !           525:                                        switch (*scope->pos) {
        !           526:                                        case 0x00: // reserved
        !           527:                                                scope->pos++;
        !           528:                                                len = aml_parselength(scope);
        !           529:                                                db_aml_disline(pos, depth+1,
        !           530:                                                    "Reserved\t%.4x,%.4x\n",
        !           531:                                                     off, len);
        !           532:                                                break;
        !           533:                                        case 0x01: // attr
        !           534:                                                db_aml_disline(pos, depth+1,
        !           535:                                                    "Attr:%.2x,%.2x\n",
        !           536:                                                     scope->pos[1], scope->pos[2]);
        !           537:                                                scope->pos += 3;
        !           538:                                                break;
        !           539:                                        default:
        !           540:                                                name = aml_parsename(scope);
        !           541:                                                len = aml_parselength(scope);
        !           542:                                                db_aml_disline(pos, depth+1,
        !           543:                                                    "NamedField\t%.4x,%.4x %s\n",
        !           544:                                                    off, len, aml_getname(name));
        !           545:                                        }
        !           546:                                        off += len;
        !           547:                                }
        !           548:                                scope->pos = end;
        !           549:                                break;
        !           550:                        default:
        !           551:                                db_printf("remaining args: '%s'\n", args);
        !           552:                        }
        !           553:                        args++;
        !           554:                }
        !           555:        }
        !           556:        pos = scope->pos;
        !           557:        aml_popscope(scope);
        !           558:        return pos;
        !           559: }

CVSweb