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 + -
显示快捷键?