/* * Delete forward. This is real easy, because the basic delete routine does * all of the work. Watches for negative arguments, and does the right thing. * If any argument is present, it kills rather than deletes, to prevent loss * of text if typed with a big argument. Normally bound to "C-D". */ int forwdel(int f, int n) { if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (backdel(f, -n)); if(TERM_OPTIMIZE && (curwp->w_dotp != curwp->w_bufp->b_linep)){ int l; if(worthit(&l) && curwp->w_doto == llength(curwp->w_dotp)) scrollup(curwp, l+1, 1); } if (f != FALSE) { /* Really a kill. */ if ((lastflag&CFKILL) == 0) kdelete(); thisflag |= CFKILL; } return (ldelete((long) n, f ? kinsert : NULL)); }
void test4 () { int lck; int pid1; int pid2; kprintf("\nTest 4: return DELETED if lock deleted while waiting\n"); lck = lcreate (); assert (lck != SYSERR,"Test 4 FAILED\n"); pid1 = create(writer4, 2000, 20, "writer4", 2, "writer", lck); pid2 = create(reader4, 2000, 20, "reader4", 2, "reader", lck); resume(pid1); sleep (1); resume(pid2); sleep(1); ldelete (lck); sleep (5); kill(pid1); kill(pid2); }
/* * Kill the region. Ask "getregion" * to figure out the bounds of the region. * Move "." to the start, and kill the characters. * Bound to "C-W". */ int killregion(int f, int n) { REGION region; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (getregion(®ion, curwp->w_markp, curwp->w_marko) != TRUE){ return (killtext(f, n)); }else { mlerase(); } if ((lastflag&CFKILL) == 0) /* This is a kill type */ kdelete(); /* command, so do magic */ thisflag |= CFKILL; /* kill buffer stuff. */ curwp->w_dotp = region.r_linep; curwp->w_doto = region.r_offset; curwp->w_markp = NULL; #ifdef _WINDOWS mswin_allowcopycut(NULL); #endif if(ldelete(region.r_size, kinsert)){ if(curwp->w_dotp == curwp->w_linep && curwp->w_dotp == curbp->b_linep){ curwp->w_force = 0; /* Center dot. */ curwp->w_flag |= WFFORCE; } return(TRUE); } return (FALSE); }
void main() { int n,num,num1,flag=0; while(1) { clrscr(); printf("\n\t\t****** DOUBLY LINKED LIST OPERATION ******\n"); printf("\t\t......______________________________......\n"); printf("\nWELCOME,WHAT YOU WANT TO DO ?::"); printf("\n_____________________________\n\n"); printf("\nINSERTION --PRESS 1\n"); printf("\nDELETION --PRESS 2\n"); printf("\nSEARCH --PRESS 3\n"); printf("\nCOUNT --PRESS 4\n"); printf("\nDISPLAY(F) --PRESS 5\n"); printf("\nDISPLAY(R) --PRESS 6\n"); printf("\nEXIT --PRESS 7\n"); printf("\n\nENTER YOUR CHOICE::\n"); scanf("%d",&n); switch(n) { case 1: while(1) { flag=0; clrscr(); printf("INSERT A NODE ::\n"); printf("\t\tAT FIRST -PRESS 1.\n"); printf("\t\tAFTER A NODE -PRESS 2.\n"); printf("\t\tBEFORE A NODE -PRESS 3.\n"); printf("\t\tAT LAST -PRESS 4.\n"); printf("\t\tEXIT FROM HERE-PRESS 5.\n"); printf("\n\nENTER YOUR CHOICE::\n"); scanf("%d",&n); switch(n) { case 1: printf("\nENTER A ELEMENT FOR INSERTION\n"); scanf("%d",&num); finsert(num); printf("\n%d IS INSERT AT FIRST PROPERLY\n",num); break; case 2: printf("\nENTER A ELEMENT FOR INSERTION\n"); scanf("%d",&num); printf("AFTER WHICH ELEMENT YOU WANT TO INSERT\n"); scanf("%d",&num1); ainsert(num,num1); break; case 3: printf("ENTER A ELEMENT FOR INSERTION\n"); scanf("%d",&num); printf("BEFORE WHICH ELEMENT YOU WANT TO INSERT\n"); scanf("%d",&num1); binsert(num,num1); break; case 4: printf("ENTER AN ELEMENT FOR INSERT IN LAST\n"); scanf("%d",&num); linsert(num); break; case 5: printf("\nTHANK YOU FOR USING INSERT OPERETION\n"); flag=1; break; } getch(); if(flag==1) break; } break; case 2: while(1) { flag=0; clrscr(); printf("DELETE A NODE ::\n"); printf("\t\tAT FIRST -PRESS 1.\n"); printf("\t\tAFTER A NODE -PRESS 2.\n"); printf("\t\tBEFORE A NODE -PRESS 3.\n"); printf("\t\tAT LAST -PRESS 4.\n"); printf("\t\tEXACT A NODE -PRESS 5.\n"); printf("\t\tEXIT FROM HERE-PRESS 6.\n"); printf("\n\nENTER YOUR CHOICE::\n"); scanf("%d",&n); switch(n) { case 1: fdelete(); break; case 2: printf("\nENTER AFTER WHICH ELEMENT YOU WANT TO DELETE A NODE\n"); scanf("%d",&num); adelete(num); break; case 3: printf("\nENTER BEFORE WHICH ELEMENT YOU WANT TO DELETE A NODE\n"); scanf("%d",&num); bdelete(num); break; case 4: ldelete(); break; case 5: printf("WHICH ELEMENT CONTAIN NODE YOU WANT TO DELETE:\n"); scanf("%d",&num); edelete(num); break; case 6: printf("THANK YOU FOR USING DELETE OPERETION"); flag=1; break; } getch(); if(flag==1) break; } break; case 3: printf("WHICH ELEMENT YOU WANT TO SEARCH ?"); scanf("%d",&num); search(num); break; case 4: num=count(); printf("AT PRESENT LINKLIST CONTAIN %d NODES\n",num); break; case 5: fdisplay(); break; case 6: rdisplay(); break; case 7: printf("\n\nTHANK YOU FOR USING THIS PROGRAM\n"); getch(); exit(0); } getch(); } }
/* ARGSUSED */ int fillpara(int f, int n) { int c; /* current char during scan */ int wordlen; /* length of current word */ int clength; /* position on line during fill */ int i; /* index during word copy */ int eopflag; /* Are we at the End-Of-Paragraph? */ int firstflag; /* first word? (needs no space) */ int newlength; /* tentative new line length */ int eolflag; /* was at end of line */ int retval; /* return value */ struct line *eopline; /* pointer to line just past EOP */ char wbuf[MAXWORD]; /* buffer for current word */ if (n == 0) return (TRUE); undo_boundary_enable(FFRAND, 0); /* record the pointer to the line just past the EOP */ (void)gotoeop(FFRAND, 1); if (curwp->w_doto != 0) { /* paragraph ends at end of buffer */ (void)lnewline(); eopline = lforw(curwp->w_dotp); } else eopline = curwp->w_dotp; /* and back top the beginning of the paragraph */ (void)gotobop(FFRAND, 1); /* initialize various info */ while (inword() == 0 && forwchar(FFRAND, 1)); clength = curwp->w_doto; wordlen = 0; /* scan through lines, filling words */ firstflag = TRUE; eopflag = FALSE; while (!eopflag) { /* get the next character in the paragraph */ if ((eolflag = (curwp->w_doto == llength(curwp->w_dotp)))) { c = ' '; if (lforw(curwp->w_dotp) == eopline) eopflag = TRUE; } else c = lgetc(curwp->w_dotp, curwp->w_doto); /* and then delete it */ if (ldelete((RSIZE) 1, KNONE) == FALSE && !eopflag) { retval = FALSE; goto cleanup; } /* if not a separator, just add it in */ if (c != ' ' && c != '\t') { if (wordlen < MAXWORD - 1) wbuf[wordlen++] = c; else { /* * You lose chars beyond MAXWORD if the word * is too long. I'm too lazy to fix it now; it * just silently truncated the word before, * so I get to feel smug. */ ewprintf("Word too long!"); } } else if (wordlen) { /* calculate tentative new length with word added */ newlength = clength + 1 + wordlen; /* * if at end of line or at doublespace and previous * character was one of '.','?','!' doublespace here. * behave the same way if a ')' is preceded by a * [.?!] and followed by a doublespace. */ if (dblspace && (!eopflag && ((eolflag || curwp->w_doto == llength(curwp->w_dotp) || (c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ' || c == '\t') && (ISEOSP(wbuf[wordlen - 1]) || (wbuf[wordlen - 1] == ')' && wordlen >= 2 && ISEOSP(wbuf[wordlen - 2])))) && wordlen < MAXWORD - 1)) wbuf[wordlen++] = ' '; /* at a word break with a word waiting */ if (newlength <= fillcol) { /* add word to current line */ if (!firstflag) { (void)linsert(1, ' '); ++clength; } firstflag = FALSE; } else { if (curwp->w_doto > 0 && lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') { curwp->w_doto -= 1; (void)ldelete((RSIZE) 1, KNONE); } /* start a new line */ (void)lnewline(); clength = 0; } /* and add the word in in either case */ for (i = 0; i < wordlen; i++) { (void)linsert(1, wbuf[i]); ++clength; } wordlen = 0; } } /* and add a last newline for the end of our new paragraph */ (void)lnewline(); /* * We really should wind up where we started, (which is hard to keep * track of) but I think the end of the last line is better than the * beginning of the blank line. */ (void)backchar(FFRAND, 1); retval = TRUE; cleanup: undo_boundary_enable(FFRAND, 1); return (retval); }
static void clock_free() { assert(lcount(_clocks)==0); ldelete(_clocks); }
PASCAL NEAR enterfold(f, n) { BUFFER *bp; /* buffer being entered */ WINDOW *wp; /* windows to fix up pointers in as well */ int wscnt; /* whitespace count */ LINE *lp; /* line loop value */ int chgflag; /* record previous value of change flag */ int vewflag; /* record previous value of view flag */ int i; /* find the proper buffer */ bp = curwp->w_bufp; if (curwp->w_dotp->l_type == LSOFOLD) { /* remove indentation and stack previous buffer values */ if (bp->b_nfolds < NFOLDS) { /* remove indentation from fold */ /* 1st find out how much to remove */ wscnt = loffset(curwp->w_dotp); /* and then remove them */ if (wscnt > 0) { /* record if buffer changed yet since this will */ chgflag = bp->b_flag & BFCHG; vewflag = bp->b_mode & MDVIEW; /* no good in view mode */ bp->b_mode &= ~MDVIEW; lp = curwp->w_dotp; /* save old value */ curwp->w_dotp = lp->l_fp; while (curwp->w_dotp != lp->l_foldp) { curwp->w_doto = 0; curwp->w_dotp->l_omargin = curwp->w_dotp->l_lmargin; curwp->w_dotp->l_lmargin = 0; /* safety 1st - but shouldn't be required */ if (loffset(curwp->w_dotp) >= wscnt) ldelete((long)wscnt, FALSE, FALSE, FALSE); if (curwp->w_dotp->l_type == LSOFOLD) curwp->w_dotp = curwp->w_dotp->l_foldp; curwp->w_dotp = curwp->w_dotp->l_fp; } curwp->w_dotp = lp; /* reset change flag? */ if (!chgflag) bp->b_flag &= ~BFCHG; if (vewflag) /* reset view flag */ bp->b_mode |= MDVIEW; } else { /* just set old margin value to zero - or problem with exit */ lp = curwp->w_dotp; /* save old value */ curwp->w_dotp = lp->l_fp; while (curwp->w_dotp != lp->l_foldp) { curwp->w_dotp->l_omargin = 0; curwp->w_dotp->l_lmargin = 0; if (curwp->w_dotp->l_type == LSOFOLD) curwp->w_dotp = curwp->w_dotp->l_foldp; curwp->w_dotp = curwp->w_dotp->l_fp; } curwp->w_dotp = lp; } /* stack values */ bp->b_folds[bp->b_nfolds].f_topline = bp->b_linep->l_fp; bp->b_folds[bp->b_nfolds].f_botline = curwp->w_dotp->l_foldp; bp->b_linep->l_fp = curwp->w_dotp->l_fp; curwp->w_dotp->l_fp->l_bp = bp->b_linep; curwp->w_dotp->l_fp = (LINE *)NULL; bp->b_folds[bp->b_nfolds].f_botline->l_bp->l_fp = bp->b_linep; bp->b_linep->l_bp->l_fp = (LINE *)NULL; bp->b_linep->l_bp = bp->b_folds[bp->b_nfolds].f_botline->l_bp; /* Move cursor to the beginning of next line */ curwp->w_dotp = bp->b_linep->l_fp; curwp->w_doto = 0; /* increment fold count */ bp->b_nfolds++; /* let all the proper windows be updated */ wp = wheadp; while (wp) { if (wp->w_bufp == bp) { wp->w_flag |= (WFHARD|WFMODE|WFFORCE); /* have to enter in all windows */ /* since buffer only valid for fold */ wp->w_linep = bp->b_linep->l_fp; wp->w_dotp = wp->w_linep; wp->w_doto = 0; /* clear out marks */ for (i = 0; i < NMARKS; i++) wp->w_markp[i] = (LINE *)NULL; } wp = wp->w_wndp; } mlwrite(TEXT220); /* "[Fold Entered]" */ if (bp->b_mode & MDASAVE) mlwrite(TEXT238); /* "%%Cannot AUTOSAVE when within a fold" */ return(TRUE); } else { mlwrite(TEXT227); /* "%% Folds too deep" */ return(FALSE); } } else { mlwrite(TEXT225); /* "%%Line is not a fold" */ return(FALSE); } }
/* * The region we're filling is the region from dot to mark. * We cut out that region and then put it back in filled. * The cut out part is saved in the ldelete call and the * reinstalled region is noted in addedregion, so that yank() * can delete it and restore the saved part. */ int fillregion(UCS *qstr, REGION *addedregion) { long c, sz, last_char = 0; int i, j, qlen, same_word, spaces, word_len, word_ind, line_len, ww; int starts_midline = 0; int ends_midline = 0; int offset_into_start; LINE *line_before_start, *lp; UCS line_last, word[NSTRING]; REGION region; /* if region starts midline insert a newline */ if(curwp->w_doto > 0 && curwp->w_doto < llength(curwp->w_dotp)) starts_midline++; /* if region ends midline insert a newline at end */ if(curwp->w_marko > 0 && curwp->w_marko < llength(curwp->w_markp)) ends_midline++; /* cut the paragraph into our fill buffer */ fdelete(); if(!getregion(®ion, curwp->w_markp, curwp->w_marko)) return(FALSE); if(!ldelete(region.r_size, finsert)) return(FALSE); line_before_start = lback(curwp->w_dotp); offset_into_start = curwp->w_doto; if(starts_midline) lnewline(); /* Now insert it back wrapped */ spaces = word_len = word_ind = line_len = same_word = 0; qlen = qstr ? ucs4_strlen(qstr) : 0; /* Beginning with leading quoting... */ if(qstr){ i = 0; while(qstr[i]){ ww = wcellwidth(qstr[i]); line_len += (ww >= 0 ? ww : 1); linsert(1, qstr[i++]); } line_last = ' '; /* no word-flush space! */ } /* remove first leading quotes if any */ if(starts_midline) i = 0; else for(i = qlen; (c = fremove(i)) == ' ' || c == TAB; i++){ linsert(1, line_last = (UCS) c); line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1); } /* then digest the rest... */ while((c = fremove(i++)) >= 0){ last_char = c; switch(c){ case '\n' : /* skip next quote string */ j = 0; while(j < qlen && ((c = fremove(i+j)) == qstr[j] || c == ' ')) j++; i += j; if(!spaces) spaces++; same_word = 0; break; case TAB : case ' ' : spaces++; same_word = 0; break; default : if(spaces){ /* flush word? */ if((line_len - qlen > 0) && line_len + word_len + 1 > fillcol && ((ucs4_isspace(line_last)) || (linsert(1, ' '))) && (line_len = fpnewline(qstr))) line_last = ' '; /* no word-flush space! */ if(word_len){ /* word to write? */ if(line_len && !ucs4_isspace(line_last)){ linsert(1, ' '); /* need padding? */ line_len++; } line_len += word_len; for(j = 0; j < word_ind; j++) linsert(1, line_last = word[j]); if(spaces > 1 && strchr(".?!:;\")", line_last)){ linsert(2, line_last = ' '); line_len += 2; } word_len = word_ind = 0; } spaces = 0; } if(word_ind + 1 >= NSTRING){ /* Magic! Fake that we output a wrapped word */ if((line_len - qlen > 0) && !same_word++){ if(!ucs4_isspace(line_last)) linsert(1, ' '); line_len = fpnewline(qstr); } line_len += word_len; for(j = 0; j < word_ind; j++) linsert(1, word[j]); word_len = word_ind = 0; line_last = ' '; } word[word_ind++] = (UCS) c; ww = wcellwidth((UCS) c); word_len += (ww >= 0 ? ww : 1); break; } } if(word_len){ if((line_len - qlen > 0) && (line_len + word_len + 1 > fillcol)){ if(!ucs4_isspace(line_last)) linsert(1, ' '); (void) fpnewline(qstr); } else if(line_len && !ucs4_isspace(line_last)) linsert(1, ' '); for(j = 0; j < word_ind; j++) linsert(1, word[j]); } if(last_char == '\n') lnewline(); if(ends_midline) (void) fpnewline(qstr); /* * Calculate the size of the region that was added. */ swapmark(0,1); /* mark current location after adds */ addedregion->r_linep = lforw(line_before_start); addedregion->r_offset = offset_into_start; lp = addedregion->r_linep; sz = llength(lp) - addedregion->r_offset; if(lforw(lp) != curwp->w_markp->l_fp){ lp = lforw(lp); while(lp != curwp->w_markp->l_fp){ sz += llength(lp) + 1; lp = lforw(lp); } } sz -= llength(curwp->w_markp) - curwp->w_marko; addedregion->r_size = sz; swapmark(0,1); if(ends_midline){ /* * We want to back up to the end of the original * region instead of being here after the added newline. */ curwp->w_doto = 0; backchar(0, 1); unmarkbuffer(); markregion(1); } return(TRUE); }
static void lcmd(int type) { switch(curChar) { case '0': gotobegin(); return; case '$': gotoend(); return; case 'A': gotoend(); putchar(*curPos++); lMode = INSERT; return; case 'a': if (curPos != startOfLine) putchar(*curPos++); lMode = INSERT; return; case 'i': lMode = INSERT; return; case 'D': delete_to_end(); return; case 'd': delete_something(); return; case 'c': delete_something(); lMode = INSERT; return; case 'x': ldelete(); return; case ' ': case 'l': if (curPos < startOfLine+lineLen-1) { putchar(*curPos); curPos++; } return; case '\b': case 'h': if (curPos > startOfLine) { putchar('\b'); curPos--; } return; case 'r': lMode = EDIT1; return; case 'R': lMode = EDIT; return; } /* The remaining commands should only be processed if we are editing * a command line. For editing a line in a file, the commands that * relate to command line history are not applicable and should be * blocked. */ if (type == EDITCMDLINE) { switch(curChar) { case '/': putchar('/'); historysearch(); return; case '+': case 'j': shownext(); return; case '-': case 'k': showprev(); return; } } /* Beep to indicate an error. */ putchar(0x07); }
int main() { int i; int count=0; int lockdesc; #if 1 /* Test Case 1: readers and writers with same priorities, with readers being called first and then writers*/ kprintf("\n\n########## Test Case1: same priority readers and writers: readers called first and then writers\n"); lockdesc = lcreate(); reader1 = create(proc, 2000, 30, "Reader 1", 4, 'A', lockdesc, 50, READ); reader2 = create(proc, 2000, 30, "Reader 2", 4, 'B', lockdesc, 50, READ); writer1 = create(proc, 2000, 30, "Writer 1", 4, 'C', lockdesc, 50, WRITE); writer2 = create(proc, 2000, 30, "Writer 2", 4, 'D', lockdesc, 50, WRITE); resume(reader1); resume(reader2); resume(writer1); resume(writer2); sleep(4); /* To make sure that all the readers and writers are done before deleting the lockdesc */ ldelete(lockdesc); while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); kill(reader2); kill(writer1); kill(writer2); /***************************** End of Test Case 1 *****************************/ count = 0; /* Test Case 2: readers and writers with different priorities */ kprintf("\n\n########## Test Case2: Readers and Writers with different priorities\n"); lockdesc = lcreate(); reader1 = create(proc, 2000, 30, "Reader 1", 4, 'A', lockdesc, 50, READ); reader2 = create(proc, 2000, 20, "Reader 2", 4, 'B', lockdesc, 20, READ); reader3 = create(proc, 2000, 30, "Reader 3", 4, 'C', lockdesc, 30, READ); writer1 = create(proc, 2000, 50, "Writer 4", 4, 'D', lockdesc, 50, WRITE); writer2 = create(proc, 2000, 30, "Writer 5", 4, 'E', lockdesc, 30, WRITE); writer3 = create(proc, 2000, 100, "Writer 6", 4, 'F', lockdesc, 100, WRITE); resume(writer3); /* prio = 100 - highest*/ resume(writer2); /* prio = 30*/ resume(reader1); /* prio = 50 > the previous writer*/ resume(reader2); resume(reader3); resume(writer1); sleep(5);//to make sure that main waits till all the readers and writers are done before deleting the lockdesc ldelete(lockdesc); while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); kill(reader2); kill(reader3); kill(writer1); kill(writer2); kill(writer3); /***************************** End of Test Case 2 *****************************/ #endif count = 0; /* Test Case 3: Testing the case of time difference between equal priority reader and writer */ kprintf("\n\n########## Test Case3: Testing the case of time difference between equal priority reader and writer \n"); lockdesc = lcreate(); reader1 = create(proc, 2000, 30, "Reader 1", 4, 'A', lockdesc, 50, READ); reader2 = create(proc, 2000, 20, "Reader 2", 4, 'B', lockdesc, 60, READ); reader3 = create(proc, 2000, 30, "Reader 3", 4, 'C', lockdesc, 70, READ); writer1 = create(proc, 2000, 50, "Writer 1", 4, 'D', lockdesc, 50, WRITE); writer2 = create(proc, 2000, 30, "Writer 2", 4, 'E', lockdesc, 55, WRITE); writer3 = create(proc, 2000, 100, "Writer 3", 4, 'F', lockdesc, 100, WRITE); resume(writer3); /* prio = 100 - highest*/ resume(reader1); resume(writer2); /* prio = 30*/ resume(reader2); resume(reader3); sleep(1); /* So that this writer comes at least 1sec after the previous reader with the same priority */ //for (i = 0; i < 1000000000; i++); resume(writer1); //wakeup(); sleep(5);//to make sure that main waits till all the readers and writers are done before deleting the lockdesc // ldelete(lockdesc); while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); kill(reader2); kill(reader3); kill(writer1); kill(writer2); kill(writer3); /***************************** End of Test Case 3 *****************************/ #if 1 count = 0; /* Test Case 4: Testing the case where a process tries to release a lockdesc it doesn't hold */ kprintf("\n\n########## Test Case4: Testing the case where a process tries to release a lockdesc it doesn't hold \n"); int lock_r = lcreate(); /* lockdesc for the reader */ int lock_w = lcreate(); /* lockdesc for the writer */ reader1 = create(proc_r, 2000, 30, "Reader 1", 5, 'A', lock_r,lock_w, 50, READ); writer1 = create(proc_w, 2000, 50, "Writer 1", 5, 'B', lock_w,lock_r, 50, WRITE); resume(reader1);/* should return error while trying to release lock_w */ resume(writer1);/* should return error while trying to release lock_r */ sleep(3);//to make sure that main waits till all the readers and writers are done before deleting the lockdesc ldelete(lock_r); ldelete(lock_w); while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); kill(writer1); /***************************** End of Test Case 4 *****************************/ count = 0; /* Test Case 5: Testing multiple deletes of the same lockdesc */ kprintf("\n\n########## Test Case5: Testing multiple deletes of the same lockdesc \n"); lockdesc = lcreate(); int del_ret = ldelete(lockdesc); kprintf("\n\tLock %d deleted first time = %d [1: OK, -1: SYSERR]\n",lockdesc,del_ret); del_ret = ldelete(lockdesc); /* Should get a SYSERR here as the lockdesc is already deleted */ kprintf("\n\tLock %d deleted second time = %d [1: OK, -1: SYSERR]\n",lockdesc,del_ret); while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); /***************************** End of Test Case 5 *****************************/ count = 0; /* Test Case 6: Testing lockdesc acquire after the lockdesc is deleted */ kprintf("\n\n########## Test Case6: Testing lockdesc acquire after the lockdesc is deleted \n"); lockdesc = lcreate(); reader1 = create(proc_lock_deleted, 2000, 30, "Reader 1", 4, 'A', lockdesc, 50, READ); del_ret = ldelete(lockdesc); resume(reader1); /* Should give a SYSERR here as lockdesc is already deleted and this proc cannot acquire it */ while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); /***************************** End of Test Case 6 *****************************/ count = 0; /* Test Case 7: Testing lockdesc release after the lockdesc has been deleted */ kprintf("\n\n########## Test Case7: Testing lockdesc release after the lockdesc has been deleted \n"); lockdesc = lcreate(); reader1 = create(proc_release_delete, 2000, 30, "Reader 1", 4, 'A', lockdesc, 50, READ); resume(reader1); ldelete(lockdesc); sleep(1); /* So that reader1 gets back the control before getting killed */ while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); /***************************** End of Test Case 7 *****************************/ count = 0; /* Test Case 8: Testing behavior of critical waiting process when a lockdesc it is waiting on is deleted */ kprintf("\n\n########## Test Case8: Testing behavior of critical waiting process when a lockdesc it is waiting on is deleted \n"); lockdesc = lcreate(); reader1 = create(proc_skip_crit_lock_del, 2000, 30, "Reader 1", 4, 'R', lockdesc, 50, READ); writer1 = create(proc_del_lock, 2000, 50, "Writer 4", 4, 'W', lockdesc, 50, WRITE); resume(writer1); resume(reader1); sleep(2); while (count++ < LOOP) { kprintf("M"); for (i = 0; i < 10000000; i++); } kill(reader1); kill(writer1); /***************************** End of Test Case 8 *****************************/ #endif kprintf("\n\nHello World, Xinu lives\n\n"); return 0; }
/* ARGSUSED */ int upperword(int f, int n) { int c, s; RSIZE size; if ((s = checkdirty(curbp)) != TRUE) return (s); if (curbp->b_flag & BFREADONLY) { ewprintf("Buffer is read-only"); return (FALSE); } if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FFRAND, 1) == FALSE) return (TRUE); } size = countfword(); undo_add_change(curwp->w_dotp, curwp->w_doto, size); while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); #ifndef MRUBY if (ISLOWER(c) != FALSE) { c = TOUPPER(c); #else if (MG_ISLOWER(c) != FALSE) { c = MG_TOUPPER(c); #endif /* !MRUBY */ lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFFULL); } if (forwchar(FFRAND, 1) == FALSE) return (TRUE); } } return (TRUE); } /* * Move the cursor forward by the specified number of words. As you move * convert characters to lower case. */ /* ARGSUSED */ int lowerword(int f, int n) { int c, s; RSIZE size; if ((s = checkdirty(curbp)) != TRUE) return (s); if (curbp->b_flag & BFREADONLY) { ewprintf("Buffer is read-only"); return (FALSE); } if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FFRAND, 1) == FALSE) return (TRUE); } size = countfword(); undo_add_change(curwp->w_dotp, curwp->w_doto, size); while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); #ifndef MRUBY if (ISUPPER(c) != FALSE) { c = TOLOWER(c); #else if (MG_ISUPPER(c) != FALSE) { c = MG_TOLOWER(c); #endif /* !MRUBY */ lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFFULL); } if (forwchar(FFRAND, 1) == FALSE) return (TRUE); } } return (TRUE); } /* * Move the cursor forward by the specified number of words. As you move * convert the first character of the word to upper case, and subsequent * characters to lower case. Error if you try to move past the end of the * buffer. */ /* ARGSUSED */ int capword(int f, int n) { int c, s; RSIZE size; if ((s = checkdirty(curbp)) != TRUE) return (s); if (curbp->b_flag & BFREADONLY) { ewprintf("Buffer is read-only"); return (FALSE); } if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FFRAND, 1) == FALSE) return (TRUE); } size = countfword(); undo_add_change(curwp->w_dotp, curwp->w_doto, size); if (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); #ifndef MRUBY if (ISLOWER(c) != FALSE) { c = TOUPPER(c); #else if (MG_ISLOWER(c) != FALSE) { c = MG_TOUPPER(c); #endif /* !MRUBY */ lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFFULL); } if (forwchar(FFRAND, 1) == FALSE) return (TRUE); while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); #ifndef MRUBY if (ISUPPER(c) != FALSE) { c = TOLOWER(c); #else if (MG_ISUPPER(c) != FALSE) { c = MG_TOLOWER(c); #endif /* !MRUBY */ lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFFULL); } if (forwchar(FFRAND, 1) == FALSE) return (TRUE); } } } return (TRUE); } /* * Count characters in word, from current position */ RSIZE countfword() { RSIZE size; struct line *dotp; int doto; dotp = curwp->w_dotp; doto = curwp->w_doto; size = 0; while (inword() != FALSE) { if (forwchar(FFRAND, 1) == FALSE) /* hit the end of the buffer */ goto out; ++size; } out: curwp->w_dotp = dotp; curwp->w_doto = doto; return (size); } /* * Kill forward by "n" words. */ /* ARGSUSED */ int delfword(int f, int n) { RSIZE size; struct line *dotp; int doto; int s; if ((s = checkdirty(curbp)) != TRUE) return (s); if (curbp->b_flag & BFREADONLY) { ewprintf("Buffer is read-only"); return (FALSE); } if (n < 0) return (FALSE); /* purge kill buffer */ if ((lastflag & CFKILL) == 0) kdelete(); thisflag |= CFKILL; dotp = curwp->w_dotp; doto = curwp->w_doto; size = 0; while (n--) { while (inword() == FALSE) { if (forwchar(FFRAND, 1) == FALSE) /* hit the end of the buffer */ goto out; ++size; } while (inword() != FALSE) { if (forwchar(FFRAND, 1) == FALSE) /* hit the end of the buffer */ goto out; ++size; } } out: curwp->w_dotp = dotp; curwp->w_doto = doto; return (ldelete(size, KFORW)); } /* * Kill backwards by "n" words. The rules for success and failure are now * different, to prevent strange behavior at the start of the buffer. The * command only fails if something goes wrong with the actual delete of the * characters. It is successful even if no characters are deleted, or if you * say delete 5 words, and there are only 4 words left. I considered making * the first call to "backchar" special, but decided that that would just be * weird. Normally this is bound to "M-Rubout" and to "M-Backspace". */ /* ARGSUSED */ int delbword(int f, int n) { RSIZE size; int s; if ((s = checkdirty(curbp)) != TRUE) return (s); if (curbp->b_flag & BFREADONLY) { ewprintf("Buffer is read-only"); return (FALSE); } if (n < 0) return (FALSE); /* purge kill buffer */ if ((lastflag & CFKILL) == 0) kdelete(); thisflag |= CFKILL; if (backchar(FFRAND, 1) == FALSE) /* hit buffer start */ return (TRUE); /* one deleted */ size = 1; while (n--) { while (inword() == FALSE) { if (backchar(FFRAND, 1) == FALSE) /* hit buffer start */ goto out; ++size; } while (inword() != FALSE) { if (backchar(FFRAND, 1) == FALSE) /* hit buffer start */ goto out; ++size; } } if (forwchar(FFRAND, 1) == FALSE) return (FALSE); /* undo assumed delete */ --size; out: return (ldelete(size, KBACK)); }
/* * This function serves two purposes, 1) to strip white space when * Pmaster asks that the composition have its trailing white space * stripped, or 2) to prepare the text as flowed text, as Pmaster * is telling us that we're working with flowed text. * * What flowed currently means to us is stripping all trailing white * space, except for one space if the following line is a continuation * of the paragraph. Also, we space-stuff all lines beginning * with white-space, and leave siglines alone. */ int cleanwhitespace(void) { LINE *cursor_dotp = NULL, **lp = NULL; int i = 0, cursor_doto = 0, is_cursor_line = 0; int do_space_stuffing = 0; if(Pmaster && Pmaster->allow_flowed_text && !(*Pmaster->user_says_noflow)()) do_space_stuffing++; cursor_dotp = curwp->w_dotp; cursor_doto = curwp->w_doto; gotobob(FALSE, 1); for(lp = &curwp->w_dotp; (*lp) != curbp->b_linep; (*lp) = lforw(*lp)){ if(!(llength(*lp) == 3 && lgetc(*lp, 0).c == '-' && lgetc(*lp, 1).c == '-' && lgetc(*lp, 2).c == ' ') && llength(*lp)){ is_cursor_line = (cursor_dotp == (*lp)); /* trim trailing whitespace, to be added back if flowing */ for(i = llength(*lp); i; i--) if(!ucs4_isspace(lgetc(*lp, i - 1).c)) break; if(i != llength(*lp)){ int flow_line = 0; if(Pmaster && !Pmaster->strip_ws_before_send && lforw(*lp) != curbp->b_linep && llength(lforw(*lp)) && !(ucs4_isspace(lgetc(lforw(*lp), 0).c) || isquotedspace(lforw(*lp))) && !(llength(lforw(*lp)) == 3 && lgetc(lforw(*lp), 0).c == '-' && lgetc(lforw(*lp), 1).c == '-' && lgetc(lforw(*lp), 2).c == ' ')) flow_line = 1; if(flow_line && i && lgetc(*lp, i).c == ' '){ /* flowed line ending with space */ i++; if(i != llength(*lp)){ curwp->w_doto = i; ldelete(llength(*lp) - i, NULL); } } else if(flow_line && i && ucs4_isspace(lgetc(*lp, i).c)){ /* flowed line ending with whitespace other than space*/ curwp->w_doto = i; ldelete(llength(*lp) - i, NULL); linsert(1, ' '); } else{ curwp->w_doto = i; ldelete(llength(*lp) - i, NULL); } } if(do_space_stuffing && llength(*lp) && ucs4_isspace(lgetc(*lp, 0).c)){ /* space-stuff only if flowed */ if(Pmaster) Pmaster->space_stuffed = 1; curwp->w_doto = 0; if(is_cursor_line && cursor_doto) cursor_doto++; linsert(1, ' '); } if(is_cursor_line) cursor_dotp = (*lp); } } /* put the cursor back where we found it */ gotobob(FALSE, 1); curwp->w_dotp = cursor_dotp; curwp->w_doto = (cursor_doto < llength(curwp->w_dotp)) ? cursor_doto : llength(curwp->w_dotp) - 1; return(0); }
/* lineeditor(): * This is a simpler version of lineeditor() (as found in lineedit.c). * It does not have the capability of the vi-like version; however, for * those not familiar with ksh, this one is probably a lot more intuitive. * * The line is modified in place so, if successful, the function * returns the same pointer but with its contents modified based * on the editor commands executed. * If failure, the function returns (char *)0. */ static char * lineeditor(char *line_to_edit,int type) { int state; if (type == EDITCMDLINE) { if (getchar() != OPEN_BRACKET) { putchar('\n'); *line_to_edit = 0; return((char *)0); } } startOfLine = line_to_edit; curPos = line_to_edit; while(*curPos != ESC) curPos++; *curPos = 0; /* Remove the escape character from the line */ lineLen = (ulong)curPos - (ulong)startOfLine; if (lineLen > 0) { curPos--; putstr(" \b\b"); } else putstr(" \b"); state = GOT_BRACKET; lastsize = 0; shwidx = stridx; srchidx = stridx; while(1) { curChar = getchar(); switch(curChar) { case CTLC: putchar('\n'); *line_to_edit = 0; return((char *)0); case VT100_UP: if (state == GOT_BRACKET) { if (type == EDITCMDLINE) showprev(); state = GOT_NUTTIN; } else { newchar(curChar); } break; case VT100_DOWN: if (state == GOT_BRACKET) { if (type == EDITCMDLINE) shownext(); state = GOT_NUTTIN; } else { newchar(curChar); } break; case VT100_RIGHT: if (state == GOT_BRACKET) { if (curPos < startOfLine+lineLen) { putchar(*curPos); curPos++; } state = GOT_NUTTIN; } else { newchar(curChar); } break; case VT100_LEFT: if (state == GOT_BRACKET) { if (curPos > startOfLine) { putchar('\b'); curPos--; } state = GOT_NUTTIN; } else { newchar(curChar); } break; case OPEN_BRACKET: if (state == GOT_ESCAPE) { state = GOT_BRACKET; } else { newchar(curChar); } break; case ESC: state = GOT_ESCAPE; break; case VT100_DEL: if (curPos != (startOfLine + lineLen)) ldelete(); break; case '\b': if (curPos > startOfLine) backspace(); break; case '\n': case '\r': putchar('\n'); if (lineLen == 0) return((char *)0); *(char *)(startOfLine + lineLen) = '\0'; return(startOfLine); default: newchar(curChar); break; } } return((char *)0); }
/* * Yank text back from the kill buffer. This is really easy. All of the work * is done by the standard insert routines. All you do is run the loop, and * check for errors. Bound to "C-Y". */ int yank(int f, int n) { int c, i; REGION region, *added_region; LINE *dotp; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); if(TERM_OPTIMIZE && (curwp->w_dotp != curwp->w_bufp->b_linep)){ int l; if(worthit(&l) && !(lastflag&CFFILL)){ register int t = 0; register int i = 0; register int ch; while((ch=fremove(i++)) >= 0) if(ch == '\n') t++; if(t+l < curwp->w_toprow+curwp->w_ntrows) scrolldown(curwp, l, t); } } if(lastflag & CFFILL){ /* if last command was fillpara() */ if(lastflag & CFFLBF){ gotoeob(FALSE, 1); dotp = curwp->w_dotp; gotobob(FALSE, 1); curwp->w_doto = 0; getregion(®ion, dotp, llength(dotp)); } else{ added_region = get_last_region_added(); if(added_region){ curwp->w_dotp = added_region->r_linep; curwp->w_doto = added_region->r_offset; region = (*added_region); } else return(FALSE); } if(!ldelete(region.r_size, NULL)) return(FALSE); } /* then splat out the saved buffer */ while (n--) { i = 0; while ((c = ((lastflag&CFFILL) ? ((lastflag & CFFLBF) ? kremove(i) : fremove(i)) : kremove(i))) >= 0) { if (c == '\n') { if (lnewline() == FALSE) return (FALSE); } else { if (linsert(1, c) == FALSE) return (FALSE); } ++i; } } if(lastflag&CFFLPA){ /* if last command was fill paragraph */ curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_doto = 0; curwp->w_flag |= WFMODE; if(!Pmaster){ sgarbk = TRUE; emlwrite("", NULL); } } return (TRUE); }
int setquotelevelinregion(int quotelevel, REGION *addedregion) { int i, standards_based = 0; int quote_chars = 0, backuptoprevline = 0; int starts_midline = 0, ends_midline = 0, offset_into_start; long c, sz; UCS qstr_def1[] = { '>', ' ', 0}, qstr_def2[] = { '>', 0}; LINE *lp, *line_before_start; REGION region; if(curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if(!glo_quote_str || !ucs4_strcmp(glo_quote_str, qstr_def1) || !ucs4_strcmp(glo_quote_str, qstr_def2)) standards_based++; if(!standards_based){ emlwrite("Quote level setting only works with standard \"> \" quotes", NULL); return(FALSE); } /* if region starts midline insert a newline */ if(curwp->w_doto > 0 && curwp->w_doto < llength(curwp->w_dotp)) starts_midline++; /* if region ends midline insert a newline at end */ if(curwp->w_marko > 0 && curwp->w_marko < llength(curwp->w_markp)){ ends_midline++; backuptoprevline++; /* count quote chars for re-insertion */ for(i = 0; i < llength(curwp->w_markp); ++i) if(lgetc(curwp->w_markp, i).c != '>') break; quote_chars = i; } else if(curwp->w_marko == 0) backuptoprevline++; /* find the size of the region */ getregion(®ion, curwp->w_markp, curwp->w_marko); /* cut the paragraph into our fill buffer */ fdelete(); if(!ldelete(region.r_size, finsert)) return(FALSE); line_before_start = lback(curwp->w_dotp); offset_into_start = curwp->w_doto; /* if region starts midline add a newline */ if(starts_midline) lnewline(); i = 0; while(fremove(i) >= 0){ /* remove all quote strs from current line */ if(standards_based){ while((c = fremove(i)) == '>') i++; if(c == ' ') i++; } else{ } /* insert quotelevel quote strs */ if(standards_based){ linsert(quotelevel, '>'); if(quotelevel > 0) linsert(1, ' '); } else{ } /* put back the actual line */ while((c = fremove(i++)) >= 0 && c != '\n') linsert(1, (UCS) c); if(c == '\n') lnewline(); } /* if region ends midline add a newline */ if(ends_midline){ lnewline(); if(quote_chars){ linsert(quote_chars, '>'); if(curwp->w_doto < llength(curwp->w_dotp) && lgetc(curwp->w_dotp, curwp->w_doto).c != ' ') linsert(1, ' '); } } /* * Calculate the size of the region that was added. */ swapmark(0,1); /* mark current location after adds */ addedregion->r_linep = lforw(line_before_start); addedregion->r_offset = offset_into_start; lp = addedregion->r_linep; sz = llength(lp) - addedregion->r_offset; if(lforw(lp) != curwp->w_markp->l_fp){ lp = lforw(lp); while(lp != curwp->w_markp->l_fp){ sz += llength(lp) + 1; lp = lforw(lp); } } sz -= llength(curwp->w_markp) - curwp->w_marko; addedregion->r_size = sz; swapmark(0,1); /* * This puts us at the end of the quoted region instead * of on the following line. This makes it convenient * for the user to follow a quotelevel adjustment with * a Justify if desired. */ if(backuptoprevline){ curwp->w_doto = 0; backchar(0, 1); } if(ends_midline){ /* doesn't need fixing otherwise */ unmarkbuffer(); markregion(1); } return (TRUE); }
int del_test3(char c, int lck){ sleep(2); kprintf("Proc %c deleting %d\n", c, ldelete(lck)); while(1){ } }
/* Justify the entire buffer instead of just a paragraph */ int fillbuf(int f, int n) { LINE *eobline; REGION region; if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ } else if (fillcol == 0) { /* no fill column set */ mlwrite_utf8("No fill column set", NULL); return(FALSE); } if((lastflag & CFFILL) && (lastflag & CFFLBF)){ /* no use doing a full justify twice */ thisflag |= (CFFLBF | CFFILL); return(TRUE); } /* record the pointer of the last line */ if(gotoeob(FALSE, 1) == FALSE) return(FALSE); eobline = curwp->w_dotp; /* last line of buffer */ if(!llength(eobline)) eobline = lback(eobline); /* and back to the beginning of the buffer */ gotobob(FALSE, 1); thisflag |= CFFLBF; /* CFFILL also gets set in fillpara */ if(!Pmaster) sgarbk = TRUE; curwp->w_flag |= WFMODE; /* * clear the kill buffer, that's where we'll store undo * information, we can't do the fill buffer because * fillpara relies on its contents */ kdelete(); curwp->w_doto = 0; getregion(®ion, eobline, llength(eobline)); /* Put full message in the kill buffer for undo */ if(!ldelete(region.r_size, kinsert)) return(FALSE); /* before yank'ing, clear lastflag so we don't just unjustify */ lastflag &= ~(CFFLBF | CFFILL); /* Now in kill buffer, bring back text to use in fillpara */ yank(FALSE, 1); gotobob(FALSE, 1); /* call fillpara until we're at the end of the buffer */ while(curwp->w_dotp != curbp->b_linep) if(!(fillpara(FALSE, 1))) return(FALSE); return(TRUE); }
/* * Fill the current paragraph according to the current fill column. */ int fillpara (int f, int n, int k) { register int c; /* current char durring scan */ register int wordlen; /* length of current word */ register int clength; /* position on line during fill */ register int eopflag; /* Are we at the End-Of-Paragraph? */ int firstflag; /* first word? (needs no space) */ int newlength; /* tentative new line length */ int eolflag; /* was at end of line */ LINE *eopline; /* pointer to line just past EOP */ char wbuf[MAXWORD]; /* buffer for current word */ /* Record the pointer to the line just past the * end of the paragraph. */ gotoeop (FALSE, 1, KRANDOM); eopline = curwp->w_dot.p; if (lforw (eopline) == curbp->b_linep) eopline = curbp->b_linep; /* Move to the begining of the paragraph. */ gotobop (FALSE, 1, KRANDOM); /* Skip to the start of the first word in the paragraph, * and set our current column position. */ while (!inword ()) if (forwchar (FALSE, 1, KRANDOM) == FALSE) break; clength = getcolpos () - 1; wordlen = 0; /* scan through lines, filling words */ firstflag = TRUE; eopflag = FALSE; while (!eopflag) { /* get the next character in the paragraph */ if ((eolflag = (curwp->w_dot.o == llength (curwp->w_dot.p))) == TRUE) { c = ' '; if (lforw (curwp->w_dot.p) == eopline) eopflag = TRUE; } else c = lgetc (curwp->w_dot.p, curwp->w_dot.o); /* and then delete it */ if (ldelete (1, FALSE) == FALSE) return (FALSE); /* if not a separator, just add it in */ if (c != ' ' && c != '\t') { if (wordlen < MAXWORD - 1) wbuf[wordlen++] = c; else { /* You lose chars beyond MAXWORD if the word * is to long. I'm to lazy to fix it now; it * just silently truncated the word before, so * I get to feel smug. */ eprintf ("Word too long!"); } } else if (wordlen) { /* calculate tenatitive new length with word added */ newlength = clength + 1 + wordlen; /* if at end of line or at doublespace and previous * character was one of '.','?','!' doublespace here. */ if ((eolflag || curwp->w_dot.o == llength (curwp->w_dot.p) || (c = lgetc (curwp->w_dot.p, curwp->w_dot.o)) == ' ' || c == '\t') && ISEOSP (wbuf[wordlen - 1]) && wordlen < MAXWORD - 1) wbuf[wordlen++] = ' '; /* at a word break with a word waiting */ if (newlength <= fillcol) { /* add word to current line */ if (!firstflag) { linsert (1, ' ', NULLPTR); ++clength; } firstflag = FALSE; } else { if (curwp->w_dot.o > 0 && lgetc (curwp->w_dot.p, curwp->w_dot.o - 1) == ' ') { curwp->w_dot.o -= 1; ldelete (1, FALSE); } /* start a new line */ lnewline (); clength = 0; } /* and add the word in in either case */ linsert (wordlen, 0, wbuf); clength += wordlen; wordlen = 0; } } /* and add a last newline for the end of our new paragraph */ lnewline (); /* we realy should wind up where we started, (which is hard to keep * track of) but I think the end of the last line is better than the * begining of the blank line. */ backchar (FALSE, 1, KRANDOM); return (TRUE); }
/* * replaces: search for a string and replace it with another string. query * might be enabled (according to kind) */ int replaces (int kind, int f, int n) { LINE *origline; /* original "." position */ char tmpc; /* temporary character */ char c; /* input char for query */ char tpat[NPAT]; /* temporary to hold search pattern */ int i; /* loop index */ int s; /* success flag on pattern inputs */ int slength, rlength; /* length of search and replace strings */ int numsub; /* number of substitutions */ int nummatch; /* number of found matches */ int nlflag; /* last char of search string a <NL>? */ int nlrepl; /* was a replace done on the last line? */ int origoff; /* and offset (for . query option) */ /* check for negative repititions */ if (f && n < 0) return (FALSE); /* ask the user for the text of a pattern */ if ((s = readpattern ((kind == FALSE ? "Replace" : "Query replace"))) != TRUE) return (s); strncpy (&tpat[0], &pat[0], NPAT); /* salt it away */ /* ask for the replacement string */ strncpy (&pat[0], &rpat[0], NPAT); /* set up default string */ if ((s = readpattern ("with")) == ABORT) return (s); /* move everything to the right place and length them */ strncpy (&rpat[0], &pat[0], NPAT); strncpy (&pat[0], &tpat[0], NPAT); slength = strlen (&pat[0]); rlength = strlen (&rpat[0]); /* set up flags so we can make sure not to do a recursive replace on the * last line */ nlflag = (pat[slength - 1] == '\n'); nlrepl = FALSE; /* build query replace question string */ strncpy (tpat, "Replace '", 10); expandp (&pat[0], &tpat[strlen (tpat)], NPAT / 3); strncat (tpat, "' with '", 9); expandp (&rpat[0], &tpat[strlen (tpat)], NPAT / 3); strncat (tpat, "'? ", 4); /* save original . position */ origline = curwp->w_dotp; origoff = curwp->w_doto; /* scan through the file */ numsub = 0; nummatch = 0; while ((f == FALSE || n > nummatch) && (nlflag == FALSE || nlrepl == FALSE)) { /* search for the pattern */ if (forscan (&pat[0], PTBEG) != TRUE) break; /* all done */ ++nummatch; /* increment # of matches */ /* check if we are on the last line */ nlrepl = (lforw (curwp->w_dotp) == curwp->w_bufp->b_linep); /* check for query */ if (kind) { /* get the query */ mlwrite (&tpat[0], &pat[0], &rpat[0]); qprompt: update (); /* show the proposed place to change */ c = (*term.t_getchar) (); /* and input */ mlwrite (""); /* and clear it */ /* and respond appropriately */ switch (c) { case 'y': /* yes, substitute */ case ' ': break; case 'n': /* no, onword */ forwchar (FALSE, 1); continue; case '!': /* yes/stop asking */ kind = FALSE; break; case '.': /* abort! and return */ /* restore old position */ curwp->w_dotp = origline; curwp->w_doto = origoff; curwp->w_flag |= WFMOVE; case BELL: /* abort! and stay */ mlwrite ("Aborted!"); return (FALSE); case 0x0d: /* controlled exit */ case 'q': return (TRUE); default: /* bitch and beep */ (*term.t_beep) (); case '?': /* help me */ mlwrite ("(Y)es, (N)o, (!)Do the rest, (^G,RET,q)Abort, (.)Abort back, (?)Help: "); goto qprompt; } } /* delete the sucker */ if (ldelete (slength, FALSE) != TRUE) { /* error while deleting */ mlwrite ("ERROR while deleteing"); return (FALSE); } /* and insert its replacement */ for (i = 0; i < rlength; i++) { tmpc = rpat[i]; s = (tmpc == '\n' ? lnewline () : linsert (1, tmpc)); if (s != TRUE) { /* error while inserting */ mlwrite ("Out of memory while inserting"); return (FALSE); } } numsub++; /* increment # of substitutions */ } /* and report the results */ mlwrite ("%d substitutions", numsub); return (TRUE); }
/* * Set a variable. * * @var: variable to set. * @value: value to set to. */ int svar(struct variable_description *var, char *value) { int vnum; /* ordinal number of var refrenced */ int vtype; /* type of variable to set */ int status; /* status return */ int c; /* translated character */ char *sp; /* scratch string pointer */ /* simplify the vd structure (we are gonna look at it a lot) */ vnum = var->v_num; vtype = var->v_type; /* and set the appropriate value */ status = TRUE; switch (vtype) { case TKVAR: /* set a user variable */ if (uv[vnum].u_value != NULL) free(uv[vnum].u_value); sp = malloc(strlen(value) + 1); if (sp == NULL) return FALSE; strcpy(sp, value); uv[vnum].u_value = sp; break; case TKENV: /* set an environment variable */ status = TRUE; /* by default */ switch (vnum) { case EVFILLCOL: fillcol = atoi(value); break; case EVPAGELEN: status = newsize(TRUE, atoi(value)); break; case EVCURCOL: status = setccol(atoi(value)); break; case EVCURLINE: status = gotoline(TRUE, atoi(value)); break; case EVRAM: break; case EVFLICKER: flickcode = stol(value); break; case EVCURWIDTH: status = newwidth(TRUE, atoi(value)); break; case EVCBUFNAME: strcpy(curbp->b_bname, value); curwp->w_flag |= WFMODE; break; case EVCFNAME: strcpy(curbp->b_fname, value); curwp->w_flag |= WFMODE; break; case EVSRES: status = TTrez(value); break; case EVDEBUG: macbug = stol(value); break; case EVSTATUS: cmdstatus = stol(value); break; case EVASAVE: gasave = atoi(value); break; case EVACOUNT: gacount = atoi(value); break; case EVLASTKEY: lastkey = atoi(value); break; case EVCURCHAR: ldelete(1L, FALSE); /* delete 1 char */ c = atoi(value); if (c == '\n') lnewline(); else linsert(1, c); backchar(FALSE, 1); break; case EVDISCMD: discmd = stol(value); break; case EVVERSION: break; case EVPROGNAME: break; case EVSEED: seed = atoi(value); break; case EVDISINP: disinp = stol(value); break; case EVWLINE: status = resize(TRUE, atoi(value)); break; case EVCWLINE: status = forwline(TRUE, atoi(value) - getwpos()); break; case EVTARGET: curgoal = atoi(value); thisflag = saveflag; break; case EVSEARCH: strcpy(pat, value); rvstrcpy(tap, pat); #if MAGIC mcclear(); #endif break; case EVREPLACE: strcpy(rpat, value); break; case EVMATCH: break; case EVKILL: break; case EVCMODE: curbp->b_mode = atoi(value); curwp->w_flag |= WFMODE; break; case EVGMODE: gmode = atoi(value); break; case EVTPAUSE: term.t_pause = atoi(value); break; case EVPENDING: break; case EVLWIDTH: break; case EVLINE: putctext(value); case EVGFLAGS: gflags = atoi(value); break; case EVRVAL: break; case EVTAB: tabmask = atoi(value) - 1; if (tabmask != 0x07 && tabmask != 0x03) tabmask = 0x07; curwp->w_flag |= WFHARD; break; case EVOVERLAP: overlap = atoi(value); break; case EVSCROLLCOUNT: scrollcount = atoi(value); break; case EVSCROLL: #if SCROLLCODE if (!stol(value)) term.t_scroll = NULL; #endif break; } break; } return status; }