static char *get_token(char *line, int which, int max) { char *c; int l, i; /* Return a pointer to the which'th white space separated * token in the line. which is 0 for the first token. */ c = line; l = 0; while (IS_BLANK(*c) && (l < max)){ c++; l++; } /* skip initial spaces */ if ((l>=max) || !*c || (*c == '\n')) return NULL; if (which == 0) return c; for (i=0; i < which; i++){ while (isgraph(*c) && (l < max)){ c++; l++;} /* skip token */ if ((l>=max) || !*c || (*c == '\n')) return NULL; while (IS_BLANK(*c) && (l < max)){ c++; l++;} /* skip space */ if ((l>=max) || !*c || (*c == '\n')) return NULL; } return c; }
void xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst ATTRIBUTE_UNUSED, const xmlChar * attributes) { const xmlChar *ncname = NULL; const xmlChar *prefix = NULL; const xmlChar *attrib, *endattr; xsltAttrElemPtr values; xsltStylesheetPtr style; if (attributes == NULL) { return; } attrib = attributes; while (*attrib != 0) { while (IS_BLANK(*attrib)) attrib++; if (*attrib == 0) break; endattr = attrib; while ((*endattr != 0) && (!IS_BLANK(*endattr))) endattr++; attrib = xmlDictLookup(ctxt->dict, attrib, endattr - attrib); if (attrib) { #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "apply attribute set %s\n", attrib); #endif ncname = xsltSplitQName(ctxt->dict, attrib, &prefix); style = ctxt->style; #ifdef WITH_DEBUGGER if ((style != NULL) && (style->attributeSets != NULL) && (ctxt->debugStatus != XSLT_DEBUG_NONE)) { values = xmlHashLookup2(style->attributeSets, ncname, prefix); if ((values != NULL) && (values->attr != NULL)) xslHandleDebugger(values->attr->parent, node, NULL, ctxt); } #endif while (style != NULL) { values = xmlHashLookup2(style->attributeSets, ncname, prefix); while (values != NULL) { if (values->attr != NULL) { xsltAttributeInternal(ctxt, node, values->attr, values->attr->psvi, 1); } values = values->next; } style = xsltNextImport(style); } } attrib = endattr; } }
/* * @return: the length of new string. */ int trim(char* str) { int begin, end; int i, j; for (i = 0; 0 != str[i] && IS_BLANK(str[i]);++i) {} begin = i; for (; 0 != str[i]; ++i) {} for (--i; i >= 0 && IS_BLANK(str[i]);--i) {} end = i + 1; for (i = 0, j = begin; j < end; ++i, ++j) str[i] = str[j]; str[i] = 0; return MAX(0, end - begin); }
char *SkipBlanks( const char *p ) { while( IS_BLANK( *p ) ) { ++p; } return( (char *)p ); }
/* removes the leading and trailing whitespaces */ static char *tag_clean (int argc, char *argv[]) { if (argc >= 1) { char *s = argv[0]; /* clean leading whitespaces */ while ((*s) && IS_BLANK (*s)) s++; /* process the text */ s = process_text (s); /* clean trailing whitespaces */ while ((*s) && IS_BLANK (s[strlen (s) - 1])) s[strlen (s) - 1] = 0; return s; } else return NULL; }
void xmlDebugDumpString(FILE *output, const CHAR *str) { int i; for (i = 0;i < 40;i++) if (str[i] == 0) return; else if (IS_BLANK(str[i])) fputc(' ', output); else fputc(str[i], output); fprintf(output, "..."); }
/** * Trim a string from blank char and copy it on to argument * @param from source * @param to destination * @param size buffer size * @param start saved starting blank chars (for replace in another place) * @param end saved ending blank chars (for replace in another place) */ static int trim(char *from, char *to, u_int size, char *start, char *end) { u_int len, istart, iend; NOPROFILER_IN(); if (size == 0 || size > COLOR_TOKEN_LEN || from == NULL || to == NULL) NOPROFILER_ROUT(-1); len = strlen(from); /* Speed check */ if (!IS_BLANK(from[0]) && !IS_BLANK(from[len])) NOPROFILER_ROUT(-1); /* Before */ for (istart = 0; istart < len && IS_BLANK(from[istart]); istart++); /* All blank, no modifications */ if (istart == len) NOPROFILER_ROUT(-1); /* After */ for (iend = len; iend > 0 && IS_BLANK(from[iend]); iend--); iend = len - iend; /* Copy the right char on to argument */ strncpy(to, from + istart, len - istart - iend); to[len - istart - iend] = 0x00; if (start) { strncpy(start, from, istart); start[istart] = 0x00; } if (end) { strncpy(end, from + len - iend, iend); end[iend] = 0x00; } NOPROFILER_ROUT(0); }
static int can_put(board_t board, color_t who, int x, int y) { int i, temp, checkx, checky; if (IS_BLANK(board[x][y])) for (i = 0; i < 8; ++i) { checkx = x + DIRX[i]; checky = y + DIRY[i]; temp = board[checkx][checky]; if (IS_BLANK(temp)) continue; if (temp != who) { while (board[checkx += DIRX[i]][checky += DIRY[i]] == temp); if (board[checkx][checky] == who) return 1; } } return 0; }
/** * @brief Read a new line, avoiding comments and void lines */ char *revm_getln() { char *buf; char *sav; NOPROFILER_IN(); do { buf = world.curjob->ws.io.input(); if (buf == ((char *) REVM_INPUT_VOID)) NOPROFILER_ROUT((char *) REVM_INPUT_VOID); if (buf == NULL) NOPROFILER_ROUT(NULL); if (!*buf) { XFREE(__FILE__, __FUNCTION__, __LINE__,buf); NOPROFILER_ROUT(NULL); } sav = buf; while (IS_BLANK(*sav)) sav++; if (!*sav || *sav == REVM_COMMENT_START) { revm_log(sav); revm_log("\n"); revm_buffer_free(buf); if (world.state.revm_mode == REVM_STATE_INTERACTIVE || world.state.revm_mode == REVM_STATE_EMBEDDED) NOPROFILER_ROUT((char*) REVM_INPUT_VOID); buf = NULL; if (*sav) continue; } if (world.state.revm_mode != REVM_STATE_SCRIPT) { revm_output_nolog("\n"); /* avoid looping with readline */ if (revm_is_enabled() && buf == NULL) NOPROFILER_ROUT((char *) REVM_INPUT_VOID); if (revm_is_enabled()) break; } } while (buf == NULL); NOPROFILER_ROUT(buf); }
// // PD_Tuple: C // // Implements PATH and SET_PATH for tuple. // Sets DS_TOP if found. Always returns 0. // REBINT PD_Tuple(REBPVS *pvs) { const REBVAL *setval; REBINT n; REBINT i; REBYTE *dat; REBINT len; dat = VAL_TUPLE(pvs->value); len = VAL_TUPLE_LEN(pvs->value); if (len < 3) { len = 3; } n = Get_Num_From_Arg(pvs->selector); if ((setval = pvs->opt_setval)) { if (n <= 0 || n > cast(REBINT, MAX_TUPLE)) fail (Error_Bad_Path_Select(pvs)); if (IS_INTEGER(setval) || IS_DECIMAL(setval)) i = Int32(setval); else if (IS_BLANK(setval)) { n--; CLEAR(dat + n, MAX_TUPLE - n); VAL_TUPLE_LEN(pvs->value) = n; return PE_OK; } else fail (Error_Bad_Path_Set(pvs)); if (i < 0) i = 0; else if (i > 255) i = 255; dat[n - 1] = i; if (n > len) VAL_TUPLE_LEN(pvs->value) = n; return PE_OK; } else { if (n > 0 && n <= len) { SET_INTEGER(pvs->store, dat[n - 1]); return PE_USE_STORE; } else return PE_NONE; } }
static int scanCommand(char *line, char **command, char **arg, char **arg2) { char *cur = line; while (IS_BLANK(cur)) cur++; if (*cur == 0) return (0); *command = cur; while ((*cur != 0) && (!IS_BLANK(cur))) cur++; if (*cur == 0) return (1); *cur = 0; cur++; while (IS_BLANK(cur)) cur++; if (*cur == 0) return (1); *arg = cur; while ((*cur != 0) && (!IS_BLANK(cur))) cur++; if (*cur == 0) return (2); *cur = 0; cur++; while (IS_BLANK(cur)) cur++; if (*cur == 0) return (2); *arg2 = cur; while ((*cur != 0) && (!IS_BLANK(cur))) cur++; if (*cur == 0) return (3); *cur = 0; cur++; while (IS_BLANK(cur)) cur++; if (*cur == 0) return (3); /* too many args */ return (-1); }
/* return parsed args number */ int utils_parse_upnp_task(char *buf, size_t size, char **argv) { char *p; //int i; int argc; argc = 0; //i = 0; p = buf; while((argc < RC_MAX_ARGS - 1) && (*p != '\0')) { /* skip blank char */ while(IS_BLANK(*p)) { *p = '\0'; p++; } if (*p == '\0') break; /* find argv[] start */ argv[argc] = p; argc++; p++; while(!IS_COLON(*p) && (*p != '\0')) p++; /* 0-terminated argv */ if (IS_COLON(*p)) { *p = '\0'; p++; } } /* check if all string has been parsed */ if (*p != '\0') { return -1; } /* final argv[] must be NULL */ argv[argc] = NULL; return (argc); }
// // Poke_Tuple_Immediate: C // // !!! Note: In the current implementation, tuples are immediate values. // So a POKE only changes the `value` in your hand. // void Poke_Tuple_Immediate( REBVAL *value, const REBVAL *picker, const REBVAL *poke ) { REBYTE *dat = VAL_TUPLE(value); REBINT len = VAL_TUPLE_LEN(value); if (len < 3) len = 3; REBINT n = Get_Num_From_Arg(picker); if (n <= 0 || n > cast(REBINT, MAX_TUPLE)) fail (Error_Out_Of_Range(picker)); REBINT i; if (IS_INTEGER(poke) || IS_DECIMAL(poke)) i = Int32(poke); else if (IS_BLANK(poke)) { n--; CLEAR(dat + n, MAX_TUPLE - n); VAL_TUPLE_LEN(value) = n; return; } else fail (poke); if (i < 0) i = 0; else if (i > 255) i = 255; dat[n - 1] = i; if (n > len) VAL_TUPLE_LEN(value) = n; }
static enum Status next_status(enum Status current_status, char ch) { enum Status next_status; if ('\n' == ch) return STATUS_PUNCTUATION; else if (STATUS_COMMENTS == current_status) return STATUS_COMMENTS; if (IS_LETTER(ch)) next_status = STATUS_LETTER; else if ('.' == ch) next_status = STATUS_PRAGMA; else if (IS_PUNCTUATION(ch)) next_status = STATUS_PUNCTUATION; else if (IS_NUMBER(ch)) next_status = STATUS_NUMBER; else if (IS_BLANK(ch)) next_status = STATUS_BLANK; else if (IS_COMMENTS(ch)) next_status = STATUS_COMMENTS; else next_status = STATUS_INVALID; return next_status; }
int tokenize(struct token_list* tk_list, char* file_buffer) { enum Status status; line_num; size_t token_begin, token_end; token_begin = 0, token_end = 0; status = STATUS_INVALID; str_toupper(file_buffer); /* * Careful: it seems an error to let "i <= len", * but we need one more execution to flush the last token into token list. */ size_t line_num = 1; for (size_t i = 0; ; ++i) { struct token_node* tok_node; switch (status) { case STATUS_LETTER: if (!IS_LETTER(file_buffer[i]) && !IS_DIGIT(file_buffer[i])) { token_end = i; tok_node = create_token(TOKEN_LABEL, file_buffer + token_begin, token_end - token_begin); tok_node->type = letter_type(tok_node->liter, tok_node->len); token_append(tk_list, tok_node); token_begin = i; status = next_status(status, file_buffer[i]); } break; case STATUS_PRAGMA: if (!IS_LETTER(file_buffer[i])) { int type; token_end = i; type = pragma_type(file_buffer + token_begin, token_end - token_begin); if (type < 0) { error("invalid pragma ad line %d\n", line_num); return -4; } tok_node = create_token(type, file_buffer + token_begin, token_end - token_begin); token_append(tk_list, tok_node); token_begin = i; status = next_status(status, file_buffer[i]); } break; case STATUS_PUNCTUATION: token_end = i; tok_node = create_token(file_buffer[token_begin], file_buffer + token_begin, token_end - token_begin); token_append(tk_list, tok_node); token_begin = i; status = next_status(status, file_buffer[i]); break; case STATUS_NUMBER: if (!IS_NUMBER(file_buffer[i])) { token_end = i; if (!check_number(file_buffer + token_begin, token_end - token_begin)) { error("invalid number format at line %d\n", line_num); return -2; } tok_node = create_token(TOKEN_NUMBER, file_buffer + token_begin, token_end - token_begin); tok_node->data = parse_number(tok_node->liter); token_append(tk_list, tok_node); token_begin = i; status = next_status(status, file_buffer[i]); } break; case STATUS_BLANK: if (!IS_BLANK(file_buffer[i])) { token_begin = i; status = next_status(status, file_buffer[i]); } break; case STATUS_COMMENTS: //once status is in comments, it will always be in comments if ('\n' == file_buffer[i]) { token_begin = i; status = next_status(status, file_buffer[i]); } break; case STATUS_INVALID: token_begin = i; status = next_status(status, file_buffer[i]); if (STATUS_INVALID == status && 0 != file_buffer[i]) { error("invalid format at line %d\n", line_num); return -3; } break; } if (0 == file_buffer[i]) break; else if ('\n' == file_buffer[i]) ++line_num; } return 0; }
static void purge_file( const char* file ) { struct stat statbuf; int fd; char* buf, *pbuf; int in_tag = 0, in_quote = 0; FILE* fo; fd = open( file, O_RDONLY ); if( fd == -1 ) return; if( fstat( fd, &statbuf) == -1 ) return; if( buf = (char*)malloc( statbuf.st_size + 1 ) ) { if( read( fd, buf, statbuf.st_size) == -1 ) { free( buf ); return; } buf[ statbuf.st_size ] = '\0'; } close( fd ); fo = fopen( file, "w" ); if( ! fo ) goto error; for( pbuf = buf; *pbuf; ++pbuf ) { if( in_tag > 0 ) { if( in_quote ) { if( *pbuf == '\"' ) in_quote = 0; } else { if( *pbuf == '\"' ) ++in_quote; if( ! in_quote && IS_BLANK(*pbuf) ) /* skip unnecessary blanks */ { do{ ++pbuf; }while( IS_BLANK( *pbuf ) ); if( *pbuf != '>' ) fputc( ' ', fo ); --pbuf; continue; } } if( *pbuf == '>' ) --in_tag; fputc( *pbuf, fo ); } else { if( *pbuf == '<' ) { if( 0 == strncmp( pbuf, "<!--", 4 ) ) /* skip comments */ { pbuf = strstr( pbuf, "-->" ); if( ! pbuf ) goto error; pbuf += 2; continue; } ++in_tag; fputc( '<', fo ); } else { char* tmp = pbuf; while( *tmp && IS_BLANK( *tmp ) && *tmp != '<' ) ++tmp; if( *tmp == '<' ) /* all cdata are blank characters */ pbuf = tmp - 1; else /* not blank, keep the cdata */ { if( tmp == pbuf ) fputc( *pbuf, fo ); else { fwrite( pbuf, 1, tmp - pbuf, fo ); pbuf = tmp - 1; } } } } } fclose( fo ); error: free( buf ); }
static int BuildList( const char *src, char *dst, bool test_abit, bool cond_copy, copy_entry **list ) { copy_entry *head; copy_entry *curr; copy_entry **owner; char *end; char path_buffer[_MAX_PATH2]; char full[_MAX_PATH]; char srcdir[_MAX_PATH]; char *drive; char *dir; char *fn; char *ext; DIR *directory; struct dirent *dent; #ifndef __UNIX__ unsigned attr; #else struct stat statsrc, statdst; char pattern[_MAX_PATH]; #endif int rc; char entry_src[_MAX_PATH]; char entry_dst[_MAX_PATH]; *list = NULL; strcpy( srcdir, src ); end = &dst[strlen( dst ) - 1]; while( IS_BLANK( end[0] ) ) { --end; } end[1] = '\0'; if( strpbrk( srcdir, WILD_METAS ) == NULL ) { /* no wild cards */ _fullpath( entry_src, srcdir, sizeof( entry_src ) ); switch( *end ) { case '\\': case '/': /* need to append source file name */ _splitpath2( srcdir, path_buffer, &drive, &dir, &fn, &ext ); _makepath( full, NULL, dst, fn, ext ); _fullpath( entry_dst, full, sizeof( entry_dst ) ); break; default: _fullpath( entry_dst, dst, sizeof( entry_dst ) ); break; } if( test_abit ) { if( ENTRY_NOT_CHANGED1() ) { return( 0 ); } } head = Alloc( sizeof( *head ) ); head->next = NULL; strcpy( head->src, entry_src ); strcpy( head->dst, entry_dst ); *list = head; return( 0 ); } #ifdef __UNIX__ _splitpath2( srcdir, path_buffer, &drive, &dir, &fn, &ext ); _makepath( srcdir, drive, dir, NULL, NULL ); _makepath( pattern, NULL, NULL, fn, ext ); if( srcdir[0] == '\0' ) { srcdir[0] = '.'; srcdir[1] = '\0'; } #endif head = NULL; rc = 1; directory = opendir( srcdir ); if( directory == NULL ) { if( !cond_copy ) { Log( false, "Can not open source directory '%s': %s\n", srcdir, strerror( errno ) ); } } else { #ifdef __UNIX__ char *srcdir_end = srcdir + strlen( srcdir ); #endif owner = &head; while( (dent = readdir( directory )) != NULL ) { #ifdef __UNIX__ struct stat buf; if( fnmatch( pattern, dent->d_name, FNM_PATHNAME | FNM_NOESCAPE ) == FNM_NOMATCH ) continue; strcpy( srcdir_end, dent->d_name ); stat( srcdir, &buf ); *srcdir_end = '\0'; if( S_ISDIR( buf.st_mode ) ) { continue; } #else if( dent->d_attr & (_A_SUBDIR | _A_VOLID) ) { continue; } #endif rc = 0; _splitpath2( srcdir, path_buffer, &drive, &dir, &fn, &ext ); _makepath( full, drive, dir, dent->d_name, NULL ); _fullpath( entry_src, full, sizeof( entry_src ) ); strcpy( full, dst ); switch( *end ) { case '\\': case '/': strcat( full, dent->d_name ); break; } _fullpath( entry_dst, full, sizeof( entry_dst ) ); if( test_abit ) { if( ENTRY_NOT_CHANGED2() ) { continue; } } curr = Alloc( sizeof( *curr ) ); curr->next = NULL; strcpy( curr->src, entry_src ); strcpy( curr->dst, entry_dst ); *owner = curr; owner = &curr->next; } closedir( directory ); } *list = head; if( cond_copy ) { return( 0 ); } return( rc ); }
static int mkdir_nested( const char *path ) /*****************************************/ { #ifdef __UNIX__ struct stat sb; #else unsigned attr; #endif char pathname[ FILENAME_MAX ]; char *p; char *end; p = pathname; strncpy( pathname, path, FILENAME_MAX ); end = pathname + strlen( pathname ); #ifndef __UNIX__ /* special case for drive letters */ if( p[0] != '\0' && p[1] == ':' ) { p += 2; } #endif /* skip initial path separator if present */ if( (p[0] == '/') || (p[0] == '\\') ) ++p; /* find the next path component */ while( p < end ) { while( (p < end) && (*p != '/') && (*p != '\\') ) ++p; *p = '\0'; /* check if pathname exists */ #ifdef __UNIX__ if( stat( pathname, &sb ) != 0 ) { #else if( _dos_getfileattr( pathname, &attr ) != 0 ) { #endif int rc; #ifdef __UNIX__ rc = mkdir( pathname, S_IRWXU | S_IRWXG | S_IRWXO ); #else rc = mkdir( pathname ); #endif if( rc != 0 ) { Log( false, "Can not create directory '%s': %s\n", pathname, strerror( errno ) ); return( -1 ); } } else { /* make sure it really is a directory */ #ifdef __UNIX__ if( !S_ISDIR( sb.st_mode ) ) { #else if( (attr & _A_SUBDIR) == 0 ) { #endif Log( false, "Can not create directory '%s': file with the same name already exists\n", pathname ); return( -1 ); } } /* put back the path separator - forward slash always works */ *p++ = '/'; } return( 0 ); } static int ProcOneCopy( const char *src, char *dst, bool cond_copy, char *copy_buff ) { FILE *sp; FILE *dp; size_t len; size_t out; struct stat srcbuf; struct utimbuf dstbuf; sp = fopen( src, "rb" ); if( sp == NULL ) { if( cond_copy ) { return( 0 ); // Quietly ignore missing source } else { Log( false, "Can not open '%s' for reading: %s\n", src, strerror( errno ) ); return( 1 ); } } dp = fopen( dst, "wb" ); if( dp == NULL ) { len = strlen( dst ); while( len-- > 0 ) { char c = dst[len]; if( c == '/' || c == '\\' ) { dst[len] = '\0'; mkdir_nested( dst ); dst[len] = c; dp = fopen( dst, "wb" ); break; } } if( dp == NULL ) { Log( false, "Can not open '%s' for writing: %s\n", dst, strerror( errno ) ); fclose( sp ); return( 1 ); } } Log( Quiet, "Copying '%s' to '%s'...\n", src, dst ); while( (len = fread( copy_buff, 1, COPY_BUFF_SIZE, sp )) != 0 ) { if( ferror( sp ) ) { Log( false, "Error reading '%s': %s\n", src, strerror( errno ) ); fclose( sp ); fclose( dp ); return( 1 ); } out = fwrite( copy_buff, 1, len, dp ); if( ferror( dp ) ) { Log( false, "Error writing '%s': %s\n", dst, strerror( errno ) ); fclose( sp ); fclose( dp ); return( 1 ); } if( out != len ) { Log( false, "Error writing '%s': Disk full\n", dst ); fclose( sp ); fclose( dp ); return( 1 ); } } fclose( sp ); fclose( dp ); /* make real copy, set the date back */ stat( src, &srcbuf ); dstbuf.actime = srcbuf.st_atime; dstbuf.modtime = srcbuf.st_mtime; utime( dst, &dstbuf ); #ifdef __UNIX__ /* copy permissions: mostly necessary for the "x" bit */ // some files is copied from the source tree with the read-only permission // for next run we need the write permission for the current user as minimum chmod( dst, srcbuf.st_mode | S_IWUSR ); #endif return( 0 ); } static int ProcCopy( char *cmd, bool test_abit, bool cond_copy, bool ignore_errors ) { char *dst; copy_entry *list; copy_entry *next; int res; for( dst = cmd; *dst != '\0'; ++dst ) { if( IS_BLANK( *dst ) ) { *dst++ = '\0'; dst = SkipBlanks( dst ); break; } } if( *dst == '\0' ) { Log( false, "Missing parameter\n" ); return( 1 ); } res = BuildList( cmd, dst, test_abit, cond_copy, &list ); if( res == 0 && list != NULL ) { char *copy_buff = Alloc( COPY_BUFF_SIZE ); for( ; list != NULL; list = next ) { next = list->next; if( res == 0 || ignore_errors ) { int rc; rc = ProcOneCopy( list->src, list->dst, cond_copy, copy_buff ); if( rc != 0 ) { res = rc; #ifndef __UNIX__ } else if( test_abit ) { list->next = IncludeStk->reset_abit; IncludeStk->reset_abit = list; continue; #endif } } free( list ); } free( copy_buff ); } return( res ); }
/** * xsltApplyAttributeSet: * @ctxt: the XSLT stylesheet * @node: the node in the source tree. * @inst: the attribute node "xsl:use-attribute-sets" * @attrSets: the list of QNames of the attribute-sets to be applied * * Apply the xsl:use-attribute-sets. * If @attrSets is NULL, then @inst will be used to exctract this * value. * If both, @attrSets and @inst, are NULL, then this will do nothing. */ void xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, const xmlChar *attrSets) { const xmlChar *ncname = NULL; const xmlChar *prefix = NULL; const xmlChar *curstr, *endstr; xsltAttrSetPtr set; xsltStylesheetPtr style; if (attrSets == NULL) { if (inst == NULL) return; else { /* * Extract the value from @inst. */ if (inst->type == XML_ATTRIBUTE_NODE) { if ( ((xmlAttrPtr) inst)->children != NULL) attrSets = ((xmlAttrPtr) inst)->children->content; } if (attrSets == NULL) { /* * TODO: Return an error? */ return; } } } /* * Parse/apply the list of QNames. */ curstr = attrSets; while (*curstr != 0) { while (IS_BLANK(*curstr)) curstr++; if (*curstr == 0) break; endstr = curstr; while ((*endstr != 0) && (!IS_BLANK(*endstr))) endstr++; curstr = xmlDictLookup(ctxt->dict, curstr, endstr - curstr); if (curstr) { xmlNsPtr ns; const xmlChar *nsUri = NULL; #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "apply attribute set %s\n", curstr); #endif if (xmlValidateQName(curstr, 0)) { xsltTransformError(ctxt, NULL, inst, "The name '%s' in use-attribute-sets is not a valid " "QName.\n", curstr); return; } ncname = xsltSplitQName(ctxt->dict, curstr, &prefix); if (prefix != NULL) { ns = xmlSearchNs(inst->doc, inst, prefix); if (ns == NULL) { xsltTransformError(ctxt, NULL, inst, "use-attribute-set : No namespace found for QName " "'%s:%s'\n", prefix, ncname); return; } nsUri = ns->href; } style = ctxt->style; #ifdef WITH_DEBUGGER if ((style != NULL) && (style->attributeSets != NULL) && (ctxt->debugStatus != XSLT_DEBUG_NONE)) { set = xmlHashLookup2(style->attributeSets, ncname, nsUri); if ((set != NULL) && (set->attrs != NULL) && (set->attrs->attr != NULL)) xslHandleDebugger(set->attrs->attr->parent, node, NULL, ctxt); } #endif /* * Lookup the referenced attribute-set. All attribute sets were * moved to the top stylesheet so there's no need to iterate * imported stylesheets */ set = xmlHashLookup2(style->attributeSets, ncname, nsUri); if (set != NULL) { xsltAttrElemPtr cur = set->attrs; while (cur != NULL) { if (cur->attr != NULL) { xsltAttribute(ctxt, node, cur->attr, cur->attr->psvi); } cur = cur->next; } } } curstr = endstr; } }
/* gets tokens from the string, the tokens can be separates by spaces (or tabs or new lines), and each one can enclosed by quotes or angular brackets, example: hi, 'good bye' <hi bye> "-\"good bye\"-" tok=hi, tok=good bye tok=<hi bye> tok=-"good bye"- */ char *own_strtok (char *s, char **holder) { char *d = *holder; char *r; if (s) d = s; else if (!d) return NULL; if ((*d != '\"') && (*d != '\'')) { for (r = d; !IS_BLANK (*d); d++) { if (*d == '<') { int c; for (c = 0;; d++) { if (*d == '<') c++; else if (*d == '>') { c--; if (c == 0) { break; } } } } else if (*d == 0) { d = NULL; break; } } } /* double quote */ else if (*d == '\"') { r = ++d; for (;;) { if (*d == 0) { d = NULL; break; } else if (*d == '\"') { break; } else if (*d == '\\') { memmove (d, d+1, strlen (d+1)); switch (*d) { case 'n': *d = '\n'; break; case 't': *d = '\t'; break; case 'r': *d = '\r'; break; } d++; } else d++; } } /* single quote */ else { r = ++d; for (;;) { if (*d == 0) { d = NULL; break; } else if (*d == '\'') { break; } else d++; } } if (d) { *d = 0; do { d++; } while ((*d) && IS_BLANK (*d)); if (!*d) d = NULL; } *holder = d; return r; }
/** * xsltApplyAttributeSet: * @ctxt: the XSLT stylesheet * @node: the node in the source tree. * @inst: the attribute node "xsl:use-attribute-sets" * @attrSets: the list of QNames of the attribute-sets to be applied * * Apply the xsl:use-attribute-sets. * If @attrSets is NULL, then @inst will be used to exctract this * value. * If both, @attrSets and @inst, are NULL, then this will do nothing. */ void xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst, const xmlChar *attrSets) { const xmlChar *ncname = NULL; const xmlChar *prefix = NULL; const xmlChar *curstr, *endstr; xsltAttrElemPtr attrs; xsltStylesheetPtr style; if (attrSets == NULL) { if (inst == NULL) return; else { /* * Extract the value from @inst. */ if (inst->type == XML_ATTRIBUTE_NODE) { if ( ((xmlAttrPtr) inst)->children != NULL) attrSets = ((xmlAttrPtr) inst)->children->content; } if (attrSets == NULL) { /* * TODO: Return an error? */ return; } } } /* * Parse/apply the list of QNames. */ curstr = attrSets; while (*curstr != 0) { while (IS_BLANK(*curstr)) curstr++; if (*curstr == 0) break; endstr = curstr; while ((*endstr != 0) && (!IS_BLANK(*endstr))) endstr++; curstr = xmlDictLookup(ctxt->dict, curstr, endstr - curstr); if (curstr) { /* * TODO: Validate the QName. */ #ifdef WITH_XSLT_DEBUG_curstrUTES xsltGenericDebug(xsltGenericDebugContext, "apply curstrute set %s\n", curstr); #endif ncname = xsltSplitQName(ctxt->dict, curstr, &prefix); style = ctxt->style; #ifdef WITH_DEBUGGER if ((style != NULL) && (style->attributeSets != NULL) && (ctxt->debugStatus != XSLT_DEBUG_NONE)) { attrs = xmlHashLookup2(style->attributeSets, ncname, prefix); if ((attrs != NULL) && (attrs->attr != NULL)) xslHandleDebugger(attrs->attr->parent, node, NULL, ctxt); } #endif /* * Lookup the referenced curstrute-set. */ while (style != NULL) { attrs = xmlHashLookup2(style->attributeSets, ncname, prefix); while (attrs != NULL) { if (attrs->attr != NULL) { xsltAttributeInternal(ctxt, node, attrs->attr, attrs->attr->psvi, 1); } attrs = attrs->next; } style = xsltNextImport(style); } } curstr = endstr; } }
void xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) { const xmlChar *ncname; const xmlChar *prefix; xmlChar *value; xmlNodePtr child; xsltAttrElemPtr attrItems; if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE)) return; value = xmlGetNsProp(cur, (const xmlChar *)"name", NULL); if ((value == NULL) || (*value == 0)) { xsltGenericError(xsltGenericErrorContext, "xsl:attribute-set : name is missing\n"); if (value) xmlFree(value); return; } ncname = xsltSplitQName(style->dict, value, &prefix); xmlFree(value); value = NULL; if (style->attributeSets == NULL) { #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "creating attribute set table\n"); #endif style->attributeSets = xmlHashCreate(10); } if (style->attributeSets == NULL) return; attrItems = xmlHashLookup2(style->attributeSets, ncname, prefix); /* * Parse the content. Only xsl:attribute elements are allowed. */ child = cur->children; while (child != NULL) { /* * Report invalid nodes. */ if ((child->type != XML_ELEMENT_NODE) || (child->ns == NULL) || (! IS_XSLT_ELEM(child))) { if (child->type == XML_ELEMENT_NODE) xsltTransformError(NULL, style, child, "xsl:attribute-set : unexpected child %s\n", child->name); else xsltTransformError(NULL, style, child, "xsl:attribute-set : child of unexpected type\n"); } else if (!IS_XSLT_NAME(child, "attribute")) { xsltTransformError(NULL, style, child, "xsl:attribute-set : unexpected child xsl:%s\n", child->name); } else { #ifdef XSLT_REFACTORED xsltAttrElemPtr nextAttr, curAttr; /* * Process xsl:attribute * --------------------- */ #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "add attribute to list %s\n", ncname); #endif /* * The following was taken over from * xsltAddAttrElemList(). */ if (attrItems == NULL) { attrItems = xsltNewAttrElem(child); } else { curAttr = attrItems; while (curAttr != NULL) { nextAttr = curAttr->next; if (curAttr->attr == child) { /* * URGENT TODO: Can somebody explain * why attrItems is set to curAttr * here? Is this somehow related to * avoidance of recursions? */ attrItems = curAttr; goto next_child; } if (curAttr->next == NULL) curAttr->next = xsltNewAttrElem(child); curAttr = nextAttr; } } /* * Parse the xsl:attribute and its content. */ xsltParseAnyXSLTElem(XSLT_CCTXT(style), child); #else #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "add attribute to list %s\n", ncname); #endif /* * OLD behaviour: */ attrItems = xsltAddAttrElemList(attrItems, child); #endif } #ifdef XSLT_REFACTORED next_child: #endif child = child->next; } /* * Process attribue "use-attribute-sets". */ /* TODO check recursion */ value = xmlGetNsProp(cur, (const xmlChar *)"use-attribute-sets", NULL); if (value != NULL) { const xmlChar *curval, *endval; curval = value; while (*curval != 0) { while (IS_BLANK(*curval)) curval++; if (*curval == 0) break; endval = curval; while ((*endval != 0) && (!IS_BLANK(*endval))) endval++; curval = xmlDictLookup(style->dict, curval, endval - curval); if (curval) { const xmlChar *ncname2 = NULL; const xmlChar *prefix2 = NULL; xsltAttrElemPtr refAttrItems; #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "xsl:attribute-set : %s adds use %s\n", ncname, curval); #endif ncname2 = xsltSplitQName(style->dict, curval, &prefix2); refAttrItems = xsltNewAttrElem(NULL); if (refAttrItems != NULL) { refAttrItems->set = ncname2; refAttrItems->ns = prefix2; attrItems = xsltMergeAttrElemList(style, attrItems, refAttrItems); xsltFreeAttrElem(refAttrItems); } } curval = endval; } xmlFree(value); value = NULL; } /* * Update the value */ /* * TODO: Why is this dummy entry needed.? */ if (attrItems == NULL) attrItems = xsltNewAttrElem(NULL); xmlHashUpdateEntry2(style->attributeSets, ncname, prefix, attrItems, NULL); #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "updated attribute list %s\n", ncname); #endif }
// // Do_Breakpoint_Throws: C // // A call to Do_Breakpoint_Throws does delegation to a hook in the host, which // (if registered) will generally start an interactive session for probing the // environment at the break. The RESUME native cooperates by being able to // give back a value (or give back code to run to produce a value) that the // call to breakpoint returns. // // RESUME has another feature, which is to be able to actually unwind and // simulate a return /AT a function *further up the stack*. (This may be // switched to a feature of a "step out" command at some point.) // REBOOL Do_Breakpoint_Throws( REBVAL *out, REBOOL interrupted, // Ctrl-C (as opposed to a BREAKPOINT) const REBVAL *default_value, REBOOL do_default ) { REBVAL *target = BLANK_VALUE; REBVAL temp; if (!PG_Breakpoint_Quitting_Hook) { // // Host did not register any breakpoint handler, so raise an error // about this as early as possible. // fail (Error(RE_HOST_NO_BREAKPOINT)); } // We call the breakpoint hook in a loop, in order to keep running if any // inadvertent FAILs or THROWs occur during the interactive session. // Only a conscious call of RESUME speaks the protocol to break the loop. // while (TRUE) { struct Reb_State state; REBCTX *error; push_trap: PUSH_TRAP(&error, &state); // The host may return a block of code to execute, but cannot // while evaluating do a THROW or a FAIL that causes an effective // "resumption". Halt is the exception, hence we PUSH_TRAP and // not PUSH_UNHALTABLE_TRAP. QUIT is also an exception, but a // desire to quit is indicated by the return value of the breakpoint // hook (which may or may not decide to request a quit based on the // QUIT command being run). // // The core doesn't want to get involved in presenting UI, so if // an error makes it here and wasn't trapped by the host first that // is a bug in the host. It should have done its own PUSH_TRAP. // if (error) { #if !defined(NDEBUG) REBVAL error_value; Val_Init_Error(&error_value, error); PROBE_MSG(&error_value, "Error not trapped during breakpoint:"); Panic_Array(CTX_VARLIST(error)); #endif // In release builds, if an error managed to leak out of the // host's breakpoint hook somehow...just re-push the trap state // and try it again. // goto push_trap; } // Call the host's breakpoint hook. // if (PG_Breakpoint_Quitting_Hook(&temp, interrupted)) { // // If a breakpoint hook returns TRUE that means it wants to quit. // The value should be the /WITH value (as in QUIT/WITH), so // not actually a "resume instruction" in this case. // assert(!THROWN(&temp)); *out = *NAT_VALUE(quit); CONVERT_NAME_TO_THROWN(out, &temp); return TRUE; // TRUE = threw } // If a breakpoint handler returns FALSE, then it should have passed // back a "resume instruction" triggered by a call like: // // resume/do [fail "This is how to fail from a breakpoint"] // // So now that the handler is done, we will allow any code handed back // to do whatever FAIL it likes vs. trapping that here in a loop. // DROP_TRAP_SAME_STACKLEVEL_AS_PUSH(&state); // Decode and process the "resume instruction" { REBFRM *frame; REBVAL *mode; REBVAL *payload; #if !defined(NDEBUG) REBOOL found = FALSE; #endif assert(IS_GROUP(&temp)); assert(VAL_LEN_HEAD(&temp) == RESUME_INST_MAX); // The instruction was built from raw material, non-relative // mode = KNOWN(VAL_ARRAY_AT_HEAD(&temp, RESUME_INST_MODE)); payload = KNOWN(VAL_ARRAY_AT_HEAD(&temp, RESUME_INST_PAYLOAD)); target = KNOWN(VAL_ARRAY_AT_HEAD(&temp, RESUME_INST_TARGET)); assert(IS_FRAME(target)); // // The first thing we need to do is determine if the target we // want to return to has another breakpoint sandbox blocking // us. If so, what we need to do is actually retransmit the // resume instruction so it can break that wall, vs. transform // it into an EXIT/FROM that would just get intercepted. // for (frame = FS_TOP; frame != NULL; frame = frame->prior) { if (NOT(Is_Any_Function_Frame(frame))) continue; if (Is_Function_Frame_Fulfilling(frame)) continue; if ( frame != FS_TOP && ( FUNC_DISPATCHER(frame->func) == &N_pause || FUNC_DISPATCHER(frame->func) == &N_breakpoint ) ) { // We hit a breakpoint (that wasn't this call to // breakpoint, at the current FS_TOP) before finding // the sought after target. Retransmit the resume // instruction so that level will get it instead. // *out = *NAT_VALUE(resume); CONVERT_NAME_TO_THROWN(out, &temp); return TRUE; // TRUE = thrown } // If the frame were the one we were looking for, it would be // reified (so it would have a context to match) // if (frame->varlist == NULL) continue; if (VAL_CONTEXT(target) == AS_CONTEXT(frame->varlist)) { // Found a match before hitting any breakpoints, so no // need to retransmit. // #if !defined(NDEBUG) found = TRUE; #endif break; } } // RESUME should not have been willing to use a target that // is not on the stack. // #if !defined(NDEBUG) assert(found); #endif if (IS_BLANK(mode)) { // // If the resume instruction had no /DO or /WITH of its own, // then it doesn't override whatever the breakpoint provided // as a default. (If neither the breakpoint nor the resume // provided a /DO or a /WITH, result will be void.) // goto return_default; // heeds `target` } assert(IS_LOGIC(mode)); if (VAL_LOGIC(mode)) { if (DO_VAL_ARRAY_AT_THROWS(&temp, payload)) { // // Throwing is not compatible with /AT currently. // if (!IS_BLANK(target)) fail (Error_No_Catch_For_Throw(&temp)); // Just act as if the BREAKPOINT call itself threw // *out = temp; return TRUE; // TRUE = thrown } // Ordinary evaluation result... } else temp = *payload; } // The resume instruction will be GC'd. // goto return_temp; } DEAD_END; return_default: if (do_default) { if (DO_VAL_ARRAY_AT_THROWS(&temp, default_value)) { // // If the code throws, we're no longer in the sandbox...so we // bubble it up. Note that breakpoint runs this code at its // level... so even if you request a higher target, any throws // will be processed as if they originated at the BREAKPOINT // frame. To do otherwise would require the EXIT/FROM protocol // to add support for DO-ing at the receiving point. // *out = temp; return TRUE; // TRUE = thrown } } else temp = *default_value; // generally void if no /WITH return_temp: // // If the target is a function, then we're looking to simulate a return // from something up the stack. This uses the same mechanic as // definitional returns--a throw named by the function or closure frame. // // !!! There is a weak spot in definitional returns for FUNCTION! that // they can only return to the most recent invocation; which is a weak // spot of FUNCTION! in general with stack relative variables. Also, // natives do not currently respond to definitional returns...though // they can do so just as well as FUNCTION! can. // Make_Thrown_Exit_Value(out, target, &temp, NULL); return TRUE; // TRUE = thrown }
std::string read_user_format_number(std::ifstream &ifs, UserFormatColumn<DATA_T> &ufc, std::string &line, bool &need_readline, encode_result &encres, char* argv[] = 0) { std::string ret, fm_buffer; DATA_T val = 0; char* c; ret.clear(); while (std::getline(ifs, line)) { encres.line_nr++; encres.line_in_blk++; c = const_cast<char*>(line.c_str()); fm_buffer.clear(); if (IS_COMMENT(line)) continue; /* end of FORMATs of a user block */ if (IS_BLANK(line)) { need_readline = false; break; } while (!IS_EOL(*c) && !IS_EOS(*c)) { /* Meeting the next FORMAT, which means this format is done */ if (IS_LETTER(*c)) { need_readline = false; break; } else if (IS_PLACEHOLD(*c)) { if (!TEMPLATE_MODE) throw E2promValueException("Placehold should be used in template file", to_string<int>(encres.line_nr), usage_allowed_user_format_type); E2promMsg("Reading parameter for user "+to_string<uint16_t>(ufc.uheader.ID)+ " @ line "+to_string<int>(encres.line_nr)); read_user_parameters(fm_buffer, ufc.uheader.ID, encres, argv); break; } else if (IS_DIGIT(*c) || IS_PERIOD(*c)) { fm_buffer += *c++; } else if (IS_SPACE(*c) || (IS_COMMENT_SIGN(*c))) { break; } else { throw E2promValueException( "Unexpected characters found for type", to_string<int>(encres.line_nr), usage_allowed_user_format_type ); } } /* end of read-char while-loop */ // if (TEMPLATE_MODE) // process_fm_buffer(fm_buffer, ufc.uheader.ID); if (!fm_buffer.empty()) { val = to_digits<DATA_T>(fm_buffer); ufc += val; } if (!IS_LETTER(*c) && !IS_BLANK(line)) { need_readline = true; } else { break; } } /* end of read-line while-loop */ // ret += strize_formats<DATA_T>(ufc); std::stringstream ss; // ss.width(decres.GLOBAL_ALIGNMENT); ss << ufc; return ss.str(); }
// // Serial_Actor: C // static REB_R Serial_Actor(REBFRM *frame_, REBCTX *port, REBSYM action) { REBREQ *req; // IO request REBVAL *spec; // port spec REBVAL *arg; // action argument value REBVAL *val; // e.g. port number value REBINT result; // IO result REBCNT refs; // refinement argument flags REBCNT len; // generic length REBSER *ser; // simplifier REBVAL *path; Validate_Port(port, action); *D_OUT = *D_ARG(1); // Validate PORT fields: spec = CTX_VAR(port, STD_PORT_SPEC); if (!IS_OBJECT(spec)) fail (Error(RE_INVALID_PORT)); path = Obj_Value(spec, STD_PORT_SPEC_HEAD_REF); if (!path) fail (Error(RE_INVALID_SPEC, spec)); //if (!IS_FILE(path)) fail (Error(RE_INVALID_SPEC, path)); req = cast(REBREQ*, Use_Port_State(port, RDI_SERIAL, sizeof(*req))); // Actions for an unopened serial port: if (!IS_OPEN(req)) { switch (action) { case SYM_OPEN: arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_PATH); if (! (IS_FILE(arg) || IS_STRING(arg) || IS_BINARY(arg))) fail (Error(RE_INVALID_PORT_ARG, arg)); req->special.serial.path = ALLOC_N(REBCHR, MAX_SERIAL_DEV_PATH); OS_STRNCPY( req->special.serial.path, // // !!! This is assuming VAL_DATA contains native chars. // Should it? (2 bytes on windows, 1 byte on linux/mac) // SER_AT(REBCHR, VAL_SERIES(arg), VAL_INDEX(arg)), MAX_SERIAL_DEV_PATH ); arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_SPEED); if (! IS_INTEGER(arg)) fail (Error(RE_INVALID_PORT_ARG, arg)); req->special.serial.baud = VAL_INT32(arg); //Secure_Port(SYM_SERIAL, ???, path, ser); arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_DATA_SIZE); if (!IS_INTEGER(arg) || VAL_INT64(arg) < 5 || VAL_INT64(arg) > 8 ) { fail (Error(RE_INVALID_PORT_ARG, arg)); } req->special.serial.data_bits = VAL_INT32(arg); arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_STOP_BITS); if (!IS_INTEGER(arg) || VAL_INT64(arg) < 1 || VAL_INT64(arg) > 2 ) { fail (Error(RE_INVALID_PORT_ARG, arg)); } req->special.serial.stop_bits = VAL_INT32(arg); arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_PARITY); if (IS_BLANK(arg)) { req->special.serial.parity = SERIAL_PARITY_NONE; } else { if (!IS_WORD(arg)) fail (Error(RE_INVALID_PORT_ARG, arg)); switch (VAL_WORD_SYM(arg)) { case SYM_ODD: req->special.serial.parity = SERIAL_PARITY_ODD; break; case SYM_EVEN: req->special.serial.parity = SERIAL_PARITY_EVEN; break; default: fail (Error(RE_INVALID_PORT_ARG, arg)); } } arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_FLOW_CONTROL); if (IS_BLANK(arg)) { req->special.serial.flow_control = SERIAL_FLOW_CONTROL_NONE; } else { if (!IS_WORD(arg)) fail (Error(RE_INVALID_PORT_ARG, arg)); switch (VAL_WORD_SYM(arg)) { case SYM_HARDWARE: req->special.serial.flow_control = SERIAL_FLOW_CONTROL_HARDWARE; break; case SYM_SOFTWARE: req->special.serial.flow_control = SERIAL_FLOW_CONTROL_SOFTWARE; break; default: fail (Error(RE_INVALID_PORT_ARG, arg)); } } if (OS_DO_DEVICE(req, RDC_OPEN)) fail (Error_On_Port(RE_CANNOT_OPEN, port, -12)); SET_OPEN(req); return R_OUT; case SYM_CLOSE: return R_OUT; case SYM_OPEN_Q: return R_FALSE; default: fail (Error_On_Port(RE_NOT_OPEN, port, -12)); } } // Actions for an open socket: switch (action) { case SYM_READ: refs = Find_Refines(frame_, ALL_READ_REFS); // Setup the read buffer (allocate a buffer if needed): arg = CTX_VAR(port, STD_PORT_DATA); if (!IS_STRING(arg) && !IS_BINARY(arg)) { Val_Init_Binary(arg, Make_Binary(32000)); } ser = VAL_SERIES(arg); req->length = SER_AVAIL(ser); // space available if (req->length < 32000/2) Extend_Series(ser, 32000); req->length = SER_AVAIL(ser); // This used STR_TAIL (obsolete, equivalent to BIN_TAIL) but was it // sure the series was byte sized? Added in a check. assert(BYTE_SIZE(ser)); req->common.data = BIN_TAIL(ser); // write at tail //if (SER_LEN(ser) == 0) req->actual = 0; // Actual for THIS read, not for total. #ifdef DEBUG_SERIAL printf("(max read length %d)", req->length); #endif result = OS_DO_DEVICE(req, RDC_READ); // recv can happen immediately if (result < 0) fail (Error_On_Port(RE_READ_ERROR, port, req->error)); #ifdef DEBUG_SERIAL for (len = 0; len < req->actual; len++) { if (len % 16 == 0) printf("\n"); printf("%02x ", req->common.data[len]); } printf("\n"); #endif *D_OUT = *arg; return R_OUT; case SYM_WRITE: refs = Find_Refines(frame_, ALL_WRITE_REFS); // Determine length. Clip /PART to size of string if needed. spec = D_ARG(2); len = VAL_LEN_AT(spec); if (refs & AM_WRITE_PART) { REBCNT n = Int32s(D_ARG(ARG_WRITE_LIMIT), 0); if (n <= len) len = n; } // Setup the write: *CTX_VAR(port, STD_PORT_DATA) = *spec; // keep it GC safe req->length = len; req->common.data = VAL_BIN_AT(spec); req->actual = 0; //Print("(write length %d)", len); result = OS_DO_DEVICE(req, RDC_WRITE); // send can happen immediately if (result < 0) fail (Error_On_Port(RE_WRITE_ERROR, port, req->error)); break; case SYM_UPDATE: // Update the port object after a READ or WRITE operation. // This is normally called by the WAKE-UP function. arg = CTX_VAR(port, STD_PORT_DATA); if (req->command == RDC_READ) { if (ANY_BINSTR(arg)) { SET_SERIES_LEN( VAL_SERIES(arg), VAL_LEN_HEAD(arg) + req->actual ); } } else if (req->command == RDC_WRITE) { SET_BLANK(arg); // Write is done. } return R_BLANK; case SYM_OPEN_Q: return R_TRUE; case SYM_CLOSE: if (IS_OPEN(req)) { OS_DO_DEVICE(req, RDC_CLOSE); SET_CLOSED(req); } break; default: fail (Error_Illegal_Action(REB_PORT, action)); } return R_OUT; }
// // Specialize_Action_Throws: C // // Create a new ACTION! value that uses the same implementation as another, // but just takes fewer arguments or refinements. It does this by storing a // heap-based "exemplar" FRAME! in the specialized action; this stores the // values to preload in the stack frame cells when it is invoked. // // The caller may provide information on the order in which refinements are // to be specialized, using the data stack. These refinements should be // pushed in the *reverse* order of their invocation, so append/dup/part // has /DUP at DS_TOP, and /PART under it. List stops at lowest_ordered_dsp. // bool Specialize_Action_Throws( REBVAL *out, REBVAL *specializee, REBSTR *opt_specializee_name, REBVAL *opt_def, // !!! REVIEW: binding modified directly (not copied) REBDSP lowest_ordered_dsp ){ assert(out != specializee); struct Reb_Binder binder; if (opt_def) INIT_BINDER(&binder); REBACT *unspecialized = VAL_ACTION(specializee); // This produces a context where partially specialized refinement slots // will be on the stack (including any we are adding "virtually", from // the current DSP down to the lowest_ordered_dsp). // REBCTX *exemplar = Make_Context_For_Action_Push_Partials( specializee, lowest_ordered_dsp, opt_def ? &binder : nullptr, CELL_MASK_NON_STACK ); Manage_Array(CTX_VARLIST(exemplar)); // destined to be managed, guarded if (opt_def) { // code that fills the frame...fully or partially // // Bind all the SET-WORD! in the body that match params in the frame // into the frame. This means `value: value` can very likely have // `value:` bound for assignments into the frame while `value` refers // to whatever value was in the context the specialization is running // in, but this is likely the more useful behavior. // // !!! This binds the actual arg data, not a copy of it--following // OBJECT!'s lead. However, ordinary functions make a copy of the // body they are passed before rebinding. Rethink. // See Bind_Values_Core() for explanations of how the binding works. Bind_Values_Inner_Loop( &binder, VAL_ARRAY_AT(opt_def), exemplar, FLAGIT_KIND(REB_SET_WORD), // types to bind (just set-word!) 0, // types to "add midstream" to binding as we go (nothing) BIND_DEEP ); // !!! Only one binder can be in effect, and we're calling arbitrary // code. Must clean up now vs. in loop we do at the end. :-( // RELVAL *key = CTX_KEYS_HEAD(exemplar); REBVAL *var = CTX_VARS_HEAD(exemplar); for (; NOT_END(key); ++key, ++var) { if (Is_Param_Unbindable(key)) continue; // !!! is this flag still relevant? if (Is_Param_Hidden(key)) { assert(GET_CELL_FLAG(var, ARG_MARKED_CHECKED)); continue; } if (GET_CELL_FLAG(var, ARG_MARKED_CHECKED)) continue; // may be refinement from stack, now specialized out Remove_Binder_Index(&binder, VAL_KEY_CANON(key)); } SHUTDOWN_BINDER(&binder); // Run block and ignore result (unless it is thrown) // PUSH_GC_GUARD(exemplar); bool threw = Do_Any_Array_At_Throws(out, opt_def, SPECIFIED); DROP_GC_GUARD(exemplar); if (threw) { DS_DROP_TO(lowest_ordered_dsp); return true; } } REBVAL *rootkey = CTX_ROOTKEY(exemplar); // Build up the paramlist for the specialized function on the stack. // The same walk used for that is used to link and process REB_X_PARTIAL // arguments for whether they become fully specialized or not. REBDSP dsp_paramlist = DSP; Move_Value(DS_PUSH(), ACT_ARCHETYPE(unspecialized)); REBVAL *param = rootkey + 1; REBVAL *arg = CTX_VARS_HEAD(exemplar); REBDSP ordered_dsp = lowest_ordered_dsp; for (; NOT_END(param); ++param, ++arg) { if (TYPE_CHECK(param, REB_TS_REFINEMENT)) { if (IS_NULLED(arg)) { // // A refinement that is nulled is a candidate for usage at the // callsite. Hence it must be pre-empted by our ordered // overrides. -but- the overrides only apply if their slot // wasn't filled by the user code. Yet these values we are // putting in disrupt that detection (!), so use another // flag (PUSH_PARTIAL) to reflect this state. // while (ordered_dsp != dsp_paramlist) { ++ordered_dsp; REBVAL *ordered = DS_AT(ordered_dsp); if (not IS_WORD_BOUND(ordered)) // specialize 'print/asdf fail (Error_Bad_Refine_Raw(ordered)); REBVAL *slot = CTX_VAR(exemplar, VAL_WORD_INDEX(ordered)); if ( IS_NULLED(slot) or GET_CELL_FLAG(slot, PUSH_PARTIAL) ){ // It's still partial, so set up the pre-empt. // Init_Any_Word_Bound( arg, REB_SYM_WORD, VAL_STORED_CANON(ordered), exemplar, VAL_WORD_INDEX(ordered) ); SET_CELL_FLAG(arg, PUSH_PARTIAL); goto unspecialized_arg; } // Otherwise the user filled it in, so skip to next... } goto unspecialized_arg; // ran out...no pre-empt needed } if (GET_CELL_FLAG(arg, ARG_MARKED_CHECKED)) { assert( IS_BLANK(arg) or ( IS_REFINEMENT(arg) and ( VAL_REFINEMENT_SPELLING(arg) == VAL_PARAM_SPELLING(param) ) ) ); } else Typecheck_Refinement_And_Canonize(param, arg); goto specialized_arg_no_typecheck; } switch (VAL_PARAM_CLASS(param)) { case REB_P_RETURN: case REB_P_LOCAL: assert(IS_NULLED(arg)); // no bindings, you can't set these goto unspecialized_arg; default: break; } // It's an argument, either a normal one or a refinement arg. if (not IS_NULLED(arg)) goto specialized_arg_with_check; unspecialized_arg: assert(NOT_CELL_FLAG(arg, ARG_MARKED_CHECKED)); assert( IS_NULLED(arg) or (IS_SYM_WORD(arg) and TYPE_CHECK(param, REB_TS_REFINEMENT)) ); Move_Value(DS_PUSH(), param); continue; specialized_arg_with_check: // !!! If argument was previously specialized, should have been type // checked already... don't type check again (?) // if (Is_Param_Variadic(param)) fail ("Cannot currently SPECIALIZE variadic arguments."); if (TYPE_CHECK(param, REB_TS_DEQUOTE_REQUOTE) and IS_QUOTED(arg)) { // // Have to leave the quotes on, but still want to type check. if (not TYPE_CHECK(param, CELL_KIND(VAL_UNESCAPED(arg)))) fail (arg); // !!! merge w/Error_Invalid_Arg() } else if (not TYPE_CHECK(param, VAL_TYPE(arg))) fail (arg); // !!! merge w/Error_Invalid_Arg() SET_CELL_FLAG(arg, ARG_MARKED_CHECKED); specialized_arg_no_typecheck: // Specialized-out arguments must still be in the parameter list, // for enumeration in the evaluator to line up with the frame values // of the underlying function. assert(GET_CELL_FLAG(arg, ARG_MARKED_CHECKED)); Move_Value(DS_PUSH(), param); TYPE_SET(DS_TOP, REB_TS_HIDDEN); continue; } REBARR *paramlist = Pop_Stack_Values_Core( dsp_paramlist, SERIES_MASK_PARAMLIST | (SER(unspecialized)->header.bits & PARAMLIST_MASK_INHERIT) ); Manage_Array(paramlist); RELVAL *rootparam = ARR_HEAD(paramlist); VAL_ACT_PARAMLIST_NODE(rootparam) = NOD(paramlist); // Everything should have balanced out for a valid specialization // while (ordered_dsp != DSP) { ++ordered_dsp; REBVAL *ordered = DS_AT(ordered_dsp); if (not IS_WORD_BOUND(ordered)) // specialize 'print/asdf fail (Error_Bad_Refine_Raw(ordered)); REBVAL *slot = CTX_VAR(exemplar, VAL_WORD_INDEX(ordered)); assert(not IS_NULLED(slot) and NOT_CELL_FLAG(slot, PUSH_PARTIAL)); UNUSED(slot); } DS_DROP_TO(lowest_ordered_dsp); // See %sysobj.r for `specialized-meta:` object template REBVAL *example = Get_System(SYS_STANDARD, STD_SPECIALIZED_META); REBCTX *meta = Copy_Context_Shallow_Managed(VAL_CONTEXT(example)); Init_Nulled(CTX_VAR(meta, STD_SPECIALIZED_META_DESCRIPTION)); // default Move_Value( CTX_VAR(meta, STD_SPECIALIZED_META_SPECIALIZEE), specializee ); if (not opt_specializee_name) Init_Nulled(CTX_VAR(meta, STD_SPECIALIZED_META_SPECIALIZEE_NAME)); else Init_Word( CTX_VAR(meta, STD_SPECIALIZED_META_SPECIALIZEE_NAME), opt_specializee_name ); MISC_META_NODE(paramlist) = NOD(meta); REBACT *specialized = Make_Action( paramlist, &Specializer_Dispatcher, ACT_UNDERLYING(unspecialized), // same underlying action as this exemplar, // also provide a context of specialization values 1 // details array capacity ); assert(CTX_KEYLIST(exemplar) == ACT_PARAMLIST(unspecialized)); assert( GET_ACTION_FLAG(specialized, IS_INVISIBLE) == GET_ACTION_FLAG(unspecialized, IS_INVISIBLE) ); // The "body" is the FRAME! value of the specialization. It takes on the // binding we want to use (which we can't put in the exemplar archetype, // that binding has to be UNBOUND). It also remembers the original // action in the phase, so Specializer_Dispatcher() knows what to call. // RELVAL *body = ARR_HEAD(ACT_DETAILS(specialized)); Move_Value(body, CTX_ARCHETYPE(exemplar)); INIT_BINDING(body, VAL_BINDING(specializee)); INIT_VAL_CONTEXT_PHASE(body, unspecialized); Init_Action_Unbound(out, specialized); return false; // code block did not throw }
void xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) { const xmlChar *ncname; const xmlChar *prefix; const xmlChar *nsUri = NULL; xmlChar *value; xmlNodePtr child; xsltAttrSetPtr set; if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE)) return; value = xmlGetNsProp(cur, (const xmlChar *)"name", NULL); if ((value == NULL) || (*value == 0)) { xsltGenericError(xsltGenericErrorContext, "xsl:attribute-set : name is missing\n"); if (value) xmlFree(value); return; } if (xmlValidateQName(value, 0)) { xsltTransformError(NULL, style, cur, "xsl:attribute-set : The name '%s' is not a valid QName.\n", value); style->errors++; xmlFree(value); return; } ncname = xsltSplitQName(style->dict, value, &prefix); xmlFree(value); value = NULL; if (prefix != NULL) { xmlNsPtr ns = xmlSearchNs(style->doc, cur, prefix); if (ns == NULL) { xsltTransformError(NULL, style, cur, "xsl:attribute-set : No namespace found for QName '%s:%s'\n", prefix, ncname); style->errors++; return; } nsUri = ns->href; } if (style->attributeSets == NULL) { #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "creating attribute set table\n"); #endif style->attributeSets = xmlHashCreate(10); } if (style->attributeSets == NULL) return; set = xmlHashLookup2(style->attributeSets, ncname, nsUri); if (set == NULL) { set = xsltNewAttrSet(); if (set == NULL) return; xmlHashAddEntry2(style->attributeSets, ncname, nsUri, set); } /* * Parse the content. Only xsl:attribute elements are allowed. */ child = cur->children; while (child != NULL) { /* * Report invalid nodes. */ if ((child->type != XML_ELEMENT_NODE) || (child->ns == NULL) || (! IS_XSLT_ELEM(child))) { if (child->type == XML_ELEMENT_NODE) xsltTransformError(NULL, style, child, "xsl:attribute-set : unexpected child %s\n", child->name); else xsltTransformError(NULL, style, child, "xsl:attribute-set : child of unexpected type\n"); } else if (!IS_XSLT_NAME(child, "attribute")) { xsltTransformError(NULL, style, child, "xsl:attribute-set : unexpected child xsl:%s\n", child->name); } else { #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "add attribute to list %s\n", ncname); #endif if (child->psvi == NULL) { xsltTransformError(NULL, style, child, "xsl:attribute-set : internal error, attribute %s not " "compiled\n", child->name); } else { set->attrs = xsltAddAttrElemList(set->attrs, child); } } child = child->next; } /* * Process attribute "use-attribute-sets". */ value = xmlGetNsProp(cur, BAD_CAST "use-attribute-sets", NULL); if (value != NULL) { const xmlChar *curval, *endval; curval = value; while (*curval != 0) { while (IS_BLANK(*curval)) curval++; if (*curval == 0) break; endval = curval; while ((*endval != 0) && (!IS_BLANK(*endval))) endval++; curval = xmlDictLookup(style->dict, curval, endval - curval); if (curval) { const xmlChar *ncname2 = NULL; const xmlChar *prefix2 = NULL; const xmlChar *nsUri2 = NULL; #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "xsl:attribute-set : %s adds use %s\n", ncname, curval); #endif if (xmlValidateQName(curval, 0)) { xsltTransformError(NULL, style, cur, "xsl:attribute-set : The name '%s' in " "use-attribute-sets is not a valid QName.\n", curval); style->errors++; xmlFree(value); return; } ncname2 = xsltSplitQName(style->dict, curval, &prefix2); if (prefix2 != NULL) { xmlNsPtr ns2 = xmlSearchNs(style->doc, cur, prefix2); if (ns2 == NULL) { xsltTransformError(NULL, style, cur, "xsl:attribute-set : No namespace found for QName " "'%s:%s' in use-attribute-sets\n", prefix2, ncname2); style->errors++; xmlFree(value); return; } nsUri2 = ns2->href; } set->useAttrSets = xsltAddUseAttrSetList(set->useAttrSets, ncname2, nsUri2); } curval = endval; } xmlFree(value); value = NULL; } #ifdef WITH_XSLT_DEBUG_ATTRIBUTES xsltGenericDebug(xsltGenericDebugContext, "updated attribute list %s\n", ncname); #endif }
static ParamList *get_ps_params(int ifd, BufList **ps_data) { char read_buf[DATA_BUF_SIZE]; ParamList *p_list = NULL; int begin_page = 0; int read_bytes; int acro_util = 0; BufList *bl = NULL; while( (read_bytes = read_line(ifd, read_buf, DATA_BUF_SIZE - 1)) > 0 ) { int dev_len = strlen(PAGE_DEV_BEGIN); int end_len = strlen(PAGE_DEV_END); // For Acrobat Reader { if( is_acro_util(read_buf, read_bytes) ){ acro_util = 1; } else if( acro_util && is_end_resource(read_buf, read_bytes) ){ acro_util = 0; } if( acro_util ){ int line_bytes=0; while( line_bytes+29 < read_bytes ){ if(!strncmp(&read_buf[line_bytes], " ct_BadResourceImplementation?", 30)){ strcpy(&read_buf[line_bytes], " false"); line_bytes+=6; strcpy(&read_buf[line_bytes], &read_buf[line_bytes+24]); read_bytes-=24; } else{ line_bytes++; } } } } // Retain the PS data in the buffer list. bl = buflist_new(read_buf, read_bytes); if( *ps_data == NULL ) *ps_data = bl; else buflist_add_tail(*ps_data, bl); if( read_bytes > 0 ) { if( read_buf[read_bytes - 1] == '\n' ) read_buf[read_bytes - 1] = '\0'; else read_buf[read_bytes] = '\0'; } else { read_buf[0] = '\0'; } // Parse the printing option per line. if( strncmp(read_buf, "%%BeginFeature:", 15) == 0 ) { char key_buf[MAX_KEY_LEN + 1]; char value_buf[MAX_VALUE_LEN + 1]; int key_len = 0; int value_len = 0; char *p_code; p_code = read_buf + 15; while( *p_code != '\0' ) { if( *p_code++ == '*' ) break; } while( *p_code != '\0' ) { if( IS_BLANK(*p_code) || key_len >= MAX_KEY_LEN ) break; key_buf[key_len++] = *p_code++; } while( *p_code != '\0' ) { if( !IS_BLANK(*p_code) ) break; *p_code++; } while( *p_code != '\0' ) { if( IS_BLANK(*p_code) || value_len >= MAX_VALUE_LEN ) break; value_buf[value_len++] = *p_code++; } if( key_len > 0 && value_len > 0 ) { key_buf[key_len] = '\0'; value_buf[value_len] = '\0'; param_list_add_multi(&p_list, key_buf, value_buf, value_len + 1, 1); } } else if( !begin_page && strncmp(read_buf, "%%Page:", 7) == 0 ) { begin_page = 1; } else if( begin_page ) { if( strncmp(read_buf, "%%EndPageSetup", 14) == 0 ) break; else if( strncmp(read_buf, "gsave", 5) == 0 ) break; else if( read_buf[0] >= '0' && read_buf[0] <= '9' ) break; } // For InkJet <</***(...)>>setpagedevice. else if(strncmp(read_buf + (read_bytes - 1 - end_len), PAGE_DEV_END, end_len) == 0) { char key_buf[MAX_KEY_LEN + 1]; char value_buf[MAX_KEY_LEN + 1]; char *p_code; int pos = 0; p_code = read_buf + dev_len; while( !IS_RETURN(p_code[pos]) ) { int key_pos = 0; int val_pos = 0; while( p_code[pos] != '/' && !IS_RETURN(p_code[pos]) ) pos++; if( p_code[pos] == '/' ) pos++; else continue; while( isalnum(p_code[pos]) && key_pos < 255 ) key_buf[key_pos++] = p_code[pos++]; key_buf[key_pos++] = 0; if( p_code[pos] == '(' ) { pos++; while( p_code[pos] != ')' && !IS_BLANK(p_code[pos]) && !IS_RETURN(p_code[pos]) && val_pos < 255 ) value_buf[val_pos++] = p_code[pos++]; value_buf[val_pos++] = 0; if( p_code[pos] == ')' ) pos++; else continue; if( !strcmp(key_buf, "CNPageSizeName") ) strncpy(key_buf, "PageSize", MAX_KEY_LEN); } else continue; param_list_add_multi(&p_list, key_buf, value_buf, val_pos+1, 1); } } } while( (read_bytes = read_line(-1, read_buf, DATA_BUF_SIZE - 1)) > 0 ) { BufList *bl = buflist_new(read_buf, read_bytes); if( *ps_data == NULL ) *ps_data = bl; else buflist_add_tail(*ps_data, bl); if( read_bytes > 0 ) { if( read_buf[read_bytes - 1] == '\n' ) read_buf[read_bytes - 1] = '\0'; else read_buf[read_bytes] = '\0'; } else { read_buf[0] = '\0'; } } return p_list; }
/* process the file `in' and output the result to `out' file */ void process_file (STREAM *in, STREAM *out) { STREAM *old_i_stream = _i_stream; STREAM *old_o_stream = _o_stream; char *old_current_line = current_line; char *old_current_col = current_col; char *s, buf[MAX_BYTES]; _i_stream = in; _o_stream = out; old_current_line = current_line; old_current_col = current_col; new_token (TOK_SPACE); update_state (); while (stgets (buf, MAX_BYTES, in)) { for (s = buf; *s; s++) { /* tag beginning */ if ((*s == '<') && (s[1] == '!')) { int c, i, used = FALSE; int restore = TRUE; char *tag = s + 1; /* jump the comment? */ if ((s[2] == '-') && (s[3] == '-')) { if (!kill_comments) stputs ("<!", out); s += 2; for (;;) { if (strncmp (s, "-->", 3) == 0) { if (!kill_comments) stputs ("-->", out); s += 2; break; } else if (*s == 0) { if (!stgets (buf, MAX_BYTES, in)) break; s = buf; } else { if (!kill_comments) stputc (*s, out); s++; } } continue; } /* jump nested tags */ for (c = 0;; s++) { if (*s == '<') c++; else if (*s == '>') { c--; if (c == 0) break; } else if (*s == 0) { if (!stgets (buf + strlen (buf), MAX_BYTES - strlen (buf), in)) break; s--; } } c = *s; *s = 0; log_printf (2, "tag found: \"%s\"\n", tag + 1); /* check for <!arg...> */ if (strncmp (tag + 1, "arg", 3) == 0) { if (can_attach) { /* <!args...> */ if (tag[4] == 's') { char temp[32]; sprintf (temp, "%d", nargs); stputs (temp, out); } /* <!arg[1-9][0-9]*...> */ else { int arg = strtol (tag + 4, NULL, 10); if ((arg > 0) && (arg <= nargs) && (args[arg - 1])) stputs (args[arg - 1], out); } } used = TRUE; } /* check for built-ins functions <!...> */ if (!used) { for (i = 0; i < ntags; i++) { if (strncmp (tag + 1, tags[i].name, strlen (tags[i].name)) == 0) { int x = tag[1 + strlen (tags[i].name)]; if (IS_BLANK (x) || (!x)) { char *tok, *argv[MAX_ARGS]; char *replacement; char *holder = NULL; int argc = 0; for (tok = own_strtok (tag + 2, &holder), tok = own_strtok (NULL, &holder); tok; tok = own_strtok (NULL, &holder)) argv[argc++] = tok; if ((tags[i].if_tag) || (can_attach)) { current_line = buf; current_col = s + 1; /* call the tag procedure */ replacement = (*tags[i].proc) (argc, argv); if (s != current_col - 1) { s = current_col - 1; restore = FALSE; } /* text to replace */ if (replacement) { stputs (replacement, out); free (replacement); } log_printf (2, "tag \"%s\" was processed\n", tags[i].name); } else log_printf (2, "tag \"%s\" wasn't processed\n", tags[i].name); used = TRUE; break; } } } } /* check for user functional macros <!...> */ if (!used && can_attach) { char *replacement = function_macro (macros_space[nmacros_space-1], tag); if (replacement) { stputs (replacement, out); free (replacement); used = TRUE; } } /* well, this is an unknown tag */ if (!used) { char *ptag = process_text (tag); if (can_attach) stputc ('<', out); if (ptag) { if (can_attach) stputs (ptag, out); free (ptag); } if (can_attach) stputc ('>', out); } if (restore) { if (!c) s--; else *s = c; } } /* put a character in the output file */ else if (can_attach) { char *replacement = NULL; int c, length = 0; /* check for macros */ for (c = 0; c < nmacros_space; c++) { replacement = replace_by_macro (macros_space[c], s, &length); if (replacement) break; } /* just put the character */ if (!replacement) { stputc (*s, out); } /* put the value of the macro */ else { stputs (replacement, out); s += length - 1; free (replacement); } } } } delete_token (); update_state (); _i_stream = old_i_stream; _o_stream = old_o_stream; current_line = old_current_line; current_col = old_current_col; }