Fossil SCM
Minor refactoring and general cleanup of the "fossil setting" logic.
Commit
32f8da0ce785b63ad8a53fa851b5416b0887391a
Parent
51751b00a96435f…
2 files changed
+123
-79
+7
-7
M
src/db.c
+123
-79
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1520,12 +1520,12 @@ | ||
| 1520 | 1520 | int i; |
| 1521 | 1521 | const char *zSep = ""; |
| 1522 | 1522 | |
| 1523 | 1523 | blob_zero(&x); |
| 1524 | 1524 | blob_append_sql(&x, "("); |
| 1525 | - for(i=0; ctrlSettings[i].name; i++){ | |
| 1526 | - blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name); | |
| 1525 | + for(i=0; aSetting[i].name; i++){ | |
| 1526 | + blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, aSetting[i].name); | |
| 1527 | 1527 | zSep = ","; |
| 1528 | 1528 | } |
| 1529 | 1529 | blob_append_sql(&x, ")"); |
| 1530 | 1530 | return blob_sql_text(&x); |
| 1531 | 1531 | } |
| @@ -1918,16 +1918,21 @@ | ||
| 1918 | 1918 | g.zConfigDbType = zTempDbType; |
| 1919 | 1919 | } |
| 1920 | 1920 | } |
| 1921 | 1921 | |
| 1922 | 1922 | /* |
| 1923 | -** Logic for reading potentially versioned settings from | |
| 1924 | -** .fossil-settings/<name> , and emits warnings if necessary. | |
| 1925 | -** Returns the non-versioned value without modification if there is no | |
| 1926 | -** versioned value. | |
| 1923 | +** Try to read a versioned setting string from .fossil-settings/<name>. | |
| 1924 | +** | |
| 1925 | +** Return the text of the string if it is found. Return NULL if not | |
| 1926 | +** found. | |
| 1927 | +** | |
| 1928 | +** If the zNonVersionedSetting parameter is not NULL then it holds the | |
| 1929 | +** non-versioned value for this setting. If both a versioned and ad | |
| 1930 | +** non-versioned value exist and are not equal, then a warning message | |
| 1931 | +** might be generated. | |
| 1927 | 1932 | */ |
| 1928 | -char *db_get_do_versionable(const char *zName, char *zNonVersionedSetting){ | |
| 1933 | +char *db_get_versioned(const char *zName, char *zNonVersionedSetting){ | |
| 1929 | 1934 | char *zVersionedSetting = 0; |
| 1930 | 1935 | int noWarn = 0; |
| 1931 | 1936 | struct _cacheEntry { |
| 1932 | 1937 | struct _cacheEntry *next; |
| 1933 | 1938 | const char *zName, *zValue; |
| @@ -1998,37 +2003,38 @@ | ||
| 1998 | 2003 | |
| 1999 | 2004 | |
| 2000 | 2005 | /* |
| 2001 | 2006 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 2002 | 2007 | ** repository and local databases. |
| 2008 | +** | |
| 2009 | +** If no such variable exists, return zDefault. Or, if zName is the name | |
| 2010 | +** of a setting, then the zDefault is ignored and the default value of the | |
| 2011 | +** setting is returned instead. If zName is a versioned setting, then | |
| 2012 | +** versioned value takes priority. | |
| 2003 | 2013 | */ |
| 2004 | 2014 | char *db_get(const char *zName, char *zDefault){ |
| 2005 | 2015 | char *z = 0; |
| 2006 | - int i; | |
| 2007 | - const struct stControlSettings *ctrlSetting = 0; | |
| 2008 | - /* Is this a setting? */ | |
| 2009 | - for(i=0; ctrlSettings[i].name; i++){ | |
| 2010 | - if( strcmp(ctrlSettings[i].name, zName)==0 ){ | |
| 2011 | - ctrlSetting = &(ctrlSettings[i]); | |
| 2012 | - break; | |
| 2013 | - } | |
| 2014 | - } | |
| 2016 | + const Setting *pSetting = db_find_setting(zName, 0); | |
| 2015 | 2017 | if( g.repositoryOpen ){ |
| 2016 | 2018 | z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName); |
| 2017 | 2019 | } |
| 2018 | 2020 | if( z==0 && g.zConfigDbName ){ |
| 2019 | 2021 | db_swap_connections(); |
| 2020 | 2022 | z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName); |
| 2021 | 2023 | db_swap_connections(); |
| 2022 | 2024 | } |
| 2023 | - if( ctrlSetting!=0 && ctrlSetting->versionable ){ | |
| 2025 | + if( pSetting!=0 && pSetting->versionable ){ | |
| 2024 | 2026 | /* This is a versionable setting, try and get the info from a |
| 2025 | 2027 | ** checked out file */ |
| 2026 | - z = db_get_do_versionable(zName, z); | |
| 2028 | + z = db_get_versioned(zName, z); | |
| 2027 | 2029 | } |
| 2028 | 2030 | if( z==0 ){ |
| 2029 | - z = zDefault; | |
| 2031 | + if( zDefault==0 && pSetting && pSetting->def[0] ){ | |
| 2032 | + z = fossil_strdup(pSetting->def); | |
| 2033 | + }else{ | |
| 2034 | + z = zDefault; | |
| 2035 | + } | |
| 2030 | 2036 | } |
| 2031 | 2037 | return z; |
| 2032 | 2038 | } |
| 2033 | 2039 | char *db_get_mtime(const char *zName, char *zFormat, char *zDefault){ |
| 2034 | 2040 | char *z = 0; |
| @@ -2290,88 +2296,91 @@ | ||
| 2290 | 2296 | g.argc = 2; |
| 2291 | 2297 | info_cmd(); |
| 2292 | 2298 | } |
| 2293 | 2299 | |
| 2294 | 2300 | /* |
| 2295 | -** Print the value of a setting named zName | |
| 2301 | +** Print the current value of a setting identified by the pSetting | |
| 2302 | +** pointer. | |
| 2296 | 2303 | */ |
| 2297 | -static void print_setting( | |
| 2298 | - const struct stControlSettings *ctrlSetting, | |
| 2299 | - int localOpen | |
| 2300 | -){ | |
| 2304 | +static void print_setting(const Setting *pSetting){ | |
| 2301 | 2305 | Stmt q; |
| 2302 | 2306 | if( g.repositoryOpen ){ |
| 2303 | 2307 | db_prepare(&q, |
| 2304 | 2308 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 2305 | 2309 | " UNION ALL " |
| 2306 | 2310 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 2307 | - ctrlSetting->name, ctrlSetting->name | |
| 2311 | + pSetting->name, pSetting->name | |
| 2308 | 2312 | ); |
| 2309 | 2313 | }else{ |
| 2310 | 2314 | db_prepare(&q, |
| 2311 | 2315 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 2312 | - ctrlSetting->name | |
| 2316 | + pSetting->name | |
| 2313 | 2317 | ); |
| 2314 | 2318 | } |
| 2315 | 2319 | if( db_step(&q)==SQLITE_ROW ){ |
| 2316 | - fossil_print("%-20s %-8s %s\n", ctrlSetting->name, db_column_text(&q, 0), | |
| 2320 | + fossil_print("%-20s %-8s %s\n", pSetting->name, db_column_text(&q, 0), | |
| 2317 | 2321 | db_column_text(&q, 1)); |
| 2318 | 2322 | }else{ |
| 2319 | - fossil_print("%-20s\n", ctrlSetting->name); | |
| 2323 | + fossil_print("%-20s\n", pSetting->name); | |
| 2320 | 2324 | } |
| 2321 | - if( ctrlSetting->versionable && localOpen ){ | |
| 2325 | + if( pSetting->versionable && g.localOpen ){ | |
| 2322 | 2326 | /* Check to see if this is overridden by a versionable settings file */ |
| 2323 | 2327 | Blob versionedPathname; |
| 2324 | 2328 | blob_zero(&versionedPathname); |
| 2325 | 2329 | blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", |
| 2326 | - g.zLocalRoot, ctrlSetting->name); | |
| 2330 | + g.zLocalRoot, pSetting->name); | |
| 2327 | 2331 | if( file_size(blob_str(&versionedPathname))>=0 ){ |
| 2328 | 2332 | fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", |
| 2329 | - ctrlSetting->name); | |
| 2333 | + pSetting->name); | |
| 2330 | 2334 | } |
| 2331 | 2335 | } |
| 2332 | 2336 | db_finalize(&q); |
| 2333 | 2337 | } |
| 2334 | 2338 | |
| 2335 | 2339 | |
| 2340 | +#if INTERFACE | |
| 2336 | 2341 | /* |
| 2337 | -** define all settings, which can be controlled via the set/unset | |
| 2338 | -** command. var is the name of the internal configuration name for db_(un)set. | |
| 2342 | +** Define all settings, which can be controlled via the set/unset | |
| 2343 | +** command. | |
| 2344 | +** | |
| 2345 | +** var is the name of the internal configuration name for db_(un)set. | |
| 2339 | 2346 | ** If var is 0, the settings name is used. |
| 2347 | +** | |
| 2340 | 2348 | ** width is the length for the edit field on the behavior page, 0 |
| 2341 | 2349 | ** is used for on/off checkboxes. |
| 2350 | +** | |
| 2342 | 2351 | ** The behaviour page doesn't use a special layout. It lists all |
| 2343 | 2352 | ** set-commands and displays the 'set'-help as info. |
| 2344 | 2353 | */ |
| 2345 | -#if INTERFACE | |
| 2346 | -struct stControlSettings { | |
| 2354 | +struct Setting { | |
| 2347 | 2355 | const char *name; /* Name of the setting */ |
| 2348 | 2356 | const char *var; /* Internal variable name used by db_set() */ |
| 2349 | 2357 | int width; /* Width of display. 0 for boolean values. */ |
| 2350 | 2358 | int versionable; /* Is this setting versionable? */ |
| 2351 | 2359 | int forceTextArea; /* Force using a text area for display? */ |
| 2352 | 2360 | const char *def; /* Default value */ |
| 2353 | 2361 | }; |
| 2354 | 2362 | #endif /* INTERFACE */ |
| 2355 | -struct stControlSettings const ctrlSettings[] = { | |
| 2363 | + | |
| 2364 | +const Setting aSetting[] = { | |
| 2356 | 2365 | { "access-log", 0, 0, 0, 0, "off" }, |
| 2357 | 2366 | { "admin-log", 0, 0, 0, 0, "off" }, |
| 2358 | 2367 | { "allow-symlinks", 0, 0, 1, 0, "off" }, |
| 2359 | 2368 | { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, |
| 2360 | 2369 | { "auto-hyperlink", 0, 0, 0, 0, "on", }, |
| 2361 | 2370 | { "auto-shun", 0, 0, 0, 0, "on" }, |
| 2362 | 2371 | { "autosync", 0, 0, 0, 0, "on" }, |
| 2363 | 2372 | { "autosync-tries", 0, 16, 0, 0, "1" }, |
| 2364 | 2373 | { "binary-glob", 0, 40, 1, 0, "" }, |
| 2365 | - { "clearsign", 0, 0, 0, 0, "off" }, | |
| 2366 | 2374 | #if defined(_WIN32) || defined(__CYGWIN__) || defined(__DARWIN__) || \ |
| 2367 | 2375 | defined(__APPLE__) |
| 2368 | 2376 | { "case-sensitive", 0, 0, 0, 0, "off" }, |
| 2369 | 2377 | #else |
| 2370 | 2378 | { "case-sensitive", 0, 0, 0, 0, "on" }, |
| 2371 | 2379 | #endif |
| 2372 | 2380 | { "clean-glob", 0, 40, 1, 0, "" }, |
| 2381 | + { "clearsign", 0, 0, 0, 0, "off" }, | |
| 2373 | 2382 | { "crnl-glob", 0, 40, 1, 0, "" }, |
| 2374 | 2383 | { "default-perms", 0, 16, 0, 0, "u" }, |
| 2375 | 2384 | { "diff-binary", 0, 0, 0, 0, "on" }, |
| 2376 | 2385 | { "diff-command", 0, 40, 0, 0, "" }, |
| 2377 | 2386 | { "dont-push", 0, 0, 0, 0, "off" }, |
| @@ -2412,10 +2421,41 @@ | ||
| 2412 | 2421 | { "th1-uri-regexp", 0, 40, 1, 0, "" }, |
| 2413 | 2422 | { "web-browser", 0, 32, 0, 0, "" }, |
| 2414 | 2423 | { "white-foreground", 0, 0, 0, 0, "off" }, |
| 2415 | 2424 | { 0,0,0,0,0,0 } |
| 2416 | 2425 | }; |
| 2426 | + | |
| 2427 | +/* | |
| 2428 | +** Look up a control setting by its name. Return a pointer to the Setting | |
| 2429 | +** object, or NULL if there is no such setting. | |
| 2430 | +** | |
| 2431 | +** If allowPrefix is true, then the Setting returned is the first one for | |
| 2432 | +** which zName is a prefix of the Setting name. | |
| 2433 | +*/ | |
| 2434 | +const Setting *db_find_setting(const char *zName, int allowPrefix){ | |
| 2435 | + int lwr, mid, upr, c; | |
| 2436 | + int n = (int)strlen(zName) + !allowPrefix; | |
| 2437 | + lwr = 0; | |
| 2438 | + upr = ArraySize(aSetting)-2; | |
| 2439 | + while( upr>=lwr ){ | |
| 2440 | + mid = (upr+lwr)/2; | |
| 2441 | + c = fossil_strncmp(zName, aSetting[mid].name, n); | |
| 2442 | + if( c<0 ){ | |
| 2443 | + upr = mid - 1; | |
| 2444 | + }else if( c>0 ){ | |
| 2445 | + lwr = mid + 1; | |
| 2446 | + }else{ | |
| 2447 | + if( allowPrefix ){ | |
| 2448 | + while( mid>lwr && fossil_strncmp(zName, aSetting[mid-1].name, n)==0 ){ | |
| 2449 | + mid--; | |
| 2450 | + } | |
| 2451 | + } | |
| 2452 | + return &aSetting[mid]; | |
| 2453 | + } | |
| 2454 | + } | |
| 2455 | + return 0; | |
| 2456 | +} | |
| 2417 | 2457 | |
| 2418 | 2458 | /* |
| 2419 | 2459 | ** COMMAND: settings |
| 2420 | 2460 | ** COMMAND: unset* |
| 2421 | 2461 | ** |
| @@ -2663,61 +2703,65 @@ | ||
| 2663 | 2703 | globalFlag = 1; |
| 2664 | 2704 | } |
| 2665 | 2705 | if( unsetFlag && g.argc!=3 ){ |
| 2666 | 2706 | usage("PROPERTY ?-global?"); |
| 2667 | 2707 | } |
| 2708 | + | |
| 2709 | + /* Verify that the aSetting[] entries are in sorted order. This is | |
| 2710 | + ** necessary for the binary search in db_find_setting() to work correctly. | |
| 2711 | + */ | |
| 2712 | + for(i=1; aSetting[i].name; i++){ | |
| 2713 | + if( fossil_strcmp(aSetting[i-1].name, aSetting[i].name)>=0 ){ | |
| 2714 | + fossil_panic("Internal Error: aSetting[] entries for \"%s\"" | |
| 2715 | + " and \"%s\" are out of order.", | |
| 2716 | + aSetting[i-1].name, aSetting[i].name); | |
| 2717 | + } | |
| 2718 | + } | |
| 2719 | + | |
| 2668 | 2720 | if( g.argc==2 ){ |
| 2669 | - int openLocal = db_open_local(0); | |
| 2670 | - for(i=0; ctrlSettings[i].name; i++){ | |
| 2671 | - print_setting(&ctrlSettings[i], openLocal); | |
| 2721 | + for(i=0; aSetting[i].name; i++){ | |
| 2722 | + print_setting(&aSetting[i]); | |
| 2672 | 2723 | } |
| 2673 | 2724 | }else if( g.argc==3 || g.argc==4 ){ |
| 2674 | 2725 | const char *zName = g.argv[2]; |
| 2675 | - int isManifest; | |
| 2676 | - int n = strlen(zName); | |
| 2677 | - for(i=0; ctrlSettings[i].name; i++){ | |
| 2678 | - if( strncmp(ctrlSettings[i].name, zName, n)==0 ) break; | |
| 2679 | - } | |
| 2680 | - if( !ctrlSettings[i].name ){ | |
| 2726 | + int n = (int)strlen(zName); | |
| 2727 | + const Setting *pSetting = db_find_setting(zName, 1); | |
| 2728 | + if( pSetting==0 ){ | |
| 2681 | 2729 | fossil_fatal("no such setting: %s", zName); |
| 2682 | 2730 | } |
| 2683 | - isManifest = fossil_strcmp(ctrlSettings[i].name, "manifest")==0; | |
| 2684 | - if( isManifest && globalFlag ){ | |
| 2731 | + if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){ | |
| 2685 | 2732 | fossil_fatal("cannot set 'manifest' globally"); |
| 2686 | 2733 | } |
| 2687 | 2734 | if( unsetFlag || g.argc==4 ){ |
| 2688 | - if( ctrlSettings[i+1].name | |
| 2689 | - && strncmp(ctrlSettings[i+1].name, zName, n)==0 | |
| 2690 | - && ctrlSettings[i].name[n]!=0 | |
| 2691 | - ){ | |
| 2692 | - fossil_print("ambiguous property prefix: %s\nMatching properties:\n", | |
| 2693 | - zName); | |
| 2694 | - while( ctrlSettings[i].name | |
| 2695 | - && strncmp(ctrlSettings[i].name, zName, n)==0 | |
| 2696 | - ){ | |
| 2697 | - fossil_print("%s\n", ctrlSettings[i].name); | |
| 2698 | - i++; | |
| 2699 | - } | |
| 2700 | - fossil_exit(1); | |
| 2701 | - }else{ | |
| 2702 | - if( unsetFlag ){ | |
| 2703 | - db_unset(ctrlSettings[i].name, globalFlag); | |
| 2704 | - }else{ | |
| 2705 | - db_set(ctrlSettings[i].name, g.argv[3], globalFlag); | |
| 2706 | - } | |
| 2707 | - } | |
| 2708 | - }else{ | |
| 2709 | - isManifest = 0; | |
| 2710 | - while( ctrlSettings[i].name | |
| 2711 | - && strncmp(ctrlSettings[i].name, zName, n)==0 | |
| 2712 | - ){ | |
| 2713 | - print_setting(&ctrlSettings[i], db_open_local(0)); | |
| 2714 | - i++; | |
| 2715 | - } | |
| 2716 | - } | |
| 2717 | - if( isManifest && g.localOpen ){ | |
| 2718 | - manifest_to_disk(db_lget_int("checkout", 0)); | |
| 2735 | + int isManifest = fossil_strcmp(pSetting->name, "manifest")==0; | |
| 2736 | + if( pSetting[1].name && fossil_strncmp(pSetting[1].name, zName, n)==0 ){ | |
| 2737 | + Blob x; | |
| 2738 | + int i; | |
| 2739 | + blob_init(&x,0,0); | |
| 2740 | + for(i=0; pSetting[i].name; i++){ | |
| 2741 | + if( fossil_strncmp(pSetting[i].name,zName,n)!=0 ) break; | |
| 2742 | + blob_appendf(&x, " %s", pSetting[i].name); | |
| 2743 | + } | |
| 2744 | + fossil_fatal("ambiguous setting \"%s\" - might be:%s", | |
| 2745 | + zName, blob_str(&x)); | |
| 2746 | + } | |
| 2747 | + if( globalFlag && isManifest ){ | |
| 2748 | + fossil_fatal("cannot set 'manifest' globally"); | |
| 2749 | + } | |
| 2750 | + if( unsetFlag ){ | |
| 2751 | + db_unset(pSetting->name, globalFlag); | |
| 2752 | + }else{ | |
| 2753 | + db_set(pSetting->name, g.argv[3], globalFlag); | |
| 2754 | + } | |
| 2755 | + if( isManifest && g.localOpen ){ | |
| 2756 | + manifest_to_disk(db_lget_int("checkout", 0)); | |
| 2757 | + } | |
| 2758 | + }else{ | |
| 2759 | + while( pSetting->name && fossil_strncmp(pSetting->name,zName,n)==0 ){ | |
| 2760 | + print_setting(pSetting); | |
| 2761 | + pSetting++; | |
| 2762 | + } | |
| 2719 | 2763 | } |
| 2720 | 2764 | }else{ |
| 2721 | 2765 | usage("?PROPERTY? ?VALUE? ?-global?"); |
| 2722 | 2766 | } |
| 2723 | 2767 | } |
| 2724 | 2768 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1520,12 +1520,12 @@ | |
| 1520 | int i; |
| 1521 | const char *zSep = ""; |
| 1522 | |
| 1523 | blob_zero(&x); |
| 1524 | blob_append_sql(&x, "("); |
| 1525 | for(i=0; ctrlSettings[i].name; i++){ |
| 1526 | blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name); |
| 1527 | zSep = ","; |
| 1528 | } |
| 1529 | blob_append_sql(&x, ")"); |
| 1530 | return blob_sql_text(&x); |
| 1531 | } |
| @@ -1918,16 +1918,21 @@ | |
| 1918 | g.zConfigDbType = zTempDbType; |
| 1919 | } |
| 1920 | } |
| 1921 | |
| 1922 | /* |
| 1923 | ** Logic for reading potentially versioned settings from |
| 1924 | ** .fossil-settings/<name> , and emits warnings if necessary. |
| 1925 | ** Returns the non-versioned value without modification if there is no |
| 1926 | ** versioned value. |
| 1927 | */ |
| 1928 | char *db_get_do_versionable(const char *zName, char *zNonVersionedSetting){ |
| 1929 | char *zVersionedSetting = 0; |
| 1930 | int noWarn = 0; |
| 1931 | struct _cacheEntry { |
| 1932 | struct _cacheEntry *next; |
| 1933 | const char *zName, *zValue; |
| @@ -1998,37 +2003,38 @@ | |
| 1998 | |
| 1999 | |
| 2000 | /* |
| 2001 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 2002 | ** repository and local databases. |
| 2003 | */ |
| 2004 | char *db_get(const char *zName, char *zDefault){ |
| 2005 | char *z = 0; |
| 2006 | int i; |
| 2007 | const struct stControlSettings *ctrlSetting = 0; |
| 2008 | /* Is this a setting? */ |
| 2009 | for(i=0; ctrlSettings[i].name; i++){ |
| 2010 | if( strcmp(ctrlSettings[i].name, zName)==0 ){ |
| 2011 | ctrlSetting = &(ctrlSettings[i]); |
| 2012 | break; |
| 2013 | } |
| 2014 | } |
| 2015 | if( g.repositoryOpen ){ |
| 2016 | z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName); |
| 2017 | } |
| 2018 | if( z==0 && g.zConfigDbName ){ |
| 2019 | db_swap_connections(); |
| 2020 | z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName); |
| 2021 | db_swap_connections(); |
| 2022 | } |
| 2023 | if( ctrlSetting!=0 && ctrlSetting->versionable ){ |
| 2024 | /* This is a versionable setting, try and get the info from a |
| 2025 | ** checked out file */ |
| 2026 | z = db_get_do_versionable(zName, z); |
| 2027 | } |
| 2028 | if( z==0 ){ |
| 2029 | z = zDefault; |
| 2030 | } |
| 2031 | return z; |
| 2032 | } |
| 2033 | char *db_get_mtime(const char *zName, char *zFormat, char *zDefault){ |
| 2034 | char *z = 0; |
| @@ -2290,88 +2296,91 @@ | |
| 2290 | g.argc = 2; |
| 2291 | info_cmd(); |
| 2292 | } |
| 2293 | |
| 2294 | /* |
| 2295 | ** Print the value of a setting named zName |
| 2296 | */ |
| 2297 | static void print_setting( |
| 2298 | const struct stControlSettings *ctrlSetting, |
| 2299 | int localOpen |
| 2300 | ){ |
| 2301 | Stmt q; |
| 2302 | if( g.repositoryOpen ){ |
| 2303 | db_prepare(&q, |
| 2304 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 2305 | " UNION ALL " |
| 2306 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 2307 | ctrlSetting->name, ctrlSetting->name |
| 2308 | ); |
| 2309 | }else{ |
| 2310 | db_prepare(&q, |
| 2311 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 2312 | ctrlSetting->name |
| 2313 | ); |
| 2314 | } |
| 2315 | if( db_step(&q)==SQLITE_ROW ){ |
| 2316 | fossil_print("%-20s %-8s %s\n", ctrlSetting->name, db_column_text(&q, 0), |
| 2317 | db_column_text(&q, 1)); |
| 2318 | }else{ |
| 2319 | fossil_print("%-20s\n", ctrlSetting->name); |
| 2320 | } |
| 2321 | if( ctrlSetting->versionable && localOpen ){ |
| 2322 | /* Check to see if this is overridden by a versionable settings file */ |
| 2323 | Blob versionedPathname; |
| 2324 | blob_zero(&versionedPathname); |
| 2325 | blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", |
| 2326 | g.zLocalRoot, ctrlSetting->name); |
| 2327 | if( file_size(blob_str(&versionedPathname))>=0 ){ |
| 2328 | fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", |
| 2329 | ctrlSetting->name); |
| 2330 | } |
| 2331 | } |
| 2332 | db_finalize(&q); |
| 2333 | } |
| 2334 | |
| 2335 | |
| 2336 | /* |
| 2337 | ** define all settings, which can be controlled via the set/unset |
| 2338 | ** command. var is the name of the internal configuration name for db_(un)set. |
| 2339 | ** If var is 0, the settings name is used. |
| 2340 | ** width is the length for the edit field on the behavior page, 0 |
| 2341 | ** is used for on/off checkboxes. |
| 2342 | ** The behaviour page doesn't use a special layout. It lists all |
| 2343 | ** set-commands and displays the 'set'-help as info. |
| 2344 | */ |
| 2345 | #if INTERFACE |
| 2346 | struct stControlSettings { |
| 2347 | const char *name; /* Name of the setting */ |
| 2348 | const char *var; /* Internal variable name used by db_set() */ |
| 2349 | int width; /* Width of display. 0 for boolean values. */ |
| 2350 | int versionable; /* Is this setting versionable? */ |
| 2351 | int forceTextArea; /* Force using a text area for display? */ |
| 2352 | const char *def; /* Default value */ |
| 2353 | }; |
| 2354 | #endif /* INTERFACE */ |
| 2355 | struct stControlSettings const ctrlSettings[] = { |
| 2356 | { "access-log", 0, 0, 0, 0, "off" }, |
| 2357 | { "admin-log", 0, 0, 0, 0, "off" }, |
| 2358 | { "allow-symlinks", 0, 0, 1, 0, "off" }, |
| 2359 | { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, |
| 2360 | { "auto-hyperlink", 0, 0, 0, 0, "on", }, |
| 2361 | { "auto-shun", 0, 0, 0, 0, "on" }, |
| 2362 | { "autosync", 0, 0, 0, 0, "on" }, |
| 2363 | { "autosync-tries", 0, 16, 0, 0, "1" }, |
| 2364 | { "binary-glob", 0, 40, 1, 0, "" }, |
| 2365 | { "clearsign", 0, 0, 0, 0, "off" }, |
| 2366 | #if defined(_WIN32) || defined(__CYGWIN__) || defined(__DARWIN__) || \ |
| 2367 | defined(__APPLE__) |
| 2368 | { "case-sensitive", 0, 0, 0, 0, "off" }, |
| 2369 | #else |
| 2370 | { "case-sensitive", 0, 0, 0, 0, "on" }, |
| 2371 | #endif |
| 2372 | { "clean-glob", 0, 40, 1, 0, "" }, |
| 2373 | { "crnl-glob", 0, 40, 1, 0, "" }, |
| 2374 | { "default-perms", 0, 16, 0, 0, "u" }, |
| 2375 | { "diff-binary", 0, 0, 0, 0, "on" }, |
| 2376 | { "diff-command", 0, 40, 0, 0, "" }, |
| 2377 | { "dont-push", 0, 0, 0, 0, "off" }, |
| @@ -2412,10 +2421,41 @@ | |
| 2412 | { "th1-uri-regexp", 0, 40, 1, 0, "" }, |
| 2413 | { "web-browser", 0, 32, 0, 0, "" }, |
| 2414 | { "white-foreground", 0, 0, 0, 0, "off" }, |
| 2415 | { 0,0,0,0,0,0 } |
| 2416 | }; |
| 2417 | |
| 2418 | /* |
| 2419 | ** COMMAND: settings |
| 2420 | ** COMMAND: unset* |
| 2421 | ** |
| @@ -2663,61 +2703,65 @@ | |
| 2663 | globalFlag = 1; |
| 2664 | } |
| 2665 | if( unsetFlag && g.argc!=3 ){ |
| 2666 | usage("PROPERTY ?-global?"); |
| 2667 | } |
| 2668 | if( g.argc==2 ){ |
| 2669 | int openLocal = db_open_local(0); |
| 2670 | for(i=0; ctrlSettings[i].name; i++){ |
| 2671 | print_setting(&ctrlSettings[i], openLocal); |
| 2672 | } |
| 2673 | }else if( g.argc==3 || g.argc==4 ){ |
| 2674 | const char *zName = g.argv[2]; |
| 2675 | int isManifest; |
| 2676 | int n = strlen(zName); |
| 2677 | for(i=0; ctrlSettings[i].name; i++){ |
| 2678 | if( strncmp(ctrlSettings[i].name, zName, n)==0 ) break; |
| 2679 | } |
| 2680 | if( !ctrlSettings[i].name ){ |
| 2681 | fossil_fatal("no such setting: %s", zName); |
| 2682 | } |
| 2683 | isManifest = fossil_strcmp(ctrlSettings[i].name, "manifest")==0; |
| 2684 | if( isManifest && globalFlag ){ |
| 2685 | fossil_fatal("cannot set 'manifest' globally"); |
| 2686 | } |
| 2687 | if( unsetFlag || g.argc==4 ){ |
| 2688 | if( ctrlSettings[i+1].name |
| 2689 | && strncmp(ctrlSettings[i+1].name, zName, n)==0 |
| 2690 | && ctrlSettings[i].name[n]!=0 |
| 2691 | ){ |
| 2692 | fossil_print("ambiguous property prefix: %s\nMatching properties:\n", |
| 2693 | zName); |
| 2694 | while( ctrlSettings[i].name |
| 2695 | && strncmp(ctrlSettings[i].name, zName, n)==0 |
| 2696 | ){ |
| 2697 | fossil_print("%s\n", ctrlSettings[i].name); |
| 2698 | i++; |
| 2699 | } |
| 2700 | fossil_exit(1); |
| 2701 | }else{ |
| 2702 | if( unsetFlag ){ |
| 2703 | db_unset(ctrlSettings[i].name, globalFlag); |
| 2704 | }else{ |
| 2705 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 2706 | } |
| 2707 | } |
| 2708 | }else{ |
| 2709 | isManifest = 0; |
| 2710 | while( ctrlSettings[i].name |
| 2711 | && strncmp(ctrlSettings[i].name, zName, n)==0 |
| 2712 | ){ |
| 2713 | print_setting(&ctrlSettings[i], db_open_local(0)); |
| 2714 | i++; |
| 2715 | } |
| 2716 | } |
| 2717 | if( isManifest && g.localOpen ){ |
| 2718 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 2719 | } |
| 2720 | }else{ |
| 2721 | usage("?PROPERTY? ?VALUE? ?-global?"); |
| 2722 | } |
| 2723 | } |
| 2724 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1520,12 +1520,12 @@ | |
| 1520 | int i; |
| 1521 | const char *zSep = ""; |
| 1522 | |
| 1523 | blob_zero(&x); |
| 1524 | blob_append_sql(&x, "("); |
| 1525 | for(i=0; aSetting[i].name; i++){ |
| 1526 | blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, aSetting[i].name); |
| 1527 | zSep = ","; |
| 1528 | } |
| 1529 | blob_append_sql(&x, ")"); |
| 1530 | return blob_sql_text(&x); |
| 1531 | } |
| @@ -1918,16 +1918,21 @@ | |
| 1918 | g.zConfigDbType = zTempDbType; |
| 1919 | } |
| 1920 | } |
| 1921 | |
| 1922 | /* |
| 1923 | ** Try to read a versioned setting string from .fossil-settings/<name>. |
| 1924 | ** |
| 1925 | ** Return the text of the string if it is found. Return NULL if not |
| 1926 | ** found. |
| 1927 | ** |
| 1928 | ** If the zNonVersionedSetting parameter is not NULL then it holds the |
| 1929 | ** non-versioned value for this setting. If both a versioned and ad |
| 1930 | ** non-versioned value exist and are not equal, then a warning message |
| 1931 | ** might be generated. |
| 1932 | */ |
| 1933 | char *db_get_versioned(const char *zName, char *zNonVersionedSetting){ |
| 1934 | char *zVersionedSetting = 0; |
| 1935 | int noWarn = 0; |
| 1936 | struct _cacheEntry { |
| 1937 | struct _cacheEntry *next; |
| 1938 | const char *zName, *zValue; |
| @@ -1998,37 +2003,38 @@ | |
| 2003 | |
| 2004 | |
| 2005 | /* |
| 2006 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 2007 | ** repository and local databases. |
| 2008 | ** |
| 2009 | ** If no such variable exists, return zDefault. Or, if zName is the name |
| 2010 | ** of a setting, then the zDefault is ignored and the default value of the |
| 2011 | ** setting is returned instead. If zName is a versioned setting, then |
| 2012 | ** versioned value takes priority. |
| 2013 | */ |
| 2014 | char *db_get(const char *zName, char *zDefault){ |
| 2015 | char *z = 0; |
| 2016 | const Setting *pSetting = db_find_setting(zName, 0); |
| 2017 | if( g.repositoryOpen ){ |
| 2018 | z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName); |
| 2019 | } |
| 2020 | if( z==0 && g.zConfigDbName ){ |
| 2021 | db_swap_connections(); |
| 2022 | z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName); |
| 2023 | db_swap_connections(); |
| 2024 | } |
| 2025 | if( pSetting!=0 && pSetting->versionable ){ |
| 2026 | /* This is a versionable setting, try and get the info from a |
| 2027 | ** checked out file */ |
| 2028 | z = db_get_versioned(zName, z); |
| 2029 | } |
| 2030 | if( z==0 ){ |
| 2031 | if( zDefault==0 && pSetting && pSetting->def[0] ){ |
| 2032 | z = fossil_strdup(pSetting->def); |
| 2033 | }else{ |
| 2034 | z = zDefault; |
| 2035 | } |
| 2036 | } |
| 2037 | return z; |
| 2038 | } |
| 2039 | char *db_get_mtime(const char *zName, char *zFormat, char *zDefault){ |
| 2040 | char *z = 0; |
| @@ -2290,88 +2296,91 @@ | |
| 2296 | g.argc = 2; |
| 2297 | info_cmd(); |
| 2298 | } |
| 2299 | |
| 2300 | /* |
| 2301 | ** Print the current value of a setting identified by the pSetting |
| 2302 | ** pointer. |
| 2303 | */ |
| 2304 | static void print_setting(const Setting *pSetting){ |
| 2305 | Stmt q; |
| 2306 | if( g.repositoryOpen ){ |
| 2307 | db_prepare(&q, |
| 2308 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 2309 | " UNION ALL " |
| 2310 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 2311 | pSetting->name, pSetting->name |
| 2312 | ); |
| 2313 | }else{ |
| 2314 | db_prepare(&q, |
| 2315 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 2316 | pSetting->name |
| 2317 | ); |
| 2318 | } |
| 2319 | if( db_step(&q)==SQLITE_ROW ){ |
| 2320 | fossil_print("%-20s %-8s %s\n", pSetting->name, db_column_text(&q, 0), |
| 2321 | db_column_text(&q, 1)); |
| 2322 | }else{ |
| 2323 | fossil_print("%-20s\n", pSetting->name); |
| 2324 | } |
| 2325 | if( pSetting->versionable && g.localOpen ){ |
| 2326 | /* Check to see if this is overridden by a versionable settings file */ |
| 2327 | Blob versionedPathname; |
| 2328 | blob_zero(&versionedPathname); |
| 2329 | blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", |
| 2330 | g.zLocalRoot, pSetting->name); |
| 2331 | if( file_size(blob_str(&versionedPathname))>=0 ){ |
| 2332 | fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", |
| 2333 | pSetting->name); |
| 2334 | } |
| 2335 | } |
| 2336 | db_finalize(&q); |
| 2337 | } |
| 2338 | |
| 2339 | |
| 2340 | #if INTERFACE |
| 2341 | /* |
| 2342 | ** Define all settings, which can be controlled via the set/unset |
| 2343 | ** command. |
| 2344 | ** |
| 2345 | ** var is the name of the internal configuration name for db_(un)set. |
| 2346 | ** If var is 0, the settings name is used. |
| 2347 | ** |
| 2348 | ** width is the length for the edit field on the behavior page, 0 |
| 2349 | ** is used for on/off checkboxes. |
| 2350 | ** |
| 2351 | ** The behaviour page doesn't use a special layout. It lists all |
| 2352 | ** set-commands and displays the 'set'-help as info. |
| 2353 | */ |
| 2354 | struct Setting { |
| 2355 | const char *name; /* Name of the setting */ |
| 2356 | const char *var; /* Internal variable name used by db_set() */ |
| 2357 | int width; /* Width of display. 0 for boolean values. */ |
| 2358 | int versionable; /* Is this setting versionable? */ |
| 2359 | int forceTextArea; /* Force using a text area for display? */ |
| 2360 | const char *def; /* Default value */ |
| 2361 | }; |
| 2362 | #endif /* INTERFACE */ |
| 2363 | |
| 2364 | const Setting aSetting[] = { |
| 2365 | { "access-log", 0, 0, 0, 0, "off" }, |
| 2366 | { "admin-log", 0, 0, 0, 0, "off" }, |
| 2367 | { "allow-symlinks", 0, 0, 1, 0, "off" }, |
| 2368 | { "auto-captcha", "autocaptcha", 0, 0, 0, "on" }, |
| 2369 | { "auto-hyperlink", 0, 0, 0, 0, "on", }, |
| 2370 | { "auto-shun", 0, 0, 0, 0, "on" }, |
| 2371 | { "autosync", 0, 0, 0, 0, "on" }, |
| 2372 | { "autosync-tries", 0, 16, 0, 0, "1" }, |
| 2373 | { "binary-glob", 0, 40, 1, 0, "" }, |
| 2374 | #if defined(_WIN32) || defined(__CYGWIN__) || defined(__DARWIN__) || \ |
| 2375 | defined(__APPLE__) |
| 2376 | { "case-sensitive", 0, 0, 0, 0, "off" }, |
| 2377 | #else |
| 2378 | { "case-sensitive", 0, 0, 0, 0, "on" }, |
| 2379 | #endif |
| 2380 | { "clean-glob", 0, 40, 1, 0, "" }, |
| 2381 | { "clearsign", 0, 0, 0, 0, "off" }, |
| 2382 | { "crnl-glob", 0, 40, 1, 0, "" }, |
| 2383 | { "default-perms", 0, 16, 0, 0, "u" }, |
| 2384 | { "diff-binary", 0, 0, 0, 0, "on" }, |
| 2385 | { "diff-command", 0, 40, 0, 0, "" }, |
| 2386 | { "dont-push", 0, 0, 0, 0, "off" }, |
| @@ -2412,10 +2421,41 @@ | |
| 2421 | { "th1-uri-regexp", 0, 40, 1, 0, "" }, |
| 2422 | { "web-browser", 0, 32, 0, 0, "" }, |
| 2423 | { "white-foreground", 0, 0, 0, 0, "off" }, |
| 2424 | { 0,0,0,0,0,0 } |
| 2425 | }; |
| 2426 | |
| 2427 | /* |
| 2428 | ** Look up a control setting by its name. Return a pointer to the Setting |
| 2429 | ** object, or NULL if there is no such setting. |
| 2430 | ** |
| 2431 | ** If allowPrefix is true, then the Setting returned is the first one for |
| 2432 | ** which zName is a prefix of the Setting name. |
| 2433 | */ |
| 2434 | const Setting *db_find_setting(const char *zName, int allowPrefix){ |
| 2435 | int lwr, mid, upr, c; |
| 2436 | int n = (int)strlen(zName) + !allowPrefix; |
| 2437 | lwr = 0; |
| 2438 | upr = ArraySize(aSetting)-2; |
| 2439 | while( upr>=lwr ){ |
| 2440 | mid = (upr+lwr)/2; |
| 2441 | c = fossil_strncmp(zName, aSetting[mid].name, n); |
| 2442 | if( c<0 ){ |
| 2443 | upr = mid - 1; |
| 2444 | }else if( c>0 ){ |
| 2445 | lwr = mid + 1; |
| 2446 | }else{ |
| 2447 | if( allowPrefix ){ |
| 2448 | while( mid>lwr && fossil_strncmp(zName, aSetting[mid-1].name, n)==0 ){ |
| 2449 | mid--; |
| 2450 | } |
| 2451 | } |
| 2452 | return &aSetting[mid]; |
| 2453 | } |
| 2454 | } |
| 2455 | return 0; |
| 2456 | } |
| 2457 | |
| 2458 | /* |
| 2459 | ** COMMAND: settings |
| 2460 | ** COMMAND: unset* |
| 2461 | ** |
| @@ -2663,61 +2703,65 @@ | |
| 2703 | globalFlag = 1; |
| 2704 | } |
| 2705 | if( unsetFlag && g.argc!=3 ){ |
| 2706 | usage("PROPERTY ?-global?"); |
| 2707 | } |
| 2708 | |
| 2709 | /* Verify that the aSetting[] entries are in sorted order. This is |
| 2710 | ** necessary for the binary search in db_find_setting() to work correctly. |
| 2711 | */ |
| 2712 | for(i=1; aSetting[i].name; i++){ |
| 2713 | if( fossil_strcmp(aSetting[i-1].name, aSetting[i].name)>=0 ){ |
| 2714 | fossil_panic("Internal Error: aSetting[] entries for \"%s\"" |
| 2715 | " and \"%s\" are out of order.", |
| 2716 | aSetting[i-1].name, aSetting[i].name); |
| 2717 | } |
| 2718 | } |
| 2719 | |
| 2720 | if( g.argc==2 ){ |
| 2721 | for(i=0; aSetting[i].name; i++){ |
| 2722 | print_setting(&aSetting[i]); |
| 2723 | } |
| 2724 | }else if( g.argc==3 || g.argc==4 ){ |
| 2725 | const char *zName = g.argv[2]; |
| 2726 | int n = (int)strlen(zName); |
| 2727 | const Setting *pSetting = db_find_setting(zName, 1); |
| 2728 | if( pSetting==0 ){ |
| 2729 | fossil_fatal("no such setting: %s", zName); |
| 2730 | } |
| 2731 | if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){ |
| 2732 | fossil_fatal("cannot set 'manifest' globally"); |
| 2733 | } |
| 2734 | if( unsetFlag || g.argc==4 ){ |
| 2735 | int isManifest = fossil_strcmp(pSetting->name, "manifest")==0; |
| 2736 | if( pSetting[1].name && fossil_strncmp(pSetting[1].name, zName, n)==0 ){ |
| 2737 | Blob x; |
| 2738 | int i; |
| 2739 | blob_init(&x,0,0); |
| 2740 | for(i=0; pSetting[i].name; i++){ |
| 2741 | if( fossil_strncmp(pSetting[i].name,zName,n)!=0 ) break; |
| 2742 | blob_appendf(&x, " %s", pSetting[i].name); |
| 2743 | } |
| 2744 | fossil_fatal("ambiguous setting \"%s\" - might be:%s", |
| 2745 | zName, blob_str(&x)); |
| 2746 | } |
| 2747 | if( globalFlag && isManifest ){ |
| 2748 | fossil_fatal("cannot set 'manifest' globally"); |
| 2749 | } |
| 2750 | if( unsetFlag ){ |
| 2751 | db_unset(pSetting->name, globalFlag); |
| 2752 | }else{ |
| 2753 | db_set(pSetting->name, g.argv[3], globalFlag); |
| 2754 | } |
| 2755 | if( isManifest && g.localOpen ){ |
| 2756 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 2757 | } |
| 2758 | }else{ |
| 2759 | while( pSetting->name && fossil_strncmp(pSetting->name,zName,n)==0 ){ |
| 2760 | print_setting(pSetting); |
| 2761 | pSetting++; |
| 2762 | } |
| 2763 | } |
| 2764 | }else{ |
| 2765 | usage("?PROPERTY? ?VALUE? ?-global?"); |
| 2766 | } |
| 2767 | } |
| 2768 |
+7
-7
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -1354,11 +1354,11 @@ | ||
| 1354 | 1354 | |
| 1355 | 1355 | /* |
| 1356 | 1356 | ** WEBPAGE: setup_settings |
| 1357 | 1357 | */ |
| 1358 | 1358 | void setup_settings(void){ |
| 1359 | - struct stControlSettings const *pSet; | |
| 1359 | + Setting const *pSet; | |
| 1360 | 1360 | |
| 1361 | 1361 | login_check_credentials(); |
| 1362 | 1362 | if( !g.perm.Setup ){ |
| 1363 | 1363 | login_needed(); |
| 1364 | 1364 | } |
| @@ -1375,14 +1375,14 @@ | ||
| 1375 | 1375 | @ See the "fossil help setting" output below for further information on |
| 1376 | 1376 | @ the meaning of each setting.</p><hr /> |
| 1377 | 1377 | @ <form action="%s(g.zTop)/setup_settings" method="post"><div> |
| 1378 | 1378 | @ <table border="0"><tr><td valign="top"> |
| 1379 | 1379 | login_insert_csrf_secret(); |
| 1380 | - for(pSet=ctrlSettings; pSet->name!=0; pSet++){ | |
| 1380 | + for(pSet=aSetting; pSet->name!=0; pSet++){ | |
| 1381 | 1381 | if( pSet->width==0 ){ |
| 1382 | 1382 | int hasVersionableValue = pSet->versionable && |
| 1383 | - (db_get_do_versionable(pSet->name, NULL)!=0); | |
| 1383 | + (db_get_versioned(pSet->name, NULL)!=0); | |
| 1384 | 1384 | onoff_attribute(pSet->name, pSet->name, |
| 1385 | 1385 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1386 | 1386 | is_truth(pSet->def), hasVersionableValue); |
| 1387 | 1387 | if( pSet->versionable ){ |
| 1388 | 1388 | @ (v)<br /> |
| @@ -1391,31 +1391,31 @@ | ||
| 1391 | 1391 | } |
| 1392 | 1392 | } |
| 1393 | 1393 | } |
| 1394 | 1394 | @ <br /><input type="submit" name="submit" value="Apply Changes" /> |
| 1395 | 1395 | @ </td><td style="width:50px;"></td><td valign="top"> |
| 1396 | - for(pSet=ctrlSettings; pSet->name!=0; pSet++){ | |
| 1396 | + for(pSet=aSetting; pSet->name!=0; pSet++){ | |
| 1397 | 1397 | if( pSet->width!=0 && !pSet->versionable && !pSet->forceTextArea ){ |
| 1398 | 1398 | entry_attribute(pSet->name, /*pSet->width*/ 25, pSet->name, |
| 1399 | 1399 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1400 | 1400 | (char*)pSet->def, 0); |
| 1401 | 1401 | @ <br /> |
| 1402 | 1402 | } |
| 1403 | 1403 | } |
| 1404 | - for(pSet=ctrlSettings; pSet->name!=0; pSet++){ | |
| 1404 | + for(pSet=aSetting; pSet->name!=0; pSet++){ | |
| 1405 | 1405 | if( pSet->width!=0 && !pSet->versionable && pSet->forceTextArea ){ |
| 1406 | 1406 | @<b>%s(pSet->name)</b><br /> |
| 1407 | 1407 | textarea_attribute("", /*rows*/ 3, /*cols*/ 50, pSet->name, |
| 1408 | 1408 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1409 | 1409 | (char*)pSet->def, 0); |
| 1410 | 1410 | @ <br /> |
| 1411 | 1411 | } |
| 1412 | 1412 | } |
| 1413 | 1413 | @ </td><td style="width:50px;"></td><td valign="top"> |
| 1414 | - for(pSet=ctrlSettings; pSet->name!=0; pSet++){ | |
| 1414 | + for(pSet=aSetting; pSet->name!=0; pSet++){ | |
| 1415 | 1415 | if( pSet->width!=0 && pSet->versionable ){ |
| 1416 | - int hasVersionableValue = db_get_do_versionable(pSet->name, NULL)!=0; | |
| 1416 | + int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0; | |
| 1417 | 1417 | @<b>%s(pSet->name)</b> (v)<br /> |
| 1418 | 1418 | textarea_attribute("", /*rows*/ 3, /*cols*/ 20, pSet->name, |
| 1419 | 1419 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1420 | 1420 | (char*)pSet->def, hasVersionableValue); |
| 1421 | 1421 | @<br /> |
| 1422 | 1422 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1354,11 +1354,11 @@ | |
| 1354 | |
| 1355 | /* |
| 1356 | ** WEBPAGE: setup_settings |
| 1357 | */ |
| 1358 | void setup_settings(void){ |
| 1359 | struct stControlSettings const *pSet; |
| 1360 | |
| 1361 | login_check_credentials(); |
| 1362 | if( !g.perm.Setup ){ |
| 1363 | login_needed(); |
| 1364 | } |
| @@ -1375,14 +1375,14 @@ | |
| 1375 | @ See the "fossil help setting" output below for further information on |
| 1376 | @ the meaning of each setting.</p><hr /> |
| 1377 | @ <form action="%s(g.zTop)/setup_settings" method="post"><div> |
| 1378 | @ <table border="0"><tr><td valign="top"> |
| 1379 | login_insert_csrf_secret(); |
| 1380 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1381 | if( pSet->width==0 ){ |
| 1382 | int hasVersionableValue = pSet->versionable && |
| 1383 | (db_get_do_versionable(pSet->name, NULL)!=0); |
| 1384 | onoff_attribute(pSet->name, pSet->name, |
| 1385 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1386 | is_truth(pSet->def), hasVersionableValue); |
| 1387 | if( pSet->versionable ){ |
| 1388 | @ (v)<br /> |
| @@ -1391,31 +1391,31 @@ | |
| 1391 | } |
| 1392 | } |
| 1393 | } |
| 1394 | @ <br /><input type="submit" name="submit" value="Apply Changes" /> |
| 1395 | @ </td><td style="width:50px;"></td><td valign="top"> |
| 1396 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1397 | if( pSet->width!=0 && !pSet->versionable && !pSet->forceTextArea ){ |
| 1398 | entry_attribute(pSet->name, /*pSet->width*/ 25, pSet->name, |
| 1399 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1400 | (char*)pSet->def, 0); |
| 1401 | @ <br /> |
| 1402 | } |
| 1403 | } |
| 1404 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1405 | if( pSet->width!=0 && !pSet->versionable && pSet->forceTextArea ){ |
| 1406 | @<b>%s(pSet->name)</b><br /> |
| 1407 | textarea_attribute("", /*rows*/ 3, /*cols*/ 50, pSet->name, |
| 1408 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1409 | (char*)pSet->def, 0); |
| 1410 | @ <br /> |
| 1411 | } |
| 1412 | } |
| 1413 | @ </td><td style="width:50px;"></td><td valign="top"> |
| 1414 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1415 | if( pSet->width!=0 && pSet->versionable ){ |
| 1416 | int hasVersionableValue = db_get_do_versionable(pSet->name, NULL)!=0; |
| 1417 | @<b>%s(pSet->name)</b> (v)<br /> |
| 1418 | textarea_attribute("", /*rows*/ 3, /*cols*/ 20, pSet->name, |
| 1419 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1420 | (char*)pSet->def, hasVersionableValue); |
| 1421 | @<br /> |
| 1422 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1354,11 +1354,11 @@ | |
| 1354 | |
| 1355 | /* |
| 1356 | ** WEBPAGE: setup_settings |
| 1357 | */ |
| 1358 | void setup_settings(void){ |
| 1359 | Setting const *pSet; |
| 1360 | |
| 1361 | login_check_credentials(); |
| 1362 | if( !g.perm.Setup ){ |
| 1363 | login_needed(); |
| 1364 | } |
| @@ -1375,14 +1375,14 @@ | |
| 1375 | @ See the "fossil help setting" output below for further information on |
| 1376 | @ the meaning of each setting.</p><hr /> |
| 1377 | @ <form action="%s(g.zTop)/setup_settings" method="post"><div> |
| 1378 | @ <table border="0"><tr><td valign="top"> |
| 1379 | login_insert_csrf_secret(); |
| 1380 | for(pSet=aSetting; pSet->name!=0; pSet++){ |
| 1381 | if( pSet->width==0 ){ |
| 1382 | int hasVersionableValue = pSet->versionable && |
| 1383 | (db_get_versioned(pSet->name, NULL)!=0); |
| 1384 | onoff_attribute(pSet->name, pSet->name, |
| 1385 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1386 | is_truth(pSet->def), hasVersionableValue); |
| 1387 | if( pSet->versionable ){ |
| 1388 | @ (v)<br /> |
| @@ -1391,31 +1391,31 @@ | |
| 1391 | } |
| 1392 | } |
| 1393 | } |
| 1394 | @ <br /><input type="submit" name="submit" value="Apply Changes" /> |
| 1395 | @ </td><td style="width:50px;"></td><td valign="top"> |
| 1396 | for(pSet=aSetting; pSet->name!=0; pSet++){ |
| 1397 | if( pSet->width!=0 && !pSet->versionable && !pSet->forceTextArea ){ |
| 1398 | entry_attribute(pSet->name, /*pSet->width*/ 25, pSet->name, |
| 1399 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1400 | (char*)pSet->def, 0); |
| 1401 | @ <br /> |
| 1402 | } |
| 1403 | } |
| 1404 | for(pSet=aSetting; pSet->name!=0; pSet++){ |
| 1405 | if( pSet->width!=0 && !pSet->versionable && pSet->forceTextArea ){ |
| 1406 | @<b>%s(pSet->name)</b><br /> |
| 1407 | textarea_attribute("", /*rows*/ 3, /*cols*/ 50, pSet->name, |
| 1408 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1409 | (char*)pSet->def, 0); |
| 1410 | @ <br /> |
| 1411 | } |
| 1412 | } |
| 1413 | @ </td><td style="width:50px;"></td><td valign="top"> |
| 1414 | for(pSet=aSetting; pSet->name!=0; pSet++){ |
| 1415 | if( pSet->width!=0 && pSet->versionable ){ |
| 1416 | int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0; |
| 1417 | @<b>%s(pSet->name)</b> (v)<br /> |
| 1418 | textarea_attribute("", /*rows*/ 3, /*cols*/ 20, pSet->name, |
| 1419 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1420 | (char*)pSet->def, hasVersionableValue); |
| 1421 | @<br /> |
| 1422 |