pattern *pat_allocate (pattern *p, int sx, int sy) { pattern *ret; int y; assert (sy > 0); assert (sx > 0); if (p) ret = p; else ALLOC(pattern,ret,1); ret->sizeX = sx; ret->sizeY = sy; ALLOC (char *,ret->cell,sy); ALLOC (char,ret->cell [0],sy*sx); for (y = 1; y < sy; y++) ret->cell [y] = ret->cell [0] + y*sx; assert (ret->cell [sy-1] + sx == ret->cell [0] + sx*sy); pat_init (ret); return ret; }
void lab_init () { int g; assert (lab); for (g = 0; g < maxGen; g++) pat_init (&lab [g]); assert (lab [0].sizeX > 0 && lab [0].sizeY > 0); }
// меню работы с пациентами void pat_menu(hash_tab **pat, node *doc, refferal **ref_head, refferal **ref_tail) { bool end(false); // флаг остановки работы(возврат в главное меню) svector_pat search; // вектор найденных данных врачей int choice; // выбор критерия string answer; // ответ на вопрос д\н while(!end) { system("cls"); cout<<"======= Работа с клиентурой =======\n" <<" 1. Регистрация нового больного\n" <<" 2. Удаление данных о больном\n" <<" 3. Список всех больных\n" <<" 4. Удаление данных о всех больных\n" <<" 5. Поиск\n" <<" 0. Назад в меню\n" <<"===================================\n" <<"\nВведите команду: "; choice = input_control(5, 0); if ((choice >= 2 && choice <= 5) && !(have_pat(*pat))) { cout << "\nБД пациентов пуста! Пункты #2 - #5 недоступны.\n"; system("pause"); choice = -1; } switch(choice) { case 1: cout<<" Регистрация больного:\n"; add_to_tab(*pat, pat_init()); system("pause"); break; case 2: del_pat(*pat, ref_head, ref_tail); system("pause"); break; case 3: pat_out(*pat); system("pause"); break; case 4: cout << " Удалить данные о всех больных? \n(Также удалится вся информация о выданных направлениях на прием) д/н "; answer_control(answer); if (answer[0] == 'д') { htab_init(*pat); del_list(ref_head, ref_tail); cout << " Записи удалены.\n"; system("pause"); } else { cout << " Записи НЕ удалены.\n"; system("pause"); } break; case 5: pat_search_menu(search, *pat, doc, *ref_head); system("pause"); break; case 0: end = true; break; default: break; } search.clear(); search.shrink_to_fit(); } }
void pat_from_string (pattern *pat, const char *str) // str contains exactly one pattern. load it centered into *pat // pat must be large enough to hold the pattern. { int x = 1, y = 1, count = 0, maxX = 1; bool isrle = false; char dCell, lCell, newLine, endPat; const char *cp = str; assert (pat->sizeX >= temp->sizeX); assert (pat->sizeY >= temp->sizeY); pat_init (temp); memset (temp->cell [0], DEAD, temp->sizeY * temp->sizeX); // we don't know the width of the pattern before we have loaded it ... /* Try to find out which format the str is in. Supported formats are: - '.' means DEAD, '*' means ALIVE, line feeds begin a new line in the pattern. Other WS is *ignored* (similar to standard .life files) - rle (b meeans DEAD, o means ALIVE, pattern lines are ended by $, bo$ can be prefix by a repeat count, ! ends pattern) WS is ignored - gencols output format. '.' means DEAD, '*' means alive, '!' begins a new pattern line, anything else terminates pattern. For convenience we are very tollerant: - Lines beginning with # are ignored (Comments) - emtpy lines (or lines consisting of WS) at the start of the pattern are ignored - lines beginning with something like "x = " are ignored (but indicate rle mode) Mode is determined heuristically: - Is there a line starting with "x ="? -> RLE mode - Look at the first "non garbage" char: is it a number or o, b? -> RLE mode - non RLE mode: does pattern contain a '!'? -> gencols mode */ while (*cp) { if (*cp == '#') { while (*cp && *cp != '\n') cp++; } else if (*cp == 'x') { isrle = true; dCell = 'b'; lCell = 'o'; newLine = '$'; endPat = '!'; while (*cp && *cp != '\n') cp++; } else if (!isspace (*cp)) break; if (*cp) cp++; } // Here: we are at the first non garbage char if (!isrle) { if (*cp == '.' || *cp == '*') { dCell = '.'; lCell = '*'; if (strchr (cp, '!')) { newLine = '!'; endPat = ' '; } else { newLine = '\n'; endPat = '\0'; } } else { isrle = true; dCell = 'b'; lCell = 'o'; newLine = '$'; endPat = '!'; } } // now for the pattern itself ... while (*cp) { if (isrle && isdigit (*cp)) count = count*10 + *cp - '0'; else if (*cp == dCell || *cp == lCell) { if (!count) count = 1; if (x + count >= temp->sizeX-1) { fprintf (stderr, "Pattern too wide!\n"); exit (1); } for (; count > 0; count--) temp->cell [y][x++] = (*cp == lCell) ? ALIVE : DEAD; if (x > maxX) maxX = x; } else if (*cp == newLine) { y += count ? count : 1; if (y >= temp->sizeY-1) { fprintf (stderr, "Pattern too high!\n"); exit (1); } x = 1; count = 0; } else if (endPat == ' ' || !isspace (*cp)) break; cp++; } temp->top = 1; temp->bottom = y; temp->left = 1; temp->right = maxX-1; // OK. Loading to a temporary space is done. Now we just have to keep this thing. // Draw temp centered in lab [0], discarding old content. pat_copy (pat, (pat->sizeX-W(temp))/2, (pat->sizeY-H(temp))/2, temp); pat_shrink_bbox (pat); }