~chrisppy/hare-atom

b1b392bdbf3bea4fe7239e121df81e549026b125 — Chris Palmer a month ago 08124dc
add extensions for person

Signed-off-by: Chris Palmer <chris@red-oxide.org>
4 files changed, 73 insertions(+), 12 deletions(-)

M format/atom/+test.ha
M format/atom/finish.ha
M format/atom/scan.ha
M format/atom/types.ha
M format/atom/+test.ha => format/atom/+test.ha +22 -2
@@ 79,6 79,9 @@ use strings;
	scmp("Feed Author 1 Email",
		"",
		f.authors[0].email);
	zcmp("Feed Author 1 Extensions",
		0z,
		len(f.authors[0].extensions));
	zcmp("Feed Categories",
		0z,
		len(f.categories));


@@ 187,6 190,11 @@ use strings;
		<name>Mark Pilgrim</name>
		<uri>http://example.org/</uri>
		<email>f8dy@example.com</email>
		<a:simple>test</a:simple>
		<a:complex xlmns="a" type="ext">
			<a:t a="b"/>
			<a:name>test</a:name>
		</a:complex>
	</author>
	<contributor>
		<name>Mark Pilgrim</name>


@@ 300,6 308,9 @@ use strings;
	scmp("Feed Author 1 Email",
		"f8dy@example.com",
		f.authors[0].email);
	zcmp("Feed Author 1 Extensions",
		13z,
		len(f.authors[0].extensions));
	zcmp("Feed Contibutors",
		1z,
		len(f.contributors));


@@ 312,6 323,9 @@ use strings;
	scmp("Feed Contributor 1 Email",
		"f8dy@example.com",
		f.contributors[0].email);
	zcmp("Feed Contributor 1 Extensions",
		0z,
		len(f.contributors[0].extensions));
	scmp("Feed Generator Value",
		"Example Toolkit",
		f.generator.0);


@@ 411,6 425,9 @@ use strings;
	scmp("Entry 1 Author 1 Email",
		"f8dy@example.com",
		f.entries[0].authors[0].email);
	zcmp("Entry 1 Author 1 Extensions",
		0z,
		len(f.entries[0].authors[0].extensions));
	zcmp("Entry 1 Contibutors",
		2z,
		len(f.entries[0].contributors));


@@ 423,15 440,18 @@ use strings;
	scmp("Entry 1 Contributor 1 Email",
		"",
		f.entries[0].contributors[0].email);
	scmp("Entry 1 Contibutor 1 Name",
	scmp("Entry 1 Contributor 1 Name",
		"Joe Gregorio",
		f.entries[0].contributors[1].name);
	scmp("Entry 1 Contibutor 1 URI",
	scmp("Entry 1 Contributor 1 URI",
		"",
		f.entries[0].contributors[1].uri);
	scmp("Entry 1 Contributor 1 Email",
		"",
		f.entries[0].contributors[1].email);
	zcmp("Entry 1 Contributor 1 Extensions",
		0z,
		len(f.entries[0].contributors[0].extensions));
	zcmp("Entry 1 Categories",
		1z,
		len(f.entries[0].categories));

M format/atom/finish.ha => format/atom/finish.ha +1 -0
@@ 72,6 72,7 @@ fn person_finish(p: *person) void = {
	free(p.name);
	free(p.uri);
	free(p.email);
	free(p.extensions);
};

fn entry_finish(e: *entry) void = {

M format/atom/scan.ha => format/atom/scan.ha +47 -6
@@ 10,10 10,11 @@ use strio;
export fn scan(in: io::handle) (feed | error) = {
	const parser = xml::parse(in)?;
	defer xml::parser_free(parser);
	return scan_feed(parser);

	return scan_root(parser);
};

fn scan_feed(p: *xml::parser) (feed | error) = {
fn scan_root(p: *xml::parser) (feed | error) = {
	match (xml::scan(p)?) {
	case void =>
		return format;


@@ 31,6 32,10 @@ fn scan_feed(p: *xml::parser) (feed | error) = {
		};
	};

	return scan_feed(p);
};

fn scan_feed(p: *xml::parser) (feed | error) = {
	let f = feed{ ... };

	for (true) {


@@ 318,6 323,7 @@ fn scan_person(p: *xml::parser) (person | error) = {
	let name = strio::dynamic();
	let uri = strio::dynamic();
	let email = strio::dynamic();
	let ext: []xml::token = [];

	let cur_elem = "";
	for (true) {


@@ 327,26 333,60 @@ fn scan_person(p: *xml::parser) (person | error) = {
		case let tok: xml::token =>
			match (tok) {
			case let e: xml::elementend =>
				switch (e) {
				switch (strings::trim(e)) {
				case "author" =>
					break;
				case "contributor" =>
					break;
				case =>
				case "name" =>
					continue;
				case "uri" =>
					continue;
				case "email" =>
					continue;
				case "" =>
					continue;
				case =>
					append(ext, tok);
				};
			case let e: xml::elementstart =>
				cur_elem = e;
				switch (strings::trim(e)) {
				case "name" =>
					cur_elem = e;
				case "uri" =>
					cur_elem = e;
				case "email" =>
					cur_elem = e;
				case "" =>
					continue;
				case =>
					cur_elem = e;
					append(ext, tok);
				};
			case let txt: xml::text =>
				switch (cur_elem) {
				txt = strings::trim(txt);
				if (txt == "") {
					continue;
				};

				switch (strings::trim(cur_elem)) {
				case "name" =>
					strio::concat(&name, txt)?;
				case "uri" =>
					strio::concat(&uri, txt)?;
				case "email" =>
					strio::concat(&email, txt)?;
				case "" =>
					continue;
				case =>
					append(ext, tok);
				};
			case let at: xml::attribute =>
				switch (strings::trim(at.0)) {
				case "" =>
					continue;
				case =>
					append(ext, tok);
				};
			case =>
				continue;


@@ 358,5 398,6 @@ fn scan_person(p: *xml::parser) (person | error) = {
		name = strings::trim(strio::string(&name)),
		uri = strings::trim(strio::string(&uri)),
		email = strings::trim(strio::string(&email)),
		extensions = ext,
	};
};

M format/atom/types.ha => format/atom/types.ha +3 -4
@@ 17,13 17,12 @@ export type category = struct {
	label: str,
};


// An Atom person element.
export type person = struct {
	name: str,
	uri: str,
	email: str,
	// TODO: extensions elements
	extensions: []xml::token,
};

// An Atom link element.


@@ 49,8 48,8 @@ export type entry = struct {
	contributors: []person,
	categories: []category,
	links: []link,
	extensions: []xml::token,
	// TODO: source element
	// TODO: extensions elements
};

// An Atom feed element.


@@ 68,7 67,7 @@ export type feed = struct {
	categories: []category,
	links: []link,
	generator: generator,
	// TODO: extensions elements
	extensions: []xml::token,
};

// Returned when scanning a XML file which does not meet the expected schema.