@@ -954,62 +954,90 @@
954 954 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
size_t offset,
955 955 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
size_t size
956 956 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
){
957 957 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
size_t end;
958 958 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
struct Blob work = BLOB_INITIALIZER;
959 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- int nUscore = 0;
959 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int nUscore = 0; /* Consecutive underscore counter */;
960 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int numberMode = 0 /* 0 for normal, 1 for #NNN numeric,
961 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ and 2 for #NNN.NNN. */;
960 962 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(offset>0 && !fossil_isspace(data[-1])){
961 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- /* Only ever match if the *previous* character is
962 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- whitespace or we're at the start of the input.
963 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Note that we rely on fossil processing emphasis
964 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- markup before reaching this function, so *#Hash*
965 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- will Do The Right Thing. */
963 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Only ever match if the *previous* character is whitespace or
964 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ we're at the start of the input. Note that we rely on fossil
965 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ processing emphasis markup before reaching this function, so
966 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ *#Hash* will Do The Right Thing. Not that this means that
967 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "#Hash." will match while ".#Hash" won't. That's okay. */
966 968 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return 0;
967 969 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
968 970 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
assert( '#' == data[0] );
969 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(size < 2 || !fossil_isalpha(data[1])) return 0;
971 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(size < 2) return 0;
972 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(fossil_isdigit(data[1])){
973 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ numberMode = 1;
974 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else if(!fossil_isalpha(data[1])){
975 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return 0;
976 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
970 977 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#if 0
971 978 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fprintf(stderr,"HASHREF offset=%d size=%d: %.*s\n",
972 979 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
(int)offset, (int)size, (int)size, data);
973 980 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#endif
974 981 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#define HASHTAG_LEGAL_END \
975 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- case ' ': case '\t': case '\r': case '\n': case '.': case ':': case ';': case '!': case '?'
982 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ case ' ': case '\t': case '\r': case '\n': \
983 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ case ':': case ';': case '!': case '?': case ','
984 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* ^^^^ '.' is handled separately */
976 985 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
for(end = 2; end < size; ++end){
977 986 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
char ch = data[end];
987 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Potential TODO: if (ch & 0xF0), treat it as valid, skip that
988 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ multi-byte character's length characters, and continue
989 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ looping. Reminder: UTF8 char lengths can be determined by
990 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ masking against 0xF0: 0xf0==4, 0xe0==3, 0xc0==2, else 1. */
978 991 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
switch(ch){
979 992 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
case '_':
980 993 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Multiple adjacent underscores not permitted. */
981 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(++nUscore>1) goto hashref_bailout;
994 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(numberMode>0 || ++nUscore>1) goto hashref_bailout;
995 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ break;
996 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ case '.':
997 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(1==numberMode) ++numberMode;
998 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ch = 0;
982 999 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
break;
983 1000 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
HASHTAG_LEGAL_END:
984 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(end<3) goto hashref_bailout/*require 2+ characters (arbitrary)*/;
1001 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(numberMode==0 && end<3){
1002 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ goto hashref_bailout/*require 2+ characters (arbitrary)*/;
1003 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
985 1004 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
ch = 0;
986 1005 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
break;
1006 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ case '0': case '1': case '2': case '3': case '4':
1007 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ case '5': case '6': case '7': case '8': case '9':
1008 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ break;
987 1009 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
default:
988 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(!fossil_isalnum(ch)) goto hashref_bailout;
1010 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(numberMode!=0 || !fossil_isalpha(ch)){
1011 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ goto hashref_bailout;
1012 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
989 1013 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
nUscore = 0;
990 1014 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
break;
991 1015 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
992 1016 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(ch) continue;
993 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- else break;
1017 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ break;
1018 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
1019 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(numberMode>1){
1020 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Check for trailing part of #NNN.nnn... */
1021 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert('.'==data[end]);
1022 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(end<size-1 && fossil_isdigit(data[end+1])){
1023 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for(++end; end<size; ++end){
1024 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!fossil_isdigit(data[end])) break;
1025 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
1026 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
994 1027 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
995 1028 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#if 0
996 1029 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fprintf(stderr,"?HASHREF length=%d: %.*s\n",
997 1030 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
(int)end, (int)end, data);
998 1031 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#endif
999 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- /*TODO: in order to support detection of forum post-style
1000 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- references, we need to recognize #X.Y, but only when X and Y are
1001 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- both purely numeric and Y ends on a word/sentence
1002 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- boundary.*/
1003 1032 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(end<size){
1004 1033 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Only match if we end at end of input or what "might" be the end
1005 1034 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
of a natural language grammar construct, e.g. period or
1006 1035 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
[semi]colon. */
1007 1036 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
switch(data[end]){
1037 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ case '.':
1008 1038 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
HASHTAG_LEGAL_END:
1009 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- /* We could arguably treat any leading multi-byte character as
1010 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- valid here. */
1011 1039 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
break;
1012 1040 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
default:
1013 1041 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
goto hashref_bailout;
1014 1042 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1015 1043 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1016 1044 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!