synctex_parser.c.svn-base

来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 1,720 行 · 第 1/5 页

SVN-BASE
1,720
字号
		if(0 == available) {			return SYNCTEX_STATUS_EOF;		}	}	/*  Now we are sure that there is at least one available character, either because	 *  SYNCTEX_CUR was already < SYNCTEX_END, or because the buffer has been properly filled. */	/*  end will point to the next unparsed '\n' character in the file, when mapped to the buffer. */	end = SYNCTEX_CUR;	*  value_ref = NULL;/*  Initialize, it will be realloc'ed */	/*  We scan all the characters up to the next '\n' */next_character:	if(end<SYNCTEX_END) {		if(*end == '\n') {			/*  OK, we found where to stop */			len = end - SYNCTEX_CUR;			if(current_size>UINT_MAX-len-1) {				/*  But we have reached the limit: we do not have current_size+len+1>UINT_MAX.				 *  We return the missing amount of memory.				 *  This will never occur in practice. */				return UINT_MAX-len-1 - current_size;			}			new_size = current_size+len;			/*  We have current_size+len+1<=UINT_MAX			 *  or equivalently new_size<UINT_MAX,			 *  where we have assumed that len<UINT_MAX */			if((*  value_ref = realloc(*  value_ref,new_size+1)) != NULL) {				if(memcpy((*value_ref)+current_size,SYNCTEX_CUR,len)) {					(*  value_ref)[new_size]='\0'; /*  Terminate the string */					SYNCTEX_CUR += len;/*  Advance to the terminating '\n' */					return SYNCTEX_STATUS_OK;				}				free(*  value_ref);				*  value_ref = NULL;				_synctex_error("!  could not copy memory (1).");				return SYNCTEX_STATUS_ERROR;			}			_synctex_error("!  could not allocate memory (1).");			return SYNCTEX_STATUS_ERROR;		} else {			++end;			goto next_character;		}	} else {		/*  end == SYNCTEX_END */		len = SYNCTEX_END - SYNCTEX_CUR;		if(current_size>UINT_MAX-len-1) {			/*  We have reached the limit. */			_synctex_error("!  limit reached (missing %i).",current_size-(UINT_MAX-len-1));			return SYNCTEX_STATUS_ERROR;		}		new_size = current_size+len;		if((*  value_ref = realloc(*  value_ref,new_size+1)) != NULL) {			if(memcpy((*value_ref)+current_size,SYNCTEX_CUR,len)) {				(*  value_ref)[new_size]='\0'; /*  Terminate the string */				SYNCTEX_CUR = SYNCTEX_END;/*  Advance the cursor to the end of the bufer */				return SYNCTEX_STATUS_OK;			}			free(*  value_ref);			*  value_ref = NULL;			_synctex_error("!  could not copy memory (2).");			return SYNCTEX_STATUS_ERROR;		}		/*  Huge memory problem */		_synctex_error("!  could not allocate memory (2).");		return SYNCTEX_STATUS_ERROR;	}}/*  Used when parsing the synctex file. *  Read an Input record. */synctex_status_t _synctex_scan_input(synctex_scanner_t scanner) {	synctex_status_t status = 0;	size_t available = 0;	synctex_node_t input = NULL;	if(NULL == scanner) {		return SYNCTEX_STATUS_BAD_ARGUMENT;	}	status = _synctex_match_string(scanner,"Input:");	if(status<SYNCTEX_STATUS_OK) {		return status;	}	/*  Create a node */	input = _synctex_new_input(scanner);	if(NULL == input) {		_synctex_error("!  could not create an input node.");		return SYNCTEX_STATUS_ERROR;	}	/*  Decode the synctag  */	status = _synctex_decode_int(scanner,&(SYNCTEX_TAG(input)));	if(status<SYNCTEX_STATUS_OK) {		_synctex_error("!  bad format of input node.");		SYNCTEX_FREE(input);		return status;	}	/*  The next character is a field separator, we expect one character in the buffer. */	available = 1;	status = _synctex_buffer_get_available_size(scanner, &available);	if(status<=SYNCTEX_STATUS_ERROR) {		return status;	}	if(0 == available) {		return SYNCTEX_STATUS_EOF;	}	/*  We can now safely advance to the next character, stepping over the field separator. */	++SYNCTEX_CUR;	--available;	/*  Then we scan the file name */	status = _synctex_decode_string(scanner,&(SYNCTEX_NAME(input)));	if(status<SYNCTEX_STATUS_OK) {		SYNCTEX_FREE(input);		return status;	}	/*  Prepend this input node to the input linked list of the scanner */	SYNCTEX_SET_SIBLING(input,scanner->input);	scanner->input = input;	return _synctex_next_line(scanner);/*  read the line termination character, if any */	/*  Now, set up the path */}typedef synctex_status_t (*synctex_decoder_t)(synctex_scanner_t,void *);synctex_status_t _synctex_scan_named(synctex_scanner_t scanner,char *  name,void *  value_ref,synctex_decoder_t decoder);/*  Used when parsing the synctex file. *  Read one of the settings. *  On normal completion, returns SYNCTEX_STATUS_OK. *  On error, returns SYNCTEX_STATUS_ERROR. *  Both arguments must not be NULL. *  On return, the scanner points to the next character after the decoded object whatever it is. *  It is the responsibility of the caller to prepare the scanner for the next line. */synctex_status_t _synctex_scan_named(synctex_scanner_t scanner,char *  name,void *  value_ref,synctex_decoder_t decoder) {	synctex_status_t status = 0;	if(NULL == scanner || NULL == name || NULL == value_ref || NULL == decoder) {		return SYNCTEX_STATUS_BAD_ARGUMENT;	}not_found:	status = _synctex_match_string(scanner,name);	if(status<SYNCTEX_STATUS_NOT_OK) {		return status;	} else if(status == SYNCTEX_STATUS_NOT_OK) {		status = _synctex_next_line(scanner);		if(status<SYNCTEX_STATUS_OK) {			return status;		}		goto not_found;	}	/*  A line is found, scan the value */	return (*decoder)(scanner,value_ref);}/*  Used when parsing the synctex file. *  Read the preamble. */synctex_status_t _synctex_scan_preamble(synctex_scanner_t scanner) {	synctex_status_t status = 0;	if(NULL == scanner) {		return SYNCTEX_STATUS_BAD_ARGUMENT;	}	status = _synctex_scan_named(scanner,"SyncTeX Version:",&(scanner->version),(synctex_decoder_t)&_synctex_decode_int);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_next_line(scanner);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	/*  Read all the input records */	do {		status = _synctex_scan_input(scanner);		if(status<SYNCTEX_STATUS_NOT_OK) {			return status;		}	} while(status == SYNCTEX_STATUS_OK);	/*  the loop exits when status == SYNCTEX_STATUS_NOT_OK */	/*  Now read all the required settings. */	status = _synctex_scan_named(scanner,"Output:",&(scanner->output_fmt),(synctex_decoder_t)&_synctex_decode_string);	if(status<SYNCTEX_STATUS_NOT_OK) {		return status;	}	status = _synctex_next_line(scanner);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_scan_named(scanner,"Magnification:",&(scanner->pre_magnification),(synctex_decoder_t)&_synctex_decode_int);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_next_line(scanner);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_scan_named(scanner,"Unit:",&(scanner->pre_unit),(synctex_decoder_t)&_synctex_decode_int);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_next_line(scanner);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_scan_named(scanner,"X Offset:",&(scanner->pre_x_offset),(synctex_decoder_t)&_synctex_decode_int);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_next_line(scanner);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	status = _synctex_scan_named(scanner,"Y Offset:",&(scanner->pre_y_offset),(synctex_decoder_t)&_synctex_decode_int);	if(status<SYNCTEX_STATUS_OK) {		return status;	}	return _synctex_next_line(scanner);}/*  parse a float with a dimension */synctex_status_t _synctex_scan_float_and_dimension(synctex_scanner_t scanner, float *  value_ref) {	synctex_status_t status = 0;	unsigned char *  endptr = NULL;	float f = 0;#ifdef HAVE_SETLOCALE	char *  loc = setlocale(LC_NUMERIC, NULL);#endif	size_t available = 0;	if(NULL == scanner || NULL == value_ref) {		return SYNCTEX_STATUS_BAD_ARGUMENT;	}	available = SYNCTEX_BUFFER_MIN_SIZE;	status = _synctex_buffer_get_available_size(scanner, &available);	if(status<SYNCTEX_STATUS_EOF) {		_synctex_error("!  problem with float.");		return status;	}#ifdef HAVE_SETLOCALE	setlocale(LC_NUMERIC, "C");#endif	f = strtod((char *)SYNCTEX_CUR,(char **)&endptr);#ifdef HAVE_SETLOCALE	setlocale(LC_NUMERIC, loc);#endif	if(endptr == SYNCTEX_CUR) {		_synctex_error("!  a float was expected.");		return SYNCTEX_STATUS_ERROR;	}	SYNCTEX_CUR = endptr;	if((status = _synctex_match_string(scanner,"in")) >= SYNCTEX_STATUS_OK) {		f *= 72.27f*65536;	} else if(status<SYNCTEX_STATUS_EOF) {report_unit_error:		_synctex_error("!  problem with unit.");		return status;	} else if((status = _synctex_match_string(scanner,"cm")) >= SYNCTEX_STATUS_OK) {		f *= 72.27f*65536/2.54f;	} else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"mm")) >= SYNCTEX_STATUS_OK) {		f *= 72.27f*65536/25.4f;	} else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"pt")) >= SYNCTEX_STATUS_OK) {		f *= 65536.0f;	} else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"bp")) >= SYNCTEX_STATUS_OK) {		f *= 72.27f/72*65536.0f;	}  else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"pc")) >= SYNCTEX_STATUS_OK) {		f *= 12.0*65536.0f;	}  else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"sp")) >= SYNCTEX_STATUS_OK) {		f *= 1.0f;	}  else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"dd")) >= SYNCTEX_STATUS_OK) {		f *= 1238.0f/1157*65536.0f;	}  else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"cc")) >= SYNCTEX_STATUS_OK) {		f *= 14856.0f/1157*65536;	} else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"nd")) >= SYNCTEX_STATUS_OK) {		f *= 685.0f/642*65536;	}  else if(status<0) {		goto report_unit_error;	} else if((status = _synctex_match_string(scanner,"nc")) >= SYNCTEX_STATUS_OK) {		f *= 1370.0f/107*65536;	} else if(status<0) {		goto report_unit_error;	}	*value_ref = f;	return SYNCTEX_STATUS_OK;}/*  parse the post scriptum *  SYNCTEX_STATUS_OK is returned on completion *  a negative error is returned otherwise */synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_t scanner) {	synctex_status_t status = 0;	unsigned char *  endptr = NULL;#ifdef HAVE_SETLOCALE	char *  loc = setlocale(LC_NUMERIC, NULL);#endif	if(NULL == scanner) {		return SYNCTEX_STATUS_BAD_ARGUMENT;	}	/*  Scan the file until a post scriptum line is found */post_scriptum_not_found:	status = _synctex_match_string(scanner,"Post scriptum:");	if(status<SYNCTEX_STATUS_NOT_OK) {		return status;	}	if(status == SYNCTEX_STATUS_NOT_OK) {		status = _synctex_next_line(scanner);		if(status<SYNCTEX_STATUS_EOF) {			return status;		} else if(status<SYNCTEX_STATUS_OK) {			return SYNCTEX_STATUS_OK;/*  The EOF is found, we have properly scanned the file */		}		goto post_scriptum_not_found;	}	/*  We found the name, advance to the next line. */next_line:	status = _synctex_next_line(scanner);	if(status<SYNCTEX_STATUS_EOF) {		return status;	} else if(status<SYNCTEX_STATUS_OK) {		return SYNCTEX_STATUS_OK;/*  The EOF is found, we have properly scanned the file */	}	/*  Scanning the information */	status = _synctex_match_string(scanner,"Magnification:");	if(status == SYNCTEX_STATUS_OK ) {#ifdef HAVE_SETLOCALE		setlocale(LC_NUMERIC, "C");#endif		scanner->unit = strtod((char *)SYNCTEX_CUR,(char **)&endptr);#ifdef HAVE_SETLOCALE		setlocale(LC_NUMERIC, loc);#endif		if(endptr == SYNCTEX_CUR) {			_synctex_error("!  bad magnification in the post sc

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?