/* * Read a pattern. Stash it in the external variable "pat". The "pat" is not * updated if the user types in an empty line. If the user typed an empty * line, and there is no old pattern, it is an error. Display the old pattern, * in the style of Jeff Lomicka. There is some do-it-yourself control * expansion. change to using <ESC> to delemit the end-of-pattern to allow * <NL>s in the search string */ int readpattern (char *prompt) { char tpat[NPAT + 20]; int s; strncpy (tpat, prompt, NPAT-12); /* copy prompt to output string */ strncat (tpat, " [", 3); /* build new prompt string */ expandp (&pat[0], &tpat[strlen (tpat)], NPAT / 2); /* add old pattern */ strncat (tpat, "]<ESC>: ", 9); s = mlreplyt (tpat, tpat, NPAT, 27); /* Read pattern */ if (s == TRUE) /* Specified */ strncpy (pat, tpat, NPAT); else if (s == FALSE && pat[0] != 0) /* CR, but old one */ s = TRUE; return (s); }
/* * 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); }
int readpattern(char *utf8prompt, int text_mode) { register int s; int i; UCS *b; UCS tpat[NPAT+20]; UCS *tpatp; EXTRAKEYS menu_pat[7]; menu_pat[i = 0].name = "^Y"; menu_pat[i].label = N_("FirstLine"); menu_pat[i].key = (CTRL|'Y'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^V"; menu_pat[i].label = N_("LastLine"); menu_pat[i].key = (CTRL|'V'); KS_OSDATASET(&menu_pat[i], KS_NONE); if(text_mode){ menu_pat[++i].name = "^T"; menu_pat[i].label = N_("LineNumber"); menu_pat[i].key = (CTRL|'T'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^W"; menu_pat[i].label = N_("Start of Para"); menu_pat[i].key = (CTRL|'W'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^O"; menu_pat[i].label = N_("End of Para"); menu_pat[i].key = (CTRL|'O'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^U"; menu_pat[i].label = N_("FullJustify"); menu_pat[i].key = (CTRL|'U'); KS_OSDATASET(&menu_pat[i], KS_NONE); } menu_pat[++i].name = NULL; b = utf8_to_ucs4_cpystr(utf8prompt); if(b){ ucs4_strncpy(tpat, b, NPAT+20); tpat[NPAT+20-1] = '\0'; fs_give((void **) &b); } tpatp = &tpat[ucs4_strlen(tpat)]; if(pat[0] != '\0'){ if((tpatp-tpat) < NPAT+20-2){ *tpatp++ = ' '; *tpatp++ = '['; *tpatp = '\0'; } expandp(pat, tpatp, NPAT+20-(tpatp-tpat)); tpat[NPAT+20-1] = '\0'; tpatp += ucs4_strlen(tpatp); if((tpatp-tpat) < NPAT+20-1){ *tpatp++ = ']'; *tpatp = '\0'; } } if((tpatp-tpat) < NPAT+20-3){ *tpatp++ = ' '; *tpatp++ = ':'; *tpatp++ = ' '; *tpatp = '\0'; } tpat[NPAT+20-1] = '\0'; s = mlreplyd(tpat, tpat, NPAT, QNORML, menu_pat); if ((s == TRUE) && ucs4_strcmp(pat,tpat)){ /* Specified */ ucs4_strncpy(pat, tpat, NPAT); pat[NPAT-1] = '\0'; rpat[0] = '\0'; } else if (s == FALSE && pat[0] != '\0') /* CR, but old one */ s = TRUE; return(s); }
/* Read a replacement pattern. Modeled after readpattern(). */ int srpat(char *utf8prompt, UCS *defpat, size_t defpatlen, int repl_mode) { register int s; int i = 0; UCS *b; UCS prompt[NPMT]; UCS *promptp; EXTRAKEYS menu_pat[8]; menu_pat[i = 0].name = "^Y"; menu_pat[i].label = N_("FirstLine"); menu_pat[i].key = (CTRL|'Y'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^V"; menu_pat[i].label = N_("LastLine"); menu_pat[i].key = (CTRL|'V'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^R"; menu_pat[i].label = repl_mode ? N_("No Replace") : N_("Replace"); menu_pat[i].key = (CTRL|'R'); KS_OSDATASET(&menu_pat[i], KS_NONE); if(!repl_mode){ menu_pat[++i].name = "^T"; menu_pat[i].label = N_("LineNumber"); menu_pat[i].key = (CTRL|'T'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^W"; /* TRANSLATORS: Start of paragraph */ menu_pat[i].label = N_("Start of Para"); menu_pat[i].key = (CTRL|'W'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^O"; menu_pat[i].label = N_("End of Para"); menu_pat[i].key = (CTRL|'O'); KS_OSDATASET(&menu_pat[i], KS_NONE); menu_pat[++i].name = "^U"; /* TRANSLATORS: Instead of justifying (formatting) just a single paragraph, Full Justify justifies the entire message. */ menu_pat[i].label = N_("FullJustify"); menu_pat[i].key = (CTRL|'U'); KS_OSDATASET(&menu_pat[i], KS_NONE); } menu_pat[++i].name = NULL; b = utf8_to_ucs4_cpystr(utf8prompt); if(b){ ucs4_strncpy(prompt, b, NPMT); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } promptp = &prompt[ucs4_strlen(prompt)]; if(repl_mode){ b = utf8_to_ucs4_cpystr(" (to replace)"); if(b){ ucs4_strncpy(promptp, b, NPMT-(promptp-prompt)); promptp += ucs4_strlen(promptp); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } } if(pat[0] != '\0'){ if((promptp-prompt) < NPMT-2){ *promptp++ = ' '; *promptp++ = '['; *promptp = '\0'; } expandp(pat, promptp, NPMT-(promptp-prompt)); prompt[NPMT-1] = '\0'; promptp += ucs4_strlen(promptp); if((promptp-prompt) < NPMT-1){ *promptp++ = ']'; *promptp = '\0'; } } if((promptp-prompt) < NPMT-2){ *promptp++ = ':'; *promptp++ = ' '; *promptp = '\0'; } prompt[NPMT-1] = '\0'; s = mlreplyd(prompt, defpat, defpatlen, QDEFLT, menu_pat); if (s == TRUE || s == FALSE){ /* changed or not, they're done */ if(!defpat[0]){ /* use default */ ucs4_strncpy(defpat, pat, defpatlen); defpat[defpatlen-1] = '\0'; } else if(ucs4_strcmp(pat, defpat)){ /* Specified */ ucs4_strncpy(pat, defpat, NPAT); pat[NPAT-1] = '\0'; rpat[0] = '\0'; } s = TRUE; /* let caller know to proceed */ } return(s); }
/* Ask the user about every occurence of orig pattern and replace it with a repl pattern if the response is affirmative. */ int replace_all(UCS *orig, UCS *repl) { register int status = 0; UCS *b; UCS realpat[NPAT]; char utf8tmp[NPMT]; UCS *promptp; UCS prompt[NPMT]; int wrapt, n = 0; LINE *stop_line = curwp->w_dotp; int stop_offset = curwp->w_doto; EML eml; while (1) if (forscan(&wrapt, orig, stop_line, stop_offset, PTBEG)){ curwp->w_flag |= WFMOVE; /* put cursor back */ update(); (*term.t_rev)(1); get_pat_cases(realpat, orig); pputs(realpat, 1); /* highlight word */ (*term.t_rev)(0); fflush(stdout); snprintf(utf8tmp, NPMT, "Replace \""); b = utf8_to_ucs4_cpystr(utf8tmp); if(b){ ucs4_strncpy(prompt, b, NPMT); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } promptp = &prompt[ucs4_strlen(prompt)]; expandp(orig, promptp, NPMT-(promptp-prompt)); prompt[NPMT-1] = '\0'; promptp += ucs4_strlen(promptp); b = utf8_to_ucs4_cpystr("\" with \""); if(b){ ucs4_strncpy(promptp, b, NPMT-(promptp-prompt)); promptp += ucs4_strlen(promptp); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } expandp(repl, promptp, NPMT-(promptp-prompt)); prompt[NPMT-1] = '\0'; promptp += ucs4_strlen(promptp); if((promptp-prompt) < NPMT-1){ *promptp++ = '\"'; *promptp = '\0'; } prompt[NPMT-1] = '\0'; status = mlyesno(prompt, TRUE); /* ask user */ if (status == TRUE){ n++; chword(realpat, repl); /* replace word */ update(); }else{ chword(realpat, realpat); /* replace word by itself */ update(); if(status == ABORT){ /* if cancelled return */ eml.s = comatose(n); emlwrite("Replace All cancelled after %s changes", &eml); return (ABORT); /* ... else keep looking */ } } } else{ char *utf8; utf8 = ucs4_to_utf8_cpystr(orig); if(utf8){ eml.s = utf8; emlwrite(_("No more matches for \"%s\""), &eml); fs_give((void **) &utf8); } else emlwrite(_("No more matches"), NULL); return (FALSE); } }
/* Replace a pattern with the pattern the user types in one or more times. */ int replace_pat(UCS *defpat, int *wrapt) { register int status; UCS lpat[NPAT], origpat[NPAT]; /* case sensitive pattern */ EXTRAKEYS menu_pat[2]; int repl_all = FALSE; UCS *b; char utf8tmp[NPMT]; UCS prompt[NPMT]; UCS *promptp; forscan(wrapt, defpat, NULL, 0, PTBEG); /* go to word to be replaced */ lpat[0] = '\0'; /* additional 'replace all' menu option */ menu_pat[0].name = "^X"; menu_pat[0].key = (CTRL|'X'); menu_pat[0].label = N_("Repl All"); KS_OSDATASET(&menu_pat[0], KS_NONE); menu_pat[1].name = NULL; while(1) { update(); (*term.t_rev)(1); get_pat_cases(origpat, defpat); pputs(origpat, 1); /* highlight word */ (*term.t_rev)(0); snprintf(utf8tmp, NPMT, "Replace%s \"", repl_all ? " every" : ""); b = utf8_to_ucs4_cpystr(utf8tmp); if(b){ ucs4_strncpy(prompt, b, NPMT); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } promptp = &prompt[ucs4_strlen(prompt)]; expandp(defpat, promptp, NPMT-(promptp-prompt)); prompt[NPMT-1] = '\0'; promptp += ucs4_strlen(promptp); b = utf8_to_ucs4_cpystr("\" with"); if(b){ ucs4_strncpy(promptp, b, NPMT-(promptp-prompt)); promptp += ucs4_strlen(promptp); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } if(rpat[0] != '\0'){ if((promptp-prompt) < NPMT-2){ *promptp++ = ' '; *promptp++ = '['; *promptp = '\0'; } expandp(rpat, promptp, NPMT-(promptp-prompt)); prompt[NPMT-1] = '\0'; promptp += ucs4_strlen(promptp); if((promptp-prompt) < NPMT-1){ *promptp++ = ']'; *promptp = '\0'; } } if((promptp-prompt) < NPMT-3){ *promptp++ = ' '; *promptp++ = ':'; *promptp++ = ' '; *promptp = '\0'; } prompt[NPMT-1] = '\0'; status = mlreplyd(prompt, lpat, NPAT, QDEFLT, menu_pat); curwp->w_flag |= WFMOVE; switch(status){ case TRUE : case FALSE : if(lpat[0]){ ucs4_strncpy(rpat, lpat, NPAT); /* remember default */ rpat[NPAT-1] = '\0'; } else{ ucs4_strncpy(lpat, rpat, NPAT); /* use default */ lpat[NPAT-1] = '\0'; } if (repl_all){ status = replace_all(defpat, lpat); } else{ chword(defpat, lpat); /* replace word */ update(); status = TRUE; } if(status == TRUE) emlwrite("", NULL); return(status); case HELPCH: /* help requested */ if(Pmaster){ VARS_TO_SAVE *saved_state; saved_state = save_pico_state(); (*Pmaster->helper)(Pmaster->search_help, _("Help for Searching"), 1); if(saved_state){ restore_pico_state(saved_state); free_pico_state(saved_state); } } else pico_help(SearchHelpText, _("Help for Searching"), 1); case (CTRL|'L'): /* redraw requested */ pico_refresh(FALSE, 1); update(); break; case (CTRL|'X'): /* toggle replace all option */ if (repl_all){ repl_all = FALSE; /* TRANSLATORS: abbreviation for Replace All occurences */ menu_pat[0].label = N_("Repl All"); } else{ repl_all = TRUE; /* TRANSLATORS: Replace just one occurence */ menu_pat[0].label = N_("Repl One"); } break; default: if(status == ABORT){ emlwrite(_("Replacement Cancelled"), NULL); pico_refresh(FALSE, 1); } else{ mlerase(); chword(defpat, origpat); } update(); return(FALSE); } } }