Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCDoc / SCDocPrim.cpp
blobe727507a4bc4e80b80dde91a9d9830c34e6c7c00
1 /************************************************************************
3 * Copyright 2012 Jonatan Liljedahl <lijon@kymatica.com>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 ************************************************************************/
20 #include "GC.h"
21 #include "PyrKernel.h"
22 #include "PyrPrimitive.h"
23 #include "PyrSymbol.h"
24 #include "SCBase.h"
25 #include "SC_DirUtils.h"
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <cerrno>
32 //extern "C" {
33 #include "SCDoc.h"
34 //}
36 PyrSymbol *s_scdoc_node;
38 static void _doc_traverse(struct VMGlobals* g, DocNode *n, PyrObject *parent, PyrSlot *slot)
40 PyrObject *result = instantiateObject( g->gc, s_scdoc_node->u.classobj, 0, false, false );
41 result->size = 0;
42 SetObject(slot, result);
43 if(parent) g->gc->GCWrite(parent, result);
45 PyrSymbol *id = getsym(n->id);
46 SetSymbol(result->slots+result->size++, id);
48 if(n->text) {
49 PyrObject *str = (PyrObject*) newPyrString(g->gc, n->text, 0, true);
50 SetObject(result->slots+result->size++, str);
51 g->gc->GCWrite(result, str);
52 } else {
53 SetNil(result->slots+result->size++);
56 if(n->n_childs) {
57 PyrObject *array = newPyrArray(g->gc, n->n_childs, 0, true);
58 array->size = 0;
59 SetObject(result->slots+result->size++, array);
60 g->gc->GCWrite(result, array);
61 for(int i=0; i<n->n_childs; i++) {
62 array->size++;
63 _doc_traverse(g, n->children[i], array, array->slots+i);
65 } else {
66 SetNil(result->slots+result->size++);
68 result->size += 3; // makeDiv, notPrivOnly, sort
72 int prSCDoc_ParseFile(struct VMGlobals* g, int numArgsPushed)
74 PyrSlot *a, *b, *c;
75 char filename[PATH_MAX];
76 int mode, err;
78 a = g->sp - 2;
79 b = g->sp - 1;
80 c = g->sp;
82 err = slotStrVal(b, filename, PATH_MAX);
83 if (err) return err;
85 err = slotIntVal(c, &mode);
86 if (err) return err;
88 DocNode *n = scdoc_parse_file(filename, mode);
89 if(n) {
90 // doc_node_dump(n);
91 _doc_traverse(g, n, NULL, a);
92 doc_node_free_tree(n);
93 } else {
94 SetNil(a);
96 return errNone;
99 void initSCDocPrimitives()
101 int base, index = 0;
103 s_scdoc_node = getsym("SCDocNode");
105 base = nextPrimitiveIndex();
107 definePrimitive(base, index++, "_SCDoc_ParseFile", prSCDoc_ParseFile, 3, 0);