| 
					
				 | 
			
			
				@@ -0,0 +1,97 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Copyright (C) 2014 OSCAR lab, Stony Brook University 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   This file is part of Graphene Library OS. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   Graphene Library OS is free software: you can redistribute it and/or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   modify it under the terms of the GNU General Public License 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   as published by the Free Software Foundation, either version 3 of the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   License, or (at your option) any later version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   Graphene Library OS is distributed in the hope that it will be useful, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   but WITHOUT ANY WARRANTY; without even the implied warranty of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   GNU General Public License for more details. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   You should have received a copy of the GNU General Public License 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * path.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * This file contains functions to read app config (manifest) file and create 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * a tree to lookup / access config values. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <api.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <pal_error.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int get_norm_path (const char * path, char * buf, int offset, int size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int head = offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char c, c1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const char * p = path; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (head) { /* find the real head, not interrupted by dot-dot */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (head > 1 && buf[head - 1] == '.' && buf[head - 2] == '.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        head--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (c = '/' ; c ; c = c1, p++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        c1 = *p; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (c == '/') {     /* find a slash, or the beginning of the path */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (c1 == 0)    /* no more path */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (c1 == '/')  /* consequential slashes */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (c1 == '.') {    /* find a dot, can be dot-dot or a file */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                c1 = *(++p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (c1 == 0)    /* no more path */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (c1 == '/')  /* a dot, skip it */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (c1 == '.') {    /* must be dot-dot */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    c1 = *(++p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (c1 != 0 && c1 != '/')   /* must be the end or a slash */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return -PAL_ERROR_INVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (offset > head) {    /* remove the last token */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        while (offset > head && buf[--offset] != '/'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (offset) {   /* add a slash */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            if (offset >= size - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                return -PAL_ERROR_TOOLONG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            buf[offset++] = '/'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        }               /* add a dot-dot */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (offset >= size - 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return -PAL_ERROR_TOOLONG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        buf[offset++] = '.'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        buf[offset++] = '.'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        head = offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { /* it's a file */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (offset) {   /* add a slash */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (offset >= size - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return -PAL_ERROR_TOOLONG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        buf[offset++] = '/'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (offset >= size - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return -PAL_ERROR_TOOLONG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    buf[offset++] = '.'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (offset || c != '/') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (offset >= size - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return -PAL_ERROR_TOOLONG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            buf[offset++] = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    buf[offset] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 |