From: drh <> Date: Sat, 8 Nov 2025 15:25:07 +0000 (+0000) Subject: Miscellaneous fixes to the new alignment configurations. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fqrf;p=thirdparty%2Fsqlite.git Miscellaneous fixes to the new alignment configurations. FossilOrigin-Name: 787fb4c2ac80db6552bc7a740c3c3c63c0c8414cb4e7db80d367b4b5512519d0 --- diff --git a/ext/qrf/qrf.c b/ext/qrf/qrf.c index c964dcf4c2..eee1b80e26 100644 --- a/ext/qrf/qrf.c +++ b/ext/qrf/qrf.c @@ -1215,23 +1215,37 @@ static void qrfBoxSeparator( sqlite3_str_append(pOut, "\n", 1); } +/* +** Load into pData the default alignment for the body of a table. +*/ +static void qrfLoadAlignment(qrfColData *pData, Qrf *p){ + sqlite3_int64 i; + memset(pData->aAlign, p->spec.eDfltAlign, pData->nCol); + for(i=0; inCol && ispec.nAlign; i++){ + unsigned char ax = p->spec.aAlign[i]; + if( (ax & QRF_ALIGN_HMASK)!=0 ){ + pData->aAlign[i] = (ax & QRF_ALIGN_HMASK) | + (pData->aAlign[i] & QRF_ALIGN_VMASK); + } + } +} + /* ** Columnar modes require that the entire query be evaluated first, with ** results written into memory, so that we can compute appropriate column ** widths. */ static void qrfColumnar(Qrf *p){ - sqlite3_int64 i, j; - const char *colSep = 0; - const char *rowSep = 0; - const char *rowStart = 0; - int szColSep, szRowSep, szRowStart; - int rc; - int nColumn = p->nCol; - int bWW; - int bCenter; - sqlite3_str *pStr; - qrfColData data; + sqlite3_int64 i, j; /* Loop counters */ + const char *colSep = 0; /* Column separator text */ + const char *rowSep = 0; /* Row terminator text */ + const char *rowStart = 0; /* Row start text */ + int szColSep, szRowSep, szRowStart; /* Size in bytes of previous 3 */ + int rc; /* Result code */ + int nColumn = p->nCol; /* Number of columns */ + int bWW; /* True to do word-wrap */ + sqlite3_str *pStr; /* Temporary rendering */ + qrfColData data; /* Columnar layout data */ rc = sqlite3_step(p->pStmt); if( rc!=SQLITE_ROW || nColumn==0 ){ @@ -1272,9 +1286,6 @@ static void qrfColumnar(Qrf *p){ } p->spec.eText = saved_eText; p->nRow++; - bCenter = 1; - }else{ - bCenter = 0; } do{ if( data.n+nColumn > data.nAlloc ){ @@ -1301,10 +1312,12 @@ static void qrfColumnar(Qrf *p){ } /* Compute the width and alignment of every column */ - memset(data.aAlign, p->spec.eDfltAlign, nColumn); - for(i=0; ispec.nAlign; i++){ - data.aAlign[i] = p->spec.aAlign[i]; + if( p->spec.bColumnNames==QRF_Yes ){ + memset(data.aAlign, p->spec.eTitleAlign, nColumn); + }else{ + qrfLoadAlignment(&data, p); } + for(i=0; ispec.nWidth ){ @@ -1343,9 +1356,10 @@ static void qrfColumnar(Qrf *p){ data.aiCol[i] = w; } - /* TBD: Narrow columns so that the total is less the p->spec.mxTotalWidth */ + /* TBD: Narrow columns so that the total is less than p->spec.mxTotalWidth */ - /* Draw the line across the top of the table */ + /* Draw the line across the top of the table. Also initialize + ** the row boundary and column separator texts. */ switch( p->spec.eStyle ){ case QRF_STYLE_Box: rowStart = BOX_13 " "; @@ -1377,6 +1391,11 @@ static void qrfColumnar(Qrf *p){ bWW = (p->spec.bWordWrap==QRF_Yes && data.bMultiRow); for(i=0; ipOut, rowStart, szRowStart); @@ -1388,7 +1407,7 @@ static void qrfColumnar(Qrf *p){ int nWS; qrfWrapLine(data.azThis[j], data.aiCol[j], bWW, &nThis, &nWide, &iNext); nWS = data.aiCol[j] - nWide; - if( bCenter || (data.aAlign[j] & QRF_ALIGN_HMASK)==QRF_ALIGN_Center ){ + if( (data.aAlign[j] & QRF_ALIGN_HMASK)==QRF_ALIGN_Center ){ /* Center the text */ sqlite3_str_appendchar(p->pOut, nWS/2, ' '); sqlite3_str_append(p->pOut, data.azThis[j], nThis); @@ -1411,29 +1430,37 @@ static void qrfColumnar(Qrf *p){ } } }while( bMore ); - bCenter = 0; + + /* Draw either (1) the separator between the title line and the body + ** of the table, or (2) separators between individual rows of the table + ** body. isTitleDataSeparator will be true if we are doing (1). + */ if( (i==0 || data.bMultiRow) && i+nColumnspec.bColumnNames==QRF_Yes); + if( isTitleDataSeparator ){ + qrfLoadAlignment(&data, p); + } switch( p->spec.eStyle ){ case QRF_STYLE_Table: { - if( (i==0 && p->spec.bColumnNames==QRF_Yes) || data.bMultiRow ){ + if( isTitleDataSeparator || data.bMultiRow ){ qrfRowSeparator(p->pOut, &data, '+'); } break; } case QRF_STYLE_Box: { - if( (i==0 && p->spec.bColumnNames==QRF_Yes) || data.bMultiRow ){ + if( isTitleDataSeparator || data.bMultiRow ){ qrfBoxSeparator(p->pOut, &data, BOX_123, BOX_1234, BOX_134); } break; } case QRF_STYLE_Markdown: { - if( i==0 && p->spec.bColumnNames==QRF_Yes ){ + if( isTitleDataSeparator ){ qrfRowSeparator(p->pOut, &data, '|'); } break; } case QRF_STYLE_Column: { - if( i==0 && p->spec.bColumnNames==QRF_Yes ){ + if( isTitleDataSeparator ){ for(j=0; jpOut, data.aiCol[j], '-'); if( jinterp, objv[i+1], azAlign, - zArg[1]=='d' ? "default alignment (-dfltalign)" : + zArg[1]=='d' ? "default alignment (-defaultalign)" : "title alignment (-titlealign)", 0, &ax); if( rc ) goto format_failed; @@ -2298,9 +2298,9 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ rc = Tcl_ListObjIndex(pDb->interp, objv[i+1], jj, &pTerm); if( rc ) goto format_failed; rc = Tcl_GetIndexFromObj(pDb->interp, pTerm, azAlign, - "column alignement (-align)", 0, &x); + "column alignment (-align)", 0, &x); if( rc ) goto format_failed; - qrf.aAlign[jj] = x; + qrf.aAlign[jj] = aAlignMap[x]; } i++; }else if( strcmp(zArg,"-widths")==0 ){ diff --git a/test/qrf01.test b/test/qrf01.test index 44fa2e37da..86ec135e82 100644 --- a/test/qrf01.test +++ b/test/qrf01.test @@ -390,11 +390,53 @@ do_test 2.6 { │ │ │ own dog. │ └───────┴───────┴────────────────────┘ } +do_test 2.7 { + set result "\n[db format -widths {5 5 18} -wordwrap yes \ + -align {left center right} -titlealign right \ + {SELECT * FROM t1}]" +} { +┌───────┬───────┬────────────────────┐ +│ a │ b │ c │ +├───────┼───────┼────────────────────┤ +│ 1 │ 2 │ The quick fox │ +│ │ │ jumps over the │ +│ │ │ lazy brown dog. │ +└───────┴───────┴────────────────────┘ +} +do_test 2.8 { + set result "\n[db format -widths {5 8 11} -wordwrap yes \ + -align {auto auto center} -titlealign left \ + -defaultalign right \ + {SELECT * FROM t1}]" +} { +┌───────┬──────────┬─────────────┐ +│ a │ b │ c │ +├───────┼──────────┼─────────────┤ +│ 1 │ 2 │ The quick │ +│ │ │ fox jumps │ +│ │ │ over the │ +│ │ │ lazy brown │ +│ │ │ dog. │ +└───────┴──────────┴─────────────┘ +} +do_test 2.9 { + catch {db format -align {auto xyz 123} {SELECT * FROM t1}} res + set res +} {bad column alignment (-align) "xyz": must be auto, bottom, c, center, e, left, middle, n, ne, nw, right, s, se, sw, top, or w} +do_test 2.10 { + catch {db format -defaultalign xyz {SELECT * FROM t1}} res + set res +} {bad default alignment (-defaultalign) "xyz": must be auto, bottom, c, center, e, left, middle, n, ne, nw, right, s, se, sw, top, or w} +do_test 2.11 { + catch {db format -titlealign xyz {SELECT * FROM t1}} res + set res +} {bad title alignment (-titlealign) "xyz": must be auto, bottom, c, center, e, left, middle, n, ne, nw, right, s, se, sw, top, or w} -do_execsql_test 2.10 { + +do_execsql_test 2.30 { UPDATE t1 SET c='Η γρήγορη αλεπού πηδάει πάνω από το τεμπέλικο καφέ σκυλί'; } -do_test 2.11 { +do_test 2.31 { set result "\n[db format -widths {5 -5 18} -wordwrap on \ {SELECT * FROM t1}]" } { @@ -407,7 +449,7 @@ do_test 2.11 { │ │ │ σκυλί │ └───────┴───────┴────────────────────┘ } -do_test 2.12 { +do_test 2.32 { set result "\n[db format -widths {5 5 18} -align {left center center} -wordwrap on \ {SELECT * FROM t1}]" } {