|
184 | 184 | ["["] = "]", |
185 | 185 | } |
186 | 186 |
|
187 | | - -- position, isUrlBlock = findEndOfBlockContents( path, template, position ) |
188 | | - local function findEndOfBlockContents(path, template, pos) |
| 187 | + -- position, isUrlBlock = findEndOfBlockContents( path, template, position, blockI1 ) |
| 188 | + local function findEndOfBlockContents(path, template, pos, blockI1) |
189 | 189 | !local PRINT_PROGRESS = DEV and 1==0 |
190 | 190 | !if PRINT_PROGRESS then __LUA`printf("%s(%d):%d: >>>>>>>>", path, pos, getLineNumber(template, pos))` end |
191 | 191 |
|
|
197 | 197 | if template:find("^ *%.?%.?/", pos) or template:find("^ *%a%w*:/", pos) then |
198 | 198 | local i1 = template:find("%*?}}", pos) |
199 | 199 | if not i1 then |
200 | | - fileError(path, template, pos, "Incomplete URL block.") |
| 200 | + fileError(path, template, blockI1, "Incomplete URL block.") |
201 | 201 | end |
202 | 202 | return i1-1, true |
203 | 203 | end |
|
249 | 249 |
|
250 | 250 | if not i2 then |
251 | 251 | fileError( |
252 | | - path, template, pos, |
| 252 | + path, template, posComment, |
253 | 253 | "Incomplete long comment. (Code block starting at line %d)", |
254 | 254 | getLineNumber(template, blockContentsI1) |
255 | 255 | ) |
|
296 | 296 |
|
297 | 297 | if not i2 then |
298 | 298 | fileError( |
299 | | - path, template, pos, |
| 299 | + path, template, posStringLong, |
300 | 300 | "Incomplete long string. (Code block starting at line %d)", |
301 | 301 | getLineNumber(template, blockContentsI1) |
302 | 302 | ) |
|
354 | 354 | ) |
355 | 355 | end |
356 | 356 |
|
357 | | - fileError( |
358 | | - path, template, pos, |
359 | | - "Missing end of code block. (Code block starting at line %d)", |
360 | | - getLineNumber(template, blockContentsI1) |
361 | | - ) |
| 357 | + fileError(path, template, blockI1, "Missing end of this code block.") |
362 | 358 | end |
363 | 359 | end |
364 | 360 |
|
|
394 | 390 |
|
395 | 391 | table.insert(out, "do end ") -- Statement divider. |
396 | 392 |
|
397 | | - local blockContentsI2, isUrlBlock = findEndOfBlockContents(path, template, pos) |
| 393 | + local blockContentsI2, isUrlBlock = findEndOfBlockContents(path, template, pos, blockI1) |
398 | 394 | local blockContents = template:sub(blockContentsI1, blockContentsI2) |
399 | 395 | pos = blockContentsI2 + 1 |
400 | 396 |
|
|
431 | 427 | if not expr then ident, expr = blockContents:match!(NOSPACE("^ %s* fori %s+ ("..PATTERN_IDENT..") %s+ in "..PATTERN_IDENT_END.." %s* (%S.*)")) |
432 | 428 | if not expr then reverse, expr = blockContents:match!(NOSPACE("^ %s* fori %s* (<?) %s* (%S.*)")) |
433 | 429 | if not expr then |
434 | | - fileError(path, template, blockI1, "Invalid 'fori' statement.") |
| 430 | + fileError(path, template, blockContentsI1, "Invalid 'fori' statement.") |
435 | 431 | end end end |
436 | 432 |
|
437 | 433 | reverse = (reverse == "<") |
438 | 434 |
|
439 | 435 | if not loadstring("_=("..expr..")") then |
440 | | - fileError(path, template, blockI1, "Invalid value expression for 'fori' loop: %s", trim(expr)) -- @UX: Better error message. |
| 436 | + fileError(path, template, blockContentsI1, "Invalid value expression for 'fori' loop: %s", trim(expr)) -- @UX: Better error message. |
441 | 437 | end |
442 | 438 |
|
443 | 439 | table.insert(out, "for i, ") |
|
492 | 488 | local expr = blockContents:gsub("for%s*<", "", 1) |
493 | 489 |
|
494 | 490 | if not loadstring("_=("..expr..")") then |
495 | | - fileError(path, template, blockI1, "Invalid value expression for simplified 'for' loop: %s", trim(expr)) -- @UX: Better error message. |
| 491 | + fileError(path, template, blockContentsI1, "Invalid value expression for simplified 'for' loop: %s", trim(expr)) -- @UX: Better error message. |
496 | 492 | end |
497 | 493 |
|
498 | 494 | table.insert(out, "for i = (") |
|
504 | 500 | local expr = blockContents:gsub("for", "", 1) |
505 | 501 |
|
506 | 502 | if not loadstring("_=("..expr..")") then |
507 | | - fileError(path, template, blockI1, "Invalid value expression for simplified 'for' loop: %s", trim(expr)) -- @UX: Better error message. |
| 503 | + fileError(path, template, blockContentsI1, "Invalid value expression for simplified 'for' loop: %s", trim(expr)) -- @UX: Better error message. |
508 | 504 | end |
509 | 505 |
|
510 | 506 | table.insert(out, "for i = 1, (") |
|
625 | 621 | then |
626 | 622 | -- @Polish: Make sure there's no garbage at the end of blockContents. |
627 | 623 | if tcsLevel == 1 then |
628 | | - fileError(path, template, blockI1, "Unexpected templateified '%s'.", blockContents:match"%a+") |
| 624 | + fileError(path, template, blockContentsI1, "Unexpected templateified '%s'.", blockContents:match"%a+") |
629 | 625 | end |
630 | 626 | !!(TRIM_POS_AFTER_BLOCK) |
631 | 627 | local blockI2 = pos - 1 |
|
634 | 630 | -- Value expression. |
635 | 631 | elseif insertLuaForEchoingIfExpression(out, blockContents) then |
636 | 632 | if blockContents:find"^%s*function%s*%(" then -- We do allow echoing functions, but this specifically is probably an error made by the user. |
637 | | - fileError(path, template, blockI1, "Invalid value expression.") |
| 633 | + fileError(path, template, blockContentsI1, "Invalid value expression.") |
638 | 634 | end |
639 | 635 | !!(TRIM_POS_AFTER_BLOCK) |
640 | 636 |
|
@@ -802,16 +798,57 @@ function _G.errorf(levelOrS, ...) |
802 | 798 | end |
803 | 799 | end |
804 | 800 |
|
805 | | --- fileError( path, contents, position, formatString, ... ) |
806 | | --- fileError( path, nil, lineNumber, formatString, ... ) |
807 | | -function _G.fileError(path, contents, pos, s, ...) |
808 | | - local ln = contents and getLineNumber(contents, pos) or pos |
809 | | - if type(s) ~= "string" then |
810 | | - s = F("%s:%d: %s", path, ln, tostring(s)) |
811 | | - else |
812 | | - s = F("%s:%d: "..s, path, ln, ...) |
| 801 | +do |
| 802 | + local function findStartOfNonEmptyLine(s, pos) |
| 803 | + while pos > 1 do |
| 804 | + if s:byte(pos-1) == !(string.byte"\n") and s:byte(pos) ~= !(string.byte"\n") then break end |
| 805 | + pos = pos - 1 |
| 806 | + end |
| 807 | + return math.max(pos, 1) |
| 808 | + end |
| 809 | + local function findEndOfLine(s, pos) |
| 810 | + while pos < #s do |
| 811 | + if s:byte(pos+1) == !(string.byte"\n") then break end |
| 812 | + pos = pos + 1 |
| 813 | + end |
| 814 | + return math.min(pos, #s) |
| 815 | + end |
| 816 | + |
| 817 | + -- fileError( path, contents, position, formatString, ... ) |
| 818 | + -- fileError( path, nil, lineNumber, formatString, ... ) |
| 819 | + function _G.fileError(path, contents, pos, s, ...) |
| 820 | + if contents then |
| 821 | + pos = math.min(math.max(pos, 1), #contents+1) |
| 822 | + end |
| 823 | + local ln = contents and getLineNumber(contents, pos) or pos |
| 824 | + |
| 825 | + if type(s) ~= "string" then |
| 826 | + s = F("%s:%d: %s", path, ln, tostring(s)) |
| 827 | + else |
| 828 | + s = F("%s:%d: "..s, path, ln, ...) |
| 829 | + end |
| 830 | + |
| 831 | + if contents then |
| 832 | + local lineStart = findStartOfNonEmptyLine(contents, pos) |
| 833 | + local lineEnd = findEndOfLine(contents, pos-1) |
| 834 | + local linePre1Start = findStartOfNonEmptyLine(contents, lineStart-1) |
| 835 | + local linePre1End = findEndOfLine(contents, linePre1Start-1) |
| 836 | + local linePre2Start = findStartOfNonEmptyLine(contents, linePre1Start-1) |
| 837 | + local linePre2End = findEndOfLine(contents, linePre2Start-1) |
| 838 | + printf("pos %d | lines %d..%d, %d..%d, %d..%d", pos, linePre2Start,linePre2End+1, linePre1Start,linePre1End+1, lineStart,lineEnd+1) |
| 839 | + |
| 840 | + s = F("%s\n\n%s%s> %s\n> %s^", |
| 841 | + s, |
| 842 | + (linePre2Start < linePre1Start and linePre2Start <= linePre2End) and F("> %s\n", (contents:sub(linePre2Start, linePre2End):gsub("\t", " "))) or "", |
| 843 | + (linePre1Start < lineStart and linePre1Start <= linePre1End) and F("> %s\n", (contents:sub(linePre1Start, linePre1End):gsub("\t", " "))) or "", |
| 844 | + contents:sub(lineStart, lineEnd):gsub("\t", " "), |
| 845 | + ("-"):rep(pos - lineStart + 3*countSubStrings(contents, lineStart, lineEnd, "\t", true)), |
| 846 | + nil |
| 847 | + ) |
| 848 | + end |
| 849 | + |
| 850 | + errorLine(s) |
813 | 851 | end |
814 | | - errorLine(s) |
815 | 852 | end |
816 | 853 |
|
817 | 854 | -- errorLine( message ) |
|
0 commit comments