? category.patch ? depends.patch Index: choose.cc =================================================================== RCS file: /cvs/src/src/winsup/cinstall/choose.cc,v retrieving revision 2.23 diff -u -p -r2.23 choose.cc --- choose.cc 2001/05/27 19:43:52 2.23 +++ choose.cc 2001/06/13 06:31:13 @@ -87,14 +87,19 @@ headers[] = { #define NEW_COL 1 { "Src?", 4, 0, 0 }, #define SRC_COL 2 + { "Category", 8, 0, 0 }, +#define CATEGORY_COL 3 { "Package", 7, 0, 0 }, -#define PACKAGE_COL 3 +#define PACKAGE_COL 4 { 0, 0, 0, 0 } }; #define NUM_COLUMNS (sizeof (headers) / (sizeof (headers[0])) - 1) int *package_indexes, nindexes; +static int add_required(int p); +static void set_full_list (HWND h, int isfull); + struct ExtraPackageInfo { char *installed_file; /* filename of previous "install" file */ @@ -188,6 +193,9 @@ paint (HWND hwnd) BitBlt (hdc, x + headers[SRC_COL].x, by, 11, 11, bitmap_dc, 0, 0, SRCCOPY); + if (package[i].category) + TextOut (hdc, x + headers[CATEGORY_COL].x, r, package[i].category, strlen (package[i].category)); + if (package[i].name) TextOut (hdc, x + headers[PACKAGE_COL].x, r, package[i].name, strlen (package[i].name)); } @@ -278,6 +286,7 @@ static LRESULT CALLBACK list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode) { int r; + int refresh; if (nindexes == 0) return 0; @@ -305,6 +314,8 @@ list_click (HWND hwnd, BOOL dblclk, int extra[p].pick++; if (extra[p].chooser[extra[p].pick].caption == 0) extra[p].pick = 0; + /* Add any packages that are needed by this package */ + refresh = add_required(p); } if (x >= headers[SRC_COL].x - HMARGIN/2 && x <= headers[SRC_COL + 1].x - HMARGIN/2) @@ -312,13 +323,34 @@ list_click (HWND hwnd, BOOL dblclk, int if (extra[p].chooser[extra[p].pick].src_avail) package[p].srcaction ^= (SRCACTION_NO^SRCACTION_YES); } + + if (refresh) + { + RECT r; + GetClientRect (lv, &r); + SCROLLINFO si; + memset (&si, 0, sizeof (si)); + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + si.nMin = 0; + + si.nMax = nindexes * row_height; + si.nPage = r.bottom - header_height; + SetScrollInfo (lv, SB_VERT, &si, TRUE); + + scroll_ulc_x = scroll_ulc_y = 0; - RECT rect; - rect.left = headers[NEW_COL].x - scroll_ulc_x; - rect.right = headers[SRC_COL + 1].x - scroll_ulc_x; - rect.top = header_height + r * row_height - scroll_ulc_y; - rect.bottom = rect.top + row_height; - InvalidateRect (hwnd, &rect, TRUE); + InvalidateRect (lv, &r, TRUE); + } + else + { + RECT rect; + rect.left = headers[NEW_COL].x - scroll_ulc_x; + rect.right = headers[SRC_COL + 1].x - scroll_ulc_x; + rect.top = header_height + r * row_height - scroll_ulc_y; + rect.bottom = rect.top + row_height; + InvalidateRect (hwnd, &rect, TRUE); + } } static LRESULT CALLBACK @@ -432,7 +464,7 @@ set_existence () } static int -best_trust (int p, int trust) +best_trust (int p, int trust, int ignore_categories) { int t; t = trust; @@ -440,12 +472,97 @@ best_trust (int p, int trust) ((package[p].info[t].install_exists && source == IDC_SOURCE_CWD) || (package[p].info[t].install_exists == 0 && source == IDC_SOURCE_DOWNLOAD) || source == IDC_SOURCE_NETINST)) - return t; + { + if (!ignore_categories && package[p].category + && strcasecmp(package[p].category, "Required")) + return TRUST_NONE; + else + return t; + } if (extra[p].installed_file && extra[p].installed_ver == package[p].info[t].version) return TRUST_KEEP; return TRUST_NONE; } +static int +find_package (const char *name) +{ + int i; + for (i=0; i < npackages; i++) + { + if (!strcasecmp(name, package[i].name)) + return i; + } + return -1; +} + +static int +add_required (int p) +{ + Dependency *dp; + int i; + int c; + int changed = 0; + dp = package[p].required; + switch (extra[p].chooser[extra[p].pick].trust) + { + case TRUST_UNINSTALL: + case TRUST_NONE: + case TRUST_SRC_ONLY: + return 0; + default: + break; + } + while (dp) + { + if ((i = find_package(dp->package)) == -1) + { + dp=dp->next; + continue; + } + switch (extra[i].chooser[extra[i].pick].trust) + { + case TRUST_PREV: + case TRUST_CURR: + case TRUST_TEST: + case TRUST_REDO: + case TRUST_KEEP: + break; + + case TRUST_UNINSTALL: + package[i].trust = TRUST_KEEP; + break; + + case TRUST_NONE: + package_indexes[nindexes++] = i; + case TRUST_SRC_ONLY: + if (! extra[i].which_is_installed >= 0) + { + /* prefer the current version, then prev, then experimental */ + package[i].trust = best_trust (i, TRUST_CURR, 1); + if (package[i].trust != TRUST_CURR) + { + package[i].trust = best_trust (i, TRUST_PREV, 1); + if (package[i].trust != TRUST_PREV) + package[i].trust = best_trust (i, TRUST_TEST, 1); + } + } + else + package[i].trust = TRUST_KEEP; + changed++; + break; + + default: + break; + } + for (c = 0; c < extra[i].npick; c++) + if (package[i].trust == extra[i].chooser[c].trust) + extra[i].pick = c; + dp=dp->next; + } + return changed; +} + static void default_trust (HWND h, int trust) { @@ -453,7 +570,7 @@ default_trust (HWND h, int trust) for (i = 0; i < npackages; i++) { - t = best_trust (i, trust); + t = best_trust (i, trust, 0); extra[i].pick = 1; package[i].trust = t; for (c = 0; c < extra[i].npick; c++) @@ -640,6 +757,7 @@ create_listview (HWND dlg, RECT *r) for (t = 0; t < NTRUST; t++) note_width (dc, package[i].info[t].version, NEW_COL_SIZE_SLOP, NEW_COL); note_width (dc, package[i].name, 0, PACKAGE_COL); + note_width (dc, package[i].category, 0, CATEGORY_COL); note_width (dc, package[i].sdesc, 0, PACKAGE_COL); } note_width (dc, "keep", NEW_COL_SIZE_SLOP, NEW_COL); @@ -648,10 +766,13 @@ create_listview (HWND dlg, RECT *r) headers[CURRENT_COL].x = HMARGIN/2; headers[NEW_COL].x = headers[CURRENT_COL].x + headers[CURRENT_COL].width + NEW_COL_SIZE_SLOP + HMARGIN; headers[SRC_COL].x = headers[NEW_COL].x + headers[NEW_COL].width + HMARGIN; - headers[PACKAGE_COL].x = headers[SRC_COL].x + headers[SRC_COL].width + HMARGIN; + headers[CATEGORY_COL].x = headers[SRC_COL].x + headers[SRC_COL].width + HMARGIN; + headers[PACKAGE_COL].x = headers[CATEGORY_COL].x + headers[CATEGORY_COL].width + HMARGIN; default_trust (lv, TRUST_CURR); set_full_list (lv, full_list); + for (i = 0; i < npackages; i++) + add_required(i); static int ta[] = { IDC_CHOOSE_CURR, 0 }; rbset (dlg, ta, IDC_CHOOSE_CURR); @@ -661,18 +782,25 @@ create_listview (HWND dlg, RECT *r) static BOOL dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) { + int i; switch (id) { case IDC_CHOOSE_PREV: default_trust (lv, TRUST_PREV); + for (i = 0; i < npackages; i++) + add_required(i); set_full_list (lv, full_list); break; case IDC_CHOOSE_CURR: default_trust (lv, TRUST_CURR); + for (i = 0; i < npackages; i++) + add_required(i); set_full_list (lv, full_list); break; case IDC_CHOOSE_EXP: default_trust (lv, TRUST_TEST); + for (i = 0; i < npackages; i++) + add_required(i); set_full_list (lv, full_list); break; case IDC_CHOOSE_FULLPART: @@ -1096,9 +1224,11 @@ do_choose (HINSTANCE h) : "unknown"); const char *partial_list = ((extra[i].in_partial_list == 1) ? "yes" : "no"); - log (LOG_BABBLE, "[%s] action=%s trust=%s installed=%s partial_list=%s src?=%s", + log (LOG_BABBLE, "[%s] action=%s trust=%s installed=%s partial_list=%s src?=%s" + " category=%s", package[i].name, action, trust, installed, - partial_list, package[i].srcaction == SRCACTION_NO ? "no" : "yes"); + partial_list, package[i].srcaction == SRCACTION_NO ? "no" : "yes", + package[i].category); for (int t = 0; t < NTRUST; t++) { if (package[i].info[t].install) Index: ini.h =================================================================== RCS file: /cvs/src/src/winsup/cinstall/ini.h,v retrieving revision 2.7 diff -u -p -r2.7 ini.h --- ini.h 2001/05/27 07:05:09 2.7 +++ ini.h 2001/06/13 06:31:13 @@ -52,14 +52,23 @@ typedef struct int partial_list_display;/* display this version in partial list */ } Info; /* +1 for TRUST_UNKNOWN */ +typedef struct Dependency_t Dependency; +struct Dependency_t +{ + Dependency *next; /* the next package in this dependency list */ + char *package; /* the name of the package that is depended on */ +}; /* Dependencies can be used for recommended/required/related... */ + typedef struct { char *name; /* package name, like "cygwin" */ char *sdesc; /* short description (replaces "name" if provided) */ char *ldesc; /* long description (multi-line) */ + char *category; /* the category the package belongs to, like "required" or "XFree86" */ int action; /* ACTION_* - only NEW and UPGRADE get installed */ int srcaction;/* SRCACTION_ */ int trust; /* TRUST_* (selects among info[] below) */ + Dependency *required; /* the packages required for this package to work */ Info info[NTRUST + 1]; /* +1 for TRUST_UNKNOWN */ } Package; @@ -73,6 +82,7 @@ extern "C" { Package *new_package (char *name); void ini_init (char *string); +void new_requirement(Package *package, char *dependson); #define pi (package[i].info[package[i].trust]) Index: inilex.l =================================================================== RCS file: /cvs/src/src/winsup/cinstall/inilex.l,v retrieving revision 2.2 diff -u -p -r2.2 inilex.l --- inilex.l 2001/05/30 01:38:41 2.2 +++ inilex.l 2001/06/13 06:31:13 @@ -47,6 +47,8 @@ STR [a-zA-Z0-9_./+-]+ "setup-timestamp:" return SETUP_TIMESTAMP; "setup-version:" return SETUP_VERSION; "version:" return VERSION; +"category:" return CATEGORY; +"requires:" return REQUIRES; "install:" return INSTALL; "source:" return SOURCE; "sdesc:" return SDESC; Index: iniparse.y =================================================================== RCS file: /cvs/src/src/winsup/cinstall/iniparse.y,v retrieving revision 2.6 diff -u -p -r2.6 iniparse.y --- iniparse.y 2001/05/27 19:43:52 2.6 +++ iniparse.y 2001/06/13 06:31:13 @@ -43,7 +43,7 @@ extern int yylineno; %} %token STRING -%token SETUP_TIMESTAMP SETUP_VERSION VERSION INSTALL SOURCE SDESC LDESC +%token SETUP_TIMESTAMP SETUP_VERSION VERSION INSTALL SOURCE SDESC LDESC CATEGORY REQUIRES %token T_PREV T_CURR T_TEST T_UNKNOWN %% @@ -81,6 +81,7 @@ lines simple_line : VERSION STRING { cpt->version = $2; } + | CATEGORY STRING { cp->category = $2; } | SDESC STRING { cp->sdesc = $2; } | LDESC STRING { cp->ldesc = $2; } | INSTALL STRING STRING { cpt->install = $2; @@ -98,6 +99,7 @@ simple_line | T_CURR { trust = TRUST_CURR; } | T_TEST { trust = TRUST_TEST; } | T_UNKNOWN { trust = TRUST_UNKNOWN; } + | REQUIRES requires | /* empty */ | error '\n' { yylineno --; yyerror ("unrecognized line in package %s (do you have the latest setup?)", cp->name); @@ -105,6 +107,10 @@ simple_line } ; +requires + : STRING { new_requirement(cp, $1); } requires + | STRING { new_requirement(cp, $1); } + ; %% Package *package = 0; @@ -133,4 +139,16 @@ new_package (char *name) trust = TRUST_CURR; return cp; +} + +void +new_requirement(Package *package, char *dependson) +{ + Dependency *dp; + if (!dependson) + return; + dp = (Dependency *) malloc (sizeof (Dependency)); + dp->next = cp->required; + dp->package = dependson; + cp->required = dp; }