示例#1
0
/* TODO maybe try not to use string port? */
static SgObject normalise_path(SgObject fullpath)
{
  SgStringPort sp;
  SgObject out = Sg_InitStringOutputPort(&sp, SG_STRING_SIZE(fullpath));
  int64_t pos = 0;
  int i = 0;
  while (i < SG_STRING_SIZE(fullpath)) {
    SgChar c = SG_STRING_VALUE_AT(fullpath, i++);
    if (c == '.') {
      if (i != SG_STRING_SIZE(fullpath)) {
	SgChar c2 = SG_STRING_VALUE_AT(fullpath, i++);
	if (c2 == '.') {
	  if (SG_STRING_VALUE_AT(fullpath, i) == '/' ||
	      SG_STRING_SIZE(fullpath) == i) {
	    if (pos-2 > 0) {
	      SgObject tmp = Sg_GetStringFromStringPort(out);
	      /* skip previous '.' and '/' */
	      pos = search_separator(tmp, pos-2);
	    } else {
	      pos = 1;		/* root */
	    }
	    if (pos <= 0) pos = 1; /* root */
	    Sg_SetPortPosition(out, pos, SG_BEGIN);
	    if (pos == 1) i++;
	  } else {
	    /* ok just a file named '..?' or longer*/
	    Sg_PutcUnsafe(out, '.');
	    Sg_PutcUnsafe(out, '.');
	    pos += 2;
	    for (; i < SG_STRING_SIZE(fullpath); i++) {
	      SgChar c3 = SG_STRING_VALUE_AT(fullpath, i);
	      if (c3 != '.') break;
	      Sg_PutcUnsafe(out, c3);
	      pos++;
	    }
	  }
	} else if (c2 != '/') {
	  Sg_PutcUnsafe(out, '.');
	  Sg_PutcUnsafe(out, c2);
	  pos += 2;
	}
      }
    } else {
      Sg_PutcUnsafe(out, c);
      pos++;
    }
  }
  return strip_trailing_slash(Sg_GetStringFromStringPort(out));
}
示例#2
0
/* 
 * Returns length of all starting parent references.
 */
static uint 
gp_file_name_prefix(const char *fname, uint flen, 
		bool (*test)(const char *fname, uint flen))
{
    uint plen = gp_file_name_root(fname, flen), slen;
    const char *ip, *ipe; 
    const char *item = fname; /* plen == flen could cause an indeterminizm. */

    if (plen > 0)
	return 0;
    ip = fname + plen;
    ipe = fname + flen;
    for (; ip < ipe; ) {
	item = ip;
	slen = search_separator(&ip, ipe, item, 1);
	if (!(*test)(item, ip - item))
	    break;
	ip += slen;
    }
    return item - fname;
}
示例#3
0
/*
 * Combine a file name with a prefix.
 * Concatenates two paths and reduce parent references and current 
 * directory references from the concatenation when possible.
 * The trailing zero byte is being added.
 *
 * Returns "gp_combine_success" if OK and sets '*blen' to the length of
 * the combined string. If the combined string is too small for the buffer
 * length passed in (as defined by the initial value of *blen), then the
 * "gp_combine_small_buffer" code is returned.
 *
 * Also tolerates/skips leading IODevice specifiers such as %os% or %rom%
 * When there is a leading '%' in the 'fname' no other processing is done.
 *
 * Examples : 
 *	"/gs/lib" + "../Resource/CMap/H" --> "/gs/Resource/CMap/H"
 *	"C:/gs/lib" + "../Resource/CMap/H" --> "C:/gs/Resource/CMap/H"
 *	"hard disk:gs:lib" + "::Resource:CMap:H" --> 
 *		"hard disk:gs:Resource:CMap:H"
 *	"DUA1:[GHOSTSCRIPT.LIB" + "-.RESOURCE.CMAP]H" --> 
 *		"DUA1:[GHOSTSCRIPT.RESOURCE.CMAP]H"
 *      "\\server\share/a/b///c/../d.e/./" + "../x.e/././/../../y.z/v.v" --> 
 *		"\\server\share/a/y.z/v.v"
 *	"%rom%lib/" + "gs_init.ps" --> "%rom%lib/gs_init.ps
 *	"" + "%rom%lib/gs_init.ps" --> "%rom%lib/gs_init.ps"
 */
