/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "rdf-int.h" char* error_string = NULL; int lineNumber = 0; void main (int argc, char* argv[]) { RDFFile rf = initFileStruct(); int ok = 1; error_string = getMem(1000); if (argc == 2) { FILE* f = fopen(argv[1], "r"); if (f != NULL) { char* buff = getMem(RDF_BUF_SIZE); int len; while (ok && ((len = fread(buff, 1, RDF_BUF_SIZE-1, f)) > 0)) { buff[len] = '\0'; ok = parseNextRDFXMLBlobInt(rf, buff, strlen(buff)); memset(buff, '\0', RDF_BUF_SIZE); } } if (ok) { while (1) { char* nextQuery = getMem(200); int n; nextQuery = gets(nextQuery); if (nextQuery) { char** ans = processRDFQuery(nextQuery); if (ans) { for (n = 0; ans[n] != NULL; n++) { printf("%s\n", ans[n]); } } } else { break; } } } } } void RDF_Init () { error_string = getMem(1000); } int RDF_DigestNewStuff (char* fileName, char* data, int len) { RDFFile rf = initFileStruct(); int ok = 1; ok = parseNextRDFXMLBlobInt(rf, data, len); freeMem(rf->line); freeMem(rf->holdOver); return ok; } RDFFile initFileStruct (void) { RDFFile ans = (RDFFile)getMem(sizeof(RDF_FileStruct)); ans->line = (char*)getMem(RDF_BUF_SIZE); ans->holdOver = (char*)getMem(RDF_BUF_SIZE); ans->depth = 1; ans->lastItem = ans->stack[0] ; return ans; } PRBool startsWith (const char* pattern, const char* uuid) { int l1 = strlen(pattern); int l2 = strlen(uuid); int n; if (l2 < l1) return 0; for (n = 0; n < l1; n++) { if (pattern[n] != uuid[n]) return 0; } return 1; } char* getMem (size_t n) { return (char*) calloc(1, n); } void freeMem(void* item) { free(item); } char decodeEntityRef (char* string, int* stringIndexPtr, int len) { if (startsWith("lt;", string)) { *stringIndexPtr = *stringIndexPtr + 3; return '<'; } else if (startsWith("gt;", string)) { *stringIndexPtr = *stringIndexPtr + 3; return '>'; } else if (startsWith("amp;", string)) { *stringIndexPtr = *stringIndexPtr + 4; return '&'; } else return '&'; } char * copyStringIgnoreWhiteSpace(char* string) { int len = strlen(string); char* buf = (char*)getMem(len + 1); PRBool inWhiteSpace = 1; int buffIndex = 0; int stringIndex = 0; while (stringIndex < len) { char nextChar = *(string + stringIndex); PRBool wsp = wsCharp(nextChar); if (!wsp) { if (nextChar == '&') { *(buf + buffIndex++) = decodeEntityRef(&string[stringIndex+1], &stringIndex, len-stringIndex); } else { *(buf + buffIndex++) = nextChar; } inWhiteSpace = 0; } else if (!inWhiteSpace) { *(buf + buffIndex++) = ' '; inWhiteSpace = 1; } else { inWhiteSpace = 1; } stringIndex++; } return buf; } char * getHref(char** attlist) { char* ans = getAttributeValue(attlist, "resource"); if (!ans) ans = getAttributeValue(attlist, "rdf:resource"); return ans; } char * getID(char** attlist) { char* ans = getAttributeValue(attlist, "id"); if (!ans) ans = getAttributeValue(attlist, "about"); if (!ans) ans = getAttributeValue(attlist, "rdf:about"); return ans; } int parseNextRDFXMLBlobInt(RDFFile f, char* blob, int size) { int n, last, m; PRBool somethingseenp = 0; n = last = 0; while (n < size) { char c = blob[n]; if ((c == '\n') || (c == '\r')) lineNumber++; m = 0; somethingseenp = 0; memset(f->line, '\0', RDF_BUF_SIZE-1); if (f->holdOver[0] != '\0') { memcpy(f->line, f->holdOver, strlen(f->holdOver)); m = strlen(f->holdOver); somethingseenp = 1; memset(f->holdOver, '\0', RDF_BUF_SIZE-1); } while ((n < size) && (wsCharp(c))) { c = blob[++n]; if ((c == '\n') || (c == '\r')) lineNumber++; } while ((m < RDF_BUF_SIZE) && (c != '<') && (c != '>')) { f->line[m] = c; m++; somethingseenp = (somethingseenp || (!(wsCharp(c)))); n++; if (n < size) c = blob[n]; else break; if ((c == '\n') || (c == '\r')) lineNumber++; } if (c == '>') f->line[m] = c; n++; if (m > 0) { if ((c == '<') || (c == '>')) { last = n; if (c == '<') f->holdOver[0] = '<'; if (somethingseenp == 1) { int ok = parseNextRDFToken(f, f->line); if (!ok) return 0; } } else if (size > last) { memcpy(f->holdOver, f->line, m); } } else if (c == '<') f->holdOver[0] = '<'; } return(1); } char * getAttributeValue (char** attlist, char* elName) { size_t n = 0; if (!attlist) return NULL; while ((n < 2*MAX_ATTRIBUTES) && (*(attlist + n) != NULL)) { if (strcmp(*(attlist + n), elName) == 0) return *(attlist + n + 1); n = n + 2; } return NULL; } char* copyString (char* str) { char* ans = getMem(strlen(str)+1); if (ans) { memcpy(ans, str, strlen(str)); return ans; } else return NULL; } void addElementProps (char** attlist, char* elementName, RDFFile f, RDF_Resource obj) { int count = 0; while (count < 2*MAX_ATTRIBUTES) { char* attName = attlist[count++]; char* attValue = attlist[count++]; if ((attName == NULL) || (attValue == NULL)) break; if (!stringEquals(attName, "resource") && !stringEquals(attName, "rdf:resource") && !stringEquals(attName, "about") && !stringEquals(attName, "rdf:about") && !stringEquals(attName, "tv") && !stringEquals(attName, "id")) { remoteStoreAdd(f, obj, getResource(f, attName), copyStringIgnoreWhiteSpace(attValue), RDF_STRING_TYPE, 1); } } } int parseNextRDFToken (RDFFile f, char* token) { char* attlist[2*MAX_ATTRIBUTES+1]; char* elementName; if (token[0] == '<') { size_t len = strlen(token); if (token[len-2] != '/') { if (token[1] == '/') { char* tok = getMem(len); memcpy(tok, &token[2], len-3); if (!stringEquals(tok, f->tagStack[f->tagDepth-1])) { sprintf(error_string, "Unbalanced tags : Expecting , found %s", f->tagStack[f->tagDepth-1], token); return 0; } else { f->tagDepth--; freeMem(tok); } } } } if (token[0] != '<') { if ((f->status == EXPECTING_OBJECT) && (f->depth > 1)) { RDF_Resource u = f->stack[f->depth-2]; RDF_Resource s = f->stack[f->depth-1]; char* val = copyStringIgnoreWhiteSpace(token); remoteStoreAdd(f, u, s, val , RDF_STRING_TYPE, 1); } else { sprintf(error_string, "Did not expect \n\"%s\".\n Was expecting a tag.", token); return 0; } } else if (startsWith("