home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 103_01 / edit3.c < prev    next >
Text File  |  1985-03-10  |  8KB  |  397 lines

  1. /*    This is the editor that everyone (including Ma) loves -> QED
  2.     This is the searching section.
  3. */
  4.  
  5. /*     find line fixed for abort 4/21/81    ns    */
  6. #include "edit.inc"
  7.  
  8. init_search()
  9.     {
  10.     used_search = 0;
  11.     }
  12.  
  13. int place_search(count, line)
  14.     int *count;
  15.     char line[];
  16.     {
  17.     int first, dummy, deflt_count, nxet;
  18.     BOOL at_begin, multiple, negate, force, use_first, use_second;
  19.     char c, delim;
  20.     allocate(&first);
  21.     last_block = &data_search[first].epsilon;
  22.     delim = line[(*count)++];
  23.     if (delim == line[*count])
  24.         {
  25.         ++*count;
  26.         line = deflt_line;
  27.         count = &dummy;
  28.         *count = 0;
  29.         delim = EOL;
  30.         }
  31.     deflt_count = 0;
  32.     at_begin = YES;
  33.     multiple = negate = force = start_begin = end_end = NO;
  34.     for (;;)
  35.         {
  36.         c = deflt_line[deflt_count++] = line[(*count)++];
  37.         if (c==delim AND NOT force)
  38.             if (multiple OR negate OR at_begin)
  39.                 return(ERROR);
  40.             else
  41.                 {
  42.                 link(0, NO_SEARCH);
  43.                 deflt_line[deflt_count-1] = EOL;
  44.                 return(first);
  45.                 }
  46.         if (c==EOL)
  47.             return(ERROR);
  48.         if (c==NOT_SYMBOL AND NOT force)
  49.             if (negate)
  50.                 return(ERROR);
  51.             else
  52.                 negate = YES;
  53.         else if (c==MANY_SYMBOL AND NOT force)
  54.             if (multiple)
  55.                 return(ERROR);
  56.             else
  57.                 multiple = YES;
  58.         else if (c==FORCE_SYMBOL AND NOT force)
  59.             force = YES;
  60.         else if (c==BEGIN_SYMBOL AND NOT force AND at_begin)
  61.             if (multiple OR negate)
  62.                 return(ERROR);
  63.             else
  64.                 {
  65.                 start_begin = YES;
  66.                 at_begin = NO;
  67.                 }
  68.         else if (c==END_SYMBOL AND NOT force AND line[*count] == delim)
  69.             if (multiple OR negate)
  70.                 return(ERROR);
  71.             else
  72.                 {
  73.                 at_begin = NO;
  74.                 end_end = YES;
  75.                 }
  76.         else
  77.             {
  78.             if (allocate(&nxet))
  79.                 return(ERROR);
  80.             data_search[nxet].test_char = c;
  81.             if (c==ANY_SYMBOL AND NOT force)
  82.                 {
  83.                 if (negate)
  84.                     return(ERROR);
  85.                 use_first = use_second = YES;
  86.                 data_search[nxet].if_found =
  87.                     &data_search[nxet].if_not;
  88.                 }
  89.             else
  90.                 if (negate)
  91.                     {
  92.                     use_first = NO;
  93.                     use_second = YES;
  94.                     }
  95.                 else
  96.                     {
  97.                     use_first = YES;
  98.                     use_second = NO;
  99.                     }
  100.             if (multiple)
  101.                 {
  102.                 if (use_first)
  103.                     data_search[nxet].if_found = nxet;
  104.                 if (use_second)
  105.                     data_search[nxet].if_not = nxet;
  106.                 link(&data_search[nxet].epsilon, nxet);
  107.                 }
  108.             else
  109.                 {
  110.                 if (use_first)
  111.                     link(&data_search[nxet].if_found, nxet);
  112.                 else
  113.                     link(&data_search[nxet].if_not, nxet);
  114.                 }
  115.             multiple = negate = at_begin = force = NO;
  116.             }
  117.         }
  118.     }
  119.  
  120. BOOL allocate(put)
  121.     int *put;
  122.     {
  123.     if (used_search == NO_SEARCH)
  124.         return(YES);
  125.     data_search[used_search].epsilon = data_search[used_search].if_found =
  126.         data_search[used_search].if_not = NONE;
  127.     *put = used_search++;
  128.     return(NO);
  129.     }
  130.  
  131. link(point, block)
  132.     int point, block;
  133.     {
  134.     int t;
  135.     while (last_block != NONE)
  136.         {
  137.         t = *last_block;
  138.         *last_block = block;
  139.         last_block = t;
  140.         }
  141.     last_block = point;
  142.     }
  143.  
  144. INT find_line(start, up)
  145.     int start;
  146.     BOOL up;
  147.     {
  148.     int stop_at, dummy1, dummy2;
  149.     fix_circular(&start);
  150.     stop_at = start;
  151.     if (dollar == 0)
  152.         return(NO);
  153.     do
  154.         {
  155.         if (kbhit())
  156.             {
  157.             getchar();
  158.             printf("!\007  ");
  159.             return(start);
  160.             }
  161.         if (test_line(start))
  162.             return(start);
  163.         if (up)
  164.             start++;
  165.         else
  166.             start--;
  167.         fix_circular(&start);
  168.         }
  169.     while (stop_at != start);
  170.     return(NO);
  171.     }
  172.  
  173. BOOL test_line(number)
  174.     int number;
  175.     {
  176.     char line[MAX_LINE+1];
  177.     int dummy1, dummy2;
  178.     read_line(number, line);
  179.     return(check_line(line, &dummy1, &dummy2, 0));
  180.     }
  181.  
  182. fix_circular(line)
  183.     int *line;
  184.     {
  185.     if (*line == 0)
  186.         *line = dollar;
  187.     if (*line > dollar)
  188.         *line = 1;
  189.     }
  190.  
  191. BOOL check_line(line, from, to, start)
  192.     char line[];
  193.     int *from, *to, start;
  194.     {
  195.     int j,i,t,set;
  196.     BOOL found[NO_SEARCH], next_found[NO_SEARCH];
  197.     *from = 0;
  198.     for (;;)
  199.         {
  200.         *to = NOPE;
  201.         for (j=0; j<used_search; j++)
  202.             found[j] = NO;
  203.         found[start] = YES;
  204.         i = *from - 1;
  205.         for (;;)
  206.             {
  207.             for (j=0; j<used_search; j++)
  208.                 if (found[j] AND (t=data_search[j].epsilon))
  209.                     if (t==NO_SEARCH)
  210.                         *to = i;
  211.                     else
  212.                         found[t] = YES;
  213.             if (line[i+1] == EOL)
  214.                 break;
  215.             for (j=0; j<used_search; j++)
  216.                 next_found[j] = NO;
  217.             i++;
  218.             for (j=0; j<used_search; j++)
  219.                 if (found[j])
  220.                     {
  221.                     if (data_search[j].test_char == line[i])
  222.                         set = data_search[j].if_found;
  223.                     else
  224.                         set = data_search[j].if_not;
  225.                     if (set == NO_SEARCH)
  226.                         *to = i;
  227.                     else if (set)
  228.                         next_found[set] = YES;
  229.                     }
  230.             for (j=0; j<used_search; j++)
  231.                 found[j] = next_found[j];
  232.             for (j=0; j<used_search; j++)
  233.                 if (found[j])
  234.                     goto lets_go_on;
  235.             break;
  236. lets_go_on:;        }
  237.         if (*to != NOPE)
  238.             if (NOT end_end OR line[*to+1]==EOL)
  239.                 return(YES);
  240.         if (start_begin OR line[*from]==EOL)
  241.             return(NO);
  242.         ++*from;
  243.         }
  244.     }
  245.  
  246. BOOL get_replace(count, line, replace)
  247.     int *count;
  248.     char line[], replace[];
  249.     {
  250.     int c;
  251.     char delim, k;
  252.     delim = line[*count-1];
  253.     for (c=0; delim != (k=line[(*count)++]); c++)
  254.         {
  255.         if (k==REPLACE_SYMBOL)
  256.             k = REP_SYM;
  257.         if (k==FORCE_SYMBOL)
  258.             k = line[(*count)++];
  259.         if (k == EOL)
  260.             return(NO);
  261.         replace[c] = k;
  262.         }
  263.     replace[c] = EOL;
  264.     return(YES);
  265.     }
  266.  
  267. BOOL get_options()
  268.     {
  269.     for (;;)
  270.         {
  271.         skip_space(&parse, line);
  272.         switch(tolower(line[parse++]))
  273.             {
  274.             case 'p':
  275.                 if (p_mode)
  276.                     return(NO);
  277.                 p_mode = YES;
  278.                 break;
  279.             case 'g':
  280.                 if (g_mode)
  281.                     return(NO);
  282.                 g_mode = YES;
  283.                 break;
  284.             case EOL:
  285.                 return(YES);
  286.             default:
  287.                 return(NO);
  288.             }
  289.         }
  290.     }
  291.  
  292. substitute(l, start_search, replace, interact)
  293.     int l, start_search;
  294.     char replace[];
  295.     BOOL interact;
  296.     {
  297.     int from, to, new_to;
  298.     char line[MAX_LINE+1], new_line[MAX_LINE+1];
  299.     read_line(l, line);
  300.     if (NOT check_line(line, &from, &to, start_search))
  301.         return;
  302.     if (NOT dosub(line, &from, &to, replace, interact))
  303.         return;
  304.     while (g_mode AND NOT start_begin AND strlen(line)>to AND
  305.         check_line(line+(new_to=to), &from, &to, start_search))
  306.         {
  307.         from += new_to;
  308.         to += new_to;
  309.         if (NOT dosub(line, &from, &to, replace, interact))
  310.             return;
  311.         }
  312.     delete_line(l);
  313.     insert_line(l, line);
  314.     if (p_mode)
  315.         print(l, NO);
  316.     dot = l;
  317.     }
  318.  
  319. #define OVER_FLOW {printf("Overflow error!\007\n");return(NO);}
  320. BOOL dosub(line, from, to, replace, interact)
  321.     char line[], replace[];
  322.     int *from, *to;
  323.     BOOL interact;
  324.     {
  325.     char new_line[MAX_LINE+1], replace_string[MAX_LINE+1];
  326.     int cnt, i, next_to, j;
  327.     cnt = 0;
  328.     for (i=0; replace[i]; i++)
  329.         if (replace[i] == REP_SYM)
  330.             for (j=*from; j<=*to; j++)
  331.                 {
  332.                 if (cnt >= MAX_LINE)
  333.                     OVER_FLOW;
  334.                 replace_string[cnt++] = line[j];
  335.                 }
  336.         else
  337.             {
  338.             if (cnt >= MAX_LINE)
  339.                 OVER_FLOW;
  340.             replace_string[cnt++] = replace[i];
  341.             }
  342.     replace_string[cnt] = EOL;
  343.     if (interact)
  344.         {
  345.         printf("%s\n", line);
  346.         for (i=0; i<*from; i++)
  347.             if (line[i] == TAB)
  348.                 printf("    ");
  349.             else
  350.                 printf(" ");
  351.         for (i=*from; i<=*to; i++)
  352.             {
  353.             printf("^");
  354.             if (line[i] == TAB)
  355.        { printf("\010^\010^\010^\010^\010^\010^\010|");
  356.        printf("\t\010\010^\010^\010^\010^\010^\010^\010^\010|"); }
  357.             }
  358.         printf("\n");
  359.         get_line(new_line,"");
  360.         if (strcmp(new_line, "."))
  361.             {
  362.             ++*to;
  363.             return(YES);
  364.             }
  365.         }
  366.     cnt = 0;
  367.     for (i=0; i<*from; i++)
  368.         new_line[cnt++] = line[i];
  369.     for (i=0; replace_string[i]; i++)
  370.         {
  371.         new_line[cnt++] = replace_string[i];
  372.         if (cnt > MAX_LINE)
  373.             OVER_FLOW;
  374.         }
  375.     next_to = cnt;
  376.     i = *to + 1;
  377.     do
  378.         {
  379.         new_line[cnt++] = line[i];
  380.         if (cnt > MAX_LINE)
  381.             OVER_FLOW;
  382.         }
  383.     while (line[i++]);
  384.     *to = next_to;
  385.     for (i=0; new_line[i]; i++)
  386.         line[i] = new_line[i];
  387.     line[i] = EOL;
  388.     return(YES);
  389.     }
  390. ile (line[i++]);
  391.     *to = next_to;
  392.     for (i=0; new_line[i]; i++)
  393.         line[i] = new_line[i];
  394.     line[i] = EOL;
  395.     return(YES);
  396.     }
  397.