gp_file_name_combine_result
gp_file_name_combine_generic(const char *prefix, uint plen, const char *fname, uint flen, 
		    bool no_sibling, char *buffer, uint *blen)
{
    /*
     * THIS CODE IS SHARED FOR MULTIPLE PLATFORMS.
     * PLEASE DON'T CHANGE IT FOR A SPECIFIC PLATFORM.
     * Change gp_file_name_combine instead.
     */
    char *bp = buffer, *bpe = buffer + *blen;
    const char *ip, *ipe;
    uint slen;
    uint infix_type = 0; /* 0=none, 1=current, 2=parent. */
    uint infix_len = 0;
    uint rlen = gp_file_name_root(fname, flen);
    /* We need a special handling of infixes only immediately after a drive. */

    if ( flen > 0 && fname[0] == '%') {
    	/* IoDevice -- just return the fname as-is since this */
	/* function only handles the default file system */
	/* NOTE: %os% will subvert the normal processing of prefix and fname */
	ip = fname;
	*blen = flen;
	if (!append(&bp, bpe, &ip, flen))
	    return gp_combine_small_buffer;
	return gp_combine_success;
    }
    if (rlen != 0) {
        /* 'fname' is absolute, ignore the prefix. */
	ip = fname;
	ipe = fname + flen;
    } else {
        /* Concatenate with prefix. */
	ip = prefix;
	ipe = prefix + plen;
	rlen = gp_file_name_root(prefix, plen);
    }
    if (!append(&bp, bpe, &ip, rlen))
	return gp_combine_small_buffer;
    slen = gs_file_name_check_separator(bp, buffer - bp, bp); /* Backward search. */
    if (rlen != 0 && slen == 0) {
	/* Patch it against names like "c:dir" on Windows. */
	const char *sep = gp_file_name_directory_separator();

	slen = strlen(sep);
	if (!append(&bp, bpe, &sep, slen))
	    return gp_combine_small_buffer;
	rlen += slen;
    }
    for (;;) {
	const char *item = ip;
	uint ilen;

	slen = search_separator(&ip, ipe, item, 1);
	ilen = ip - item;
	if (ilen == 0 && !gp_file_name_is_empty_item_meanful()) {
	    ip += slen;
	    slen = 0;
	} else if (gp_file_name_is_current(item, ilen)) {
	    /* Skip the reference to 'current', except the starting one.
	     * We keep the starting 'current' for platforms, which
	     * require relative paths to start with it.
	     */
	    if (bp == buffer) {
		if (!append(&bp, bpe, &item, ilen))
		    return gp_combine_small_buffer;
		infix_type = 1;
		infix_len = ilen;
	    } else {
		ip += slen;
		slen = 0;
	    }
	} else if (!gp_file_name_is_parent(item, ilen)) {
	    if (!append(&bp, bpe, &item, ilen))
		return gp_combine_small_buffer;
	    /* The 'item' pointer is now broken; it may be restored using 'ilen'. */
	} else if (bp == buffer + rlen + infix_len) {
	    /* Input is a parent and the output only contains a root and an infix. */
	    if (rlen != 0)
		return gp_combine_cant_handle;
	    switch (infix_type) {
		case 1:
		    /* Replace the infix with parent. */
		    bp = buffer + rlen; /* Drop the old infix, if any. */
		    infix_len = 0;
		    /* Falls through. */
		case 0:
		    /* We have no infix, start with parent. */
		    if ((no_sibling && ipe == fname + flen && flen != 0) || 
			    !gp_file_name_is_partent_allowed())
			return gp_combine_cant_handle;
		    /* Falls through. */
		case 2:
		    /* Append one more parent - falls through. */
		    DO_NOTHING;
	    }
	    if (!append(&bp, bpe, &item, ilen))
		return gp_combine_small_buffer;
	    infix_type = 2;
	    infix_len += ilen;
	    /* Recompute the separator length. We cannot use the old slen on Mac OS. */
	    slen = gs_file_name_check_separator(ip, ipe - ip, ip);
	} else {
	    /* Input is a parent and the output continues after infix. */
	    /* Unappend the last separator and the last item. */
	    uint slen1 = gs_file_name_check_separator(bp, buffer + rlen - bp, bp); /* Backward search. */
	    char *bie = bp - slen1;

	    bp = bie;
	    DISCARD(search_separator((const char **)&bp, buffer + rlen, bp, -1));
	    /* The cast above quiets a gcc warning. We believe it's a bug in the compiler. */
	    /* Skip the input with separator. We cannot use slen on Mac OS. */
	    ip += gs_file_name_check_separator(ip, ipe - ip, ip);
	    if (no_sibling) {
		const char *p = ip;

		DISCARD(search_separator(&p, ipe, ip, 1));
		if (p - ip != bie - bp || memcmp(ip, bp, p - ip))    
		    return gp_combine_cant_handle;
	    }
	    slen = 0;
	}
	if (slen) {
	    if (bp == buffer + rlen + infix_len)
		infix_len += slen;
	    if (!append(&bp, bpe, &ip, slen))
		return gp_combine_small_buffer;
	}
	if (ip == ipe) {
	    if (ipe == fname + flen) {
		/* All done.
		 * Note that the case (prefix + plen == fname && flen == 0)
		 * falls here without appending a separator.
		 */
		const char *zero="";

		if (bp == buffer) {
		    /* Must not return empty path. */
		    const char *current = gp_file_name_current();
		    int clen = strlen(current);

		    if (!append(&bp, bpe, &current, clen))
			return gp_combine_small_buffer;
		}
		*blen = bp - buffer;
		if (!append(&bp, bpe, &zero, 1))
		    return gp_combine_small_buffer;
		return gp_combine_success;
	    } else {
	        /* ipe == prefix + plen */
		/* Switch to fname. */
		ip = fname;
		ipe = fname + flen;
		if (slen == 0) {
		    /* Insert a separator. */
		    const char *sep;
    
		    slen = search_separator(&ip, ipe, fname, 1);
		    sep = (slen != 0 ? gp_file_name_directory_separator() 
		                    : gp_file_name_separator());
		    slen = strlen(sep);
		    if (bp == buffer + rlen + infix_len)
			infix_len += slen;
		    if (!append(&bp, bpe, &sep, slen))
			return gp_combine_small_buffer;
		    ip = fname; /* Switch to fname. */
		}
	    }
	}
    }
}
示例#4
0
static void     scan_script( void )
{
    inputcb     *   cb;
    mac_entry   *   me;
    char        *   p;
    char        *   pt;
    int             toklen;
    int             k;
    bool            cwfound;

    cb = input_cbs;
    p = scan_start + 1;
    scan_restart = scan_start;

    if( (*p == '*') || !strnicmp( p, "cm ", 3 ) ) {
        scan_start = scan_stop + 1;     // .cm  +++ ignore comment up to EOL
        return;                         // .*   +++ ignore comment up to EOL
    }

    if( *p == SCR_char && *(p+1) == SCR_char ) {
            pt = token_buf;
            *pt++ = SCR_char;               // special for ...label
            *pt++ = SCR_char;
            *pt   = '\0';
            me = NULL;
            scan_start = p + 2;
            toklen = 2;
    } else {
        if( *p == '\'' ) {                  // .'
            p++;
            ProcFlags.CW_sep_ignore = 1;
        } else {
            if( CW_sep_char == '\0') {
                ProcFlags.CW_sep_ignore = 1;// No separator char no split
            } else{
                ProcFlags.CW_sep_ignore = 0;
            }
            if( *p == SCR_char ) {          // ..
                p++;
                ProcFlags.macro_ignore = 1;
                me = NULL;
            } else {
                ProcFlags.macro_ignore = 0;
            }
        }
        if( ProcFlags.literal ) {       // no macro or split line if literal
            ProcFlags.CW_sep_ignore = 1;
            ProcFlags.macro_ignore = 1;
        }
        if( !ProcFlags.CW_sep_ignore ) { // scan line for CW_sep_char
            char    *   pchar;

            pchar = search_separator( buff2, CW_sep_char );

            if( pchar != NULL ) {
                if( *(pchar + 1) != '\0' ) {    // only split if more follows
                    split_input( buff2, pchar + 1, false );// ignore CW_sep_char
                }
                *pchar= '\0';               // delete CW_sep_char
                buff2_lg = strlen( buff2 ); // new length of first part
            }
        }

        scan_start = p;

        pt = token_buf;
        while( *p && is_macro_char( *p ) ) {  // end of controlword
           *pt++ = tolower( *p++ );     // copy lowercase to TokenBuf
        }
        *pt = '\0';

        toklen = pt - token_buf;

        if( *p && (*p != ' ') || toklen == 0 ) {// no valid script controlword / macro
//          if( !ProcFlags.literal ) {   // TBD
//             cw_err();
//          }
            scan_start = scan_restart;  // treat as text
            return;
        }

        if( toklen >= MAC_NAME_LENGTH ) {
            *(token_buf + MAC_NAME_LENGTH) = '\0';
        }
        if( !ProcFlags.macro_ignore ) {
            me = find_macro( macro_dict, token_buf );
        } else {
            me = NULL;
        }
    }

    if( me != NULL ) {                  // macro found
        if( GlobalFlags.firstpass && cb->fmflags & II_research ) {
            if( cb->fmflags & II_macro ) {
                printf_research( "L%d    %c%s macro found in macro %s(%d)\n\n",
                                 inc_level, SCR_char, token_buf,
                                 cb->s.m->mac->name, cb->s.m->lineno );
            } else {
                printf_research( "L%d    %c%s macro found in file %s(%d)\n\n",
                                 inc_level, SCR_char, token_buf,
                                 cb->s.f->filename, cb->s.f->lineno );
            }
            add_SCR_tag_research( token_buf );
        }
        add_macro_cb_entry( me, NULL );
        inc_inc_level();
        add_macro_parms( p );
        scan_restart = scan_stop + 1;
    } else {                            // try script controlword
        cwfound = false;
        if( cb->fmflags & II_research && GlobalFlags.firstpass ) {
            if( cb->fmflags & II_macro ) {
                printf_research( "L%d    %c%s CW found in macro %s(%d)\n\n",
                                 inc_level, SCR_char, token_buf,
                                 cb->s.m->mac->name, cb->s.m->lineno );
            } else {
                printf_research( "L%d    %c%s CW found in file %s(%d)\n\n",
                                 inc_level, SCR_char, token_buf,
                                 cb->s.f->filename, cb->s.f->lineno );
            }
            add_SCR_tag_research( token_buf );
        }

        if( toklen == SCR_KW_LENGTH ) {
            for( k = 0; k < SCR_TAGMAX; ++k ) {
                if( !strcmp( scr_tags[k].tagname, token_buf ) ) {
#if 0
                    if( !ProcFlags.fb_document_done &&
                          scr_tags[k].cwflags & cw_o_t ) {

                        /***************************************************/
                        /*  if this is the first cw  which produces output */
                        /* set page geometry and margins from layout       */
                        /***************************************************/
                        do_layout_end_processing();
                    }
#endif
                    if( !ProcFlags.layout && (scr_tags[k].cwflags & cw_o_t) ) {

                        /********************************************************/
                        /* this is the first control word which produces output */
                        /* start the document, the layout is done               */
                        /* start_doc_sect() calls do_layout_end_processing()    */
                        /********************************************************/

                        start_doc_sect();
                    }
                    if( ProcFlags.literal  ) {  // .li active
                        if( !strcmp( token_buf, "li" ) ) {  // .li
                            scan_start = p; // found, process
                            scr_tags[k].tagproc();
                        }
                    } else {
                        scan_start = p; // script controlword found, process
                        if( scr_tags[k].cwflags & cw_break ) {
                            scr_process_break();// output incomplete line, if any
                        }
                        scr_tags[k].tagproc();
                    }
                    cwfound = true;
                    break;
                }
            }
        }
        if( !cwfound ) {
            cw_err();                   // unrecognized control word
        }
    }
    scan_start = scan_restart;
}