home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / TeX / tex / scanning.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-18  |  21.3 KB  |  952 lines

  1. /* Part 26: Basic scanning subroutines... */
  2.  
  3. #define EXTERN extern
  4. #include "texd.h"
  5.  
  6. void scanleftbrace ( void )        /* 403. */
  7. { scanleftbrace_regmem
  8.   register eightbits r_curcmd;
  9.  
  10.   r_curcmd = getxnbtoken(1);
  11.  
  12.   if ( r_curcmd != 1 ) {
  13.     p_print_err( STR_H_MISSING_LEFTBRACE );
  14.     zhelp1( STR_H_A_LEFTBRACE_MANDATORY );
  15.     backerror();
  16.     curtok = leftbracetoken + 123 ; 
  17.     curcmd = 1 ; 
  18.     curchr = 123 ; 
  19.     incr ( alignstate ) ; 
  20.   }
  21. }
  22.  
  23. void scanoptionalequals ( void )    /* 405. */
  24. { scanoptionalequals_regmem
  25.  
  26.   (void) getxnbtoken(0);
  27.   if ( curtok != othertoken + 61 )
  28.     backinput ();
  29. }
  30.  
  31. boolean scankeyword ( strnumber s )    /* 407. */
  32. { scankeyword_regmem 
  33.   register long_halfword p ;
  34.   register packedASCIIcode *pp, *endp;
  35.  
  36.   p = backuphead;
  37.   link ( p ) = 0;
  38.  
  39.   pp   = &strpool[strstart[s]];        /* k = strstart[s]; */
  40.   endp = &strpool[strstart[s+1]];
  41.   while ( pp < endp ) {            /* (k < strstart[s+1]) */
  42.     register eightbits r_curcmd;
  43.  
  44.     r_curcmd = getxtoken ();        /* *pp: strpool[k] */
  45.     if ( curcs == 0
  46.     && ( (packedASCIIcode)curchr == *pp
  47.       || (packedASCIIcode)curchr == *pp - 32 ) ) {
  48.       storenewtoken ( curtok );
  49.       pp++;
  50.     } else if ( r_curcmd != 10 || (halfword)p != backuphead ) {
  51.       backinput ();
  52.       if ( (halfword)p != backuphead )
  53.     begintokenlist ( link ( backuphead ) , backedup );
  54.       return(false);
  55.     }
  56.   }
  57.   flushlist ( link ( backuphead ) );
  58.   return(true);
  59. }
  60.  
  61. void muerror ( void )        /* 408. */
  62. { muerror_regmem 
  63.  
  64.   print_err ("Incompatible glue units");
  65.   zhelp1( STR_H_IM_GOING_MU_PT );
  66.   error () ; 
  67.  
  68.  
  69. integer scaneightbitint ( void )    /* 433. */
  70. { scaneightbitint_regmem 
  71.   register integer r_curval;
  72.  
  73.   r_curval = scanint (); 
  74.   if ( r_curval < 0 || r_curval > 255 ) {
  75.     print_err("Bad register code");
  76.     zhelp2( STR_H_REGISTERNUMBER_BETWEEN, STR_H_I_CHANGED_TO_ZERO );
  77.     interror ( curval );
  78.     curval = 0L;
  79.     return 0L;
  80.   }
  81.   return r_curval;
  82. }
  83.  
  84. integer scancharnum ( void )
  85. { scancharnum_regmem 
  86.   register integer r_curval;
  87.   
  88.   r_curval = scanint();
  89.   if ( r_curval < 0 || r_curval > 255 ) {
  90.     print_err("Bad character code");
  91.     zhelp2( STR_H_CHARNUMBER_BETWEEN, STR_H_I_CHANGED_TO_ZERO );
  92.     interror ( curval );
  93.     curval = 0L;
  94.     return 0L;
  95.   }
  96.   return r_curval;
  97. }
  98.  
  99. integer scanfourbitint ( void )
  100. { scanfourbitint_regmem 
  101.   register integer r_curval;
  102.  
  103.   r_curval = scanint();
  104.   if ( r_curval < 0 || r_curval > 15 ) {
  105.     print_err("Bad number");
  106.     zhelp2( STR_H_SINCE_I_EXPECT_BETWEEN, STR_H_I_CHANGED_TO_ZERO );
  107.     interror ( curval );
  108.     curval = 0L; 
  109.     return 0L;
  110.   }
  111.   return r_curval;
  112. }
  113.  
  114. integer scanfifteenbitint ( void )
  115. { scanfifteenbitint_regmem
  116.   register integer r_curval;
  117.  
  118.   r_curval = scanint();
  119.   if ( r_curval < 0 || r_curval > 32767 ) {
  120. #if 0  /* TeX 3.141 */
  121.     print_err("Bad math code");
  122. #else
  123.     print_err("Bad mathchar");
  124. #endif
  125.     zhelp2( STR_H_NUMERICMATH_BETWEEN, STR_H_I_CHANGED_TO_ZERO );
  126.     interror ( curval );
  127.     curval = 0L;
  128.     return 0L;
  129.   }
  130.   return r_curval;
  131. }
  132.  
  133. integer scantwentysevenbitint ( void )
  134. { scantwentysevenbitint_regmem 
  135.   register integer r_curval;
  136.  
  137.   r_curval = scanint();
  138.   if ( r_curval < 0 || r_curval > 134217727L ) {
  139.     print_err("Bad delimiter code");
  140.     zhelp2( STR_H_NUMERICDEL_BETWEEN, STR_H_I_CHANGED_TO_ZERO );
  141.     interror ( curval );
  142.     curval = 0L;
  143.     return 0L;
  144.   }
  145.   return r_curval;
  146. }
  147.  
  148. integer scanfontident ( void )        /* 577. */
  149. { scanfontident_regmem
  150.   register internalfontnumber f;
  151.   register eightbits r_curcmd;
  152.  
  153.   r_curcmd = getxnbtoken(0);
  154.  
  155.   if ( r_curcmd == def_font )
  156.     f = curfont;
  157.   else if ( r_curcmd == set_font )
  158.     f = curchr;
  159.   else if ( r_curcmd == def_family ) {
  160.     register halfword m;
  161.     m = curchr;
  162.     f = equiv( m + scanfourbitint() );
  163.   } else {
  164.     print_err("Missing font identifier");
  165.     zhelp1( STR_H_I_LOOKING_FOR_CS );
  166.     backerror();
  167.     f = nullfont;
  168.   }
  169.   curval = f;
  170.   return (integer)f;
  171. }
  172.  
  173.  
  174. integer findfontdimen ( boolean writing )    /* 578. */
  175. { findfontdimen_regmem
  176.   register internalfontnumber f;
  177.   register integer n;
  178.   register integer r_curval;
  179.  
  180.   n = scanint ();
  181.   f = scanfontident();
  182.   if ( n <= 0 )
  183.     r_curval = fmemptr;
  184.   else {
  185.     if ( writing && ( n <= spaceshrinkcode )
  186.     && ( n >= spacecode ) && ( fontglue(f) != 0 ) )
  187.     {
  188.       deleteglueref ( fontglue(f) );
  189.       fontglue(f) = 0;
  190.     }
  191.     if ( n > fontparams(f) ) {
  192.       if ( f < fontptr ) {
  193.     r_curval = fmemptr ; 
  194.       } else {
  195.     do {
  196.       if ( fmemptr == fontmemsize ) 
  197.         overflow(11, fontmemsize);
  198.       fontinfo [ fmemptr ] .cint = 0 ; 
  199.       incr ( fmemptr ) ; 
  200.       incr ( fontparams(f) ) ; 
  201.         } while ( n != fontparams(f) );
  202.         r_curval = fmemptr - 1;
  203.       }
  204.     } else {
  205.       r_curval = n + parambase(f);
  206.     }
  207.   }
  208.  
  209.   curval = r_curval;
  210.  
  211.   if ( r_curval == fmemptr ) {
  212.     print_err("Font ");
  213.     printesc ( fontidtext ( f ) );
  214.     c_print(" has only ");
  215.     printint ( fontparams(f) );
  216.     c_print(" fontdimen parameters");
  217.     zhelp1( STR_H_TO_INCREASE_FNTP );
  218.     error();
  219.     return curval;
  220.   } else {
  221.     return r_curval;
  222.   }
  223. }
  224.  
  225.  
  226.   static void
  227. missing_number_error(void)
  228. {
  229.   print_err("Missing number, treated as zero");
  230.   zhelp1( STR_H_ANUMBER_SHOULD_HERE );
  231.   backerror();
  232. }
  233.  
  234.  
  235.   integer
  236. scansomethinginternal ( smallnumber level, boolean negative ) /* 413. */
  237. { scansomethinginternal_regmem 
  238.   register halfword m;
  239.   register integer r_curval;
  240.   register schar r_curvallevel;
  241.  
  242.   m = curchr;
  243.   switch ( curcmd ) {
  244.   case def_code:
  245.       r_curval = scancharnum () ; 
  246.       if ( m == mathcodebase ) {
  247.     r_curval = mathcode ( r_curval );
  248.     r_curvallevel = intval;
  249.       } else if ( m < mathcodebase ) {
  250.     r_curval = equiv ( m + r_curval ) ; 
  251.     r_curvallevel = intval ; 
  252.       } else {
  253.     r_curval = eqtb [ m + r_curval ] .cint ; 
  254.     r_curvallevel = intval ; 
  255.       }
  256.       break;
  257.   case toks_register:
  258.   case assign_toks:
  259.   case def_family:
  260.   case set_font:
  261.   case def_font:
  262.     if ( level != tokval ) {
  263.       missing_number_error();
  264.       r_curval = 0 ; 
  265.       r_curvallevel = dimenval ; 
  266.     } else if ( curcmd <= assign_toks ) {
  267.       if ( curcmd < assign_toks ) {
  268.     r_curval = scaneightbitint () ;
  269.     m = toksbase + r_curval ;
  270.       }
  271.       r_curval = equiv(m);
  272.       r_curvallevel = tokval;
  273.     } else {
  274.       backinput ();
  275.       r_curval = scanfontident ();
  276.       r_curval = fontidbase + r_curval ; 
  277.       r_curvallevel = identval ; 
  278.     }
  279.     break;
  280.   case assign_int:
  281.     r_curval = eqtb[m].cint;
  282.     r_curvallevel = intval;
  283.     break ; 
  284.   case assign_dimen:
  285.     r_curval = eqtb [ m ] .cint;
  286.     r_curvallevel = dimenval;
  287.     break;
  288.   case assign_glue:
  289.     r_curval = equiv ( m );
  290.     r_curvallevel = glueval;
  291.     break;
  292.   case assign_mu_glue:
  293.     r_curval = equiv ( m );
  294.     r_curvallevel = muval;
  295.     break;
  296.   case set_aux:
  297.     if ( abs ( curlist.modefield ) != m ) {
  298.       p_print_err( STR_H_IMPROPER );
  299.       printcmdchr( set_aux, m );
  300.       zhelp2( STR_H_YOU_REFER_SPACEFACTOR, STR_H_IM_FORGETTING_ZERO );
  301.       error ();
  302.       r_curval = 0;
  303.       if ( level != tokval ) {
  304.     r_curvallevel = dimenval;
  305.       } else {
  306.     r_curvallevel = intval;
  307.       }
  308.     } else if ( m == vmode ) {
  309.       r_curval = curlist .auxfield .cint;
  310.       r_curvallevel = dimenval;
  311.     } else {
  312.       r_curval = curlist .auxfield .hh .v.LH;
  313.       r_curvallevel = intval;
  314.     }
  315.     break;
  316.   case set_prev_graf: 
  317.     if ( curlist .modefield == 0 ) {
  318.       r_curval = 0;
  319.       r_curvallevel = intval;
  320.     } else {    
  321.       register integer p;
  322.  
  323.       nest [ nestptr ] = curlist;
  324.       p = nestptr;
  325.       while ( abs ( nest [ p ] .modefield ) != vmode )
  326.     decr ( p );
  327.       r_curval = nest [ p ] .pgfield;
  328.       r_curvallevel = intval;
  329.     }
  330.     break ;
  331.   case set_page_int:
  332.     if ( m == 0 ) 
  333.     r_curval = deadcycles ; 
  334.     else
  335.     r_curval = insertpenalties ; 
  336.     r_curvallevel = intval ; 
  337.     break ; 
  338.   case set_page_dimen:
  339.     if ( pagecontents == 0 && !outputactive )
  340.       if ( m == 0 )
  341.     r_curval = maxdimen;
  342.       else
  343.     r_curval = 0;
  344.     else
  345.       r_curval = pagesofar [ m ];
  346.     r_curvallevel = dimenval;
  347.     break ; 
  348.   case set_shape:
  349.     if ( parshapeptr == 0 ) 
  350.     r_curval = 0;
  351.     else
  352.     r_curval = info ( parshapeptr );
  353.     r_curvallevel = intval ; 
  354.     break ; 
  355.   case set_box_dimen:
  356.     r_curval = scaneightbitint ();
  357.     if ( box ( r_curval ) == 0 )
  358.     r_curval = 0;
  359.     else
  360.     r_curval = mem [ box ( r_curval ) + m ] .cint;
  361.     r_curvallevel = dimenval ; 
  362.     break ; 
  363.   case chargiven:
  364.   case math_given:
  365.     r_curval = curchr;
  366.     r_curvallevel = intval;
  367.     break ; 
  368.   case assign_font_dimen:
  369.     r_curval = findfontdimen ( false );
  370.     fontinfo[fmemptr].cint = 0;
  371.     r_curval = fontinfo [ r_curval ] .cint;
  372.     r_curvallevel = dimenval;
  373.     break;
  374.   case assign_font_int:
  375.     r_curval = scanfontident ();
  376.     if ( m == 0 ) {
  377.     r_curval = hyphenchar(r_curval);
  378.     } else {      
  379.     r_curval = skewchar(r_curval);
  380.     }
  381.     r_curvallevel = intval ; 
  382.     break ; 
  383.   case register_cmd:
  384.     {
  385.       r_curval = scaneightbitint ();
  386.       switch ( m ) {
  387.       case intval :
  388.     r_curval = count ( r_curval );
  389.     break ; 
  390.       case dimenval : 
  391.     r_curval = dimen ( r_curval ) ;
  392.     break ;
  393.       case glueval : 
  394.     r_curval = skip ( r_curval ) ;
  395.     break ; 
  396.       case muval : 
  397.     r_curval = muskip ( r_curval ) ;
  398.     break ; 
  399.       }
  400.       r_curvallevel = m ; 
  401.     }
  402.     break ; 
  403.   case last_item:
  404.     if ( curchr > glueval ) {
  405.       if ( curchr == inputlinenocode ) 
  406.     r_curval = line ; 
  407.       else
  408.     r_curval = lastbadness ; 
  409.       r_curvallevel = intval ; 
  410.     } else {    
  411.       if ( curchr == glueval )
  412.     r_curval = zeroglue ; 
  413.       else
  414.     r_curval = 0 ; 
  415.       r_curvallevel = curchr;
  416.       if ( ! ischarnode ( curlist.tailfield ) && ( curlist.modefield != 0 ) ) {
  417.     switch ( curchr ) {
  418.     case intval : 
  419.       if ( ztype ( curlist .tailfield ) == penaltynode )
  420.         r_curval = mem [ curlist .tailfield + 1 ] .cint ; 
  421.       break ; 
  422.     case dimenval : 
  423.       if ( ztype ( curlist .tailfield ) == kernnode ) 
  424.         r_curval = width ( curlist .tailfield ) ; 
  425.       break ; 
  426.     case glueval : 
  427.       if ( ztype ( curlist .tailfield ) == gluenode ) {
  428.         r_curval = glueptr ( curlist .tailfield ) ; 
  429.         if ( subtype ( curlist .tailfield ) == muglue ) 
  430.           r_curvallevel = muval ; 
  431.       }
  432.       break;
  433.     }
  434.       } else if ( curlist .modefield == vmode
  435.            && curlist.tailfield == curlist.headfield ) {
  436.     switch ( curchr ) {
  437.     case intval : 
  438.       r_curval = lastpenalty ; 
  439.       break ; 
  440.     case dimenval : 
  441.       r_curval = lastkern ; 
  442.       break ; 
  443.     case glueval : 
  444.       if ( lastglue != maxhalfword ) 
  445.         r_curval = lastglue ; 
  446.       break;
  447.     }
  448.       }
  449.     }
  450.     break;
  451.   default: 
  452.     {
  453.       p_print_err( STR_H_YOUCANTUSE );
  454.       printcmdchr( curcmd, curchr );
  455.       print( STR_H_AFTER );
  456.       printesc( STR_THE );
  457.       zhelp1( STR_H_IM_FORGETTING_ZERO );
  458.       error () ; 
  459.       r_curval = 0;
  460.       if ( level != tokval ) {
  461.     r_curvallevel = dimenval;
  462.       } else {
  463.     r_curvallevel = intval;
  464.       }
  465.     }
  466.     break;
  467.   }
  468.  
  469.   while ( r_curvallevel > level ) {      
  470.     if ( r_curvallevel == glueval )
  471.       r_curval = width ( r_curval ) ; 
  472.     else if ( r_curvallevel == muval ) {
  473.       muerror ();
  474.       /* Possible insertions in error()... reload registers */
  475.       r_curval = curval; r_curvallevel = curvallevel;
  476.     }
  477.     decr ( r_curvallevel );
  478.   }
  479.   if ( negative ) {
  480.     if ( r_curvallevel >= glueval ) {
  481.       curval = r_curval = newspec ( r_curval );
  482.       width ( r_curval ) = - (integer) width ( r_curval );
  483.       stretch ( r_curval ) = - (integer) stretch ( r_curval );
  484.       shrink ( r_curval ) = - (integer) shrink ( r_curval );
  485.     } else {
  486.       r_curval = - (integer) r_curval;
  487.     }
  488.   } else if ( r_curvallevel >= glueval && r_curvallevel <= muval ) {
  489.     addglueref ( r_curval );
  490.   }
  491.  
  492.   /* Update global values... */
  493.   curvallevel = r_curvallevel;
  494.   curval = r_curval;
  495.  
  496.   return r_curval;
  497. }
  498.  
  499.  
  500.   integer
  501. scanint ( void )        /* 440. */
  502. { scanint_regmem
  503.   boolean negative;
  504.   register eightbits r_curcmd;
  505.  
  506.   radix = 0;
  507.   negative = false;
  508.   do {
  509.     r_curcmd = getxnbtoken(0);
  510.     if ( curtok == othertoken + 45 ) {
  511.       negative = ! negative ; 
  512.       curtok = othertoken + 43 ;
  513.     }
  514.   } while ( curtok == othertoken + 43 );
  515.  
  516.   if ( curtok == alphatoken ) {
  517.     r_curcmd = gettoken();
  518.     if ( curtok < cstokenflag ) {
  519.       curval = curchr ;
  520.       if ( r_curcmd <= 2 ) 
  521.     if ( r_curcmd == 2 ) 
  522.       incr ( alignstate ) ; 
  523.     else
  524.       decr ( alignstate );
  525.     } else if ( curtok < cstokenflag + singlebase )
  526.       curval = curtok - cstokenflag - activebase;
  527.     else
  528.       curval = curtok - cstokenflag - singlebase;
  529.  
  530.     if ( curval > 255 ) {
  531.       print_err("Improper alphabetic constant");
  532.       zhelp1( STR_H_ONECHAR_CS_BELONGS );
  533.       curval = 48;
  534.       backerror ();
  535.     } else {
  536.       if ( (eightbits)getxtoken() != 10 )
  537.         backinput();
  538.     }
  539.  
  540.   } else if ( r_curcmd >= min_internal && r_curcmd <= max_internal )
  541.  
  542.     scansomethinginternal ( intval , false ) ; 
  543.  
  544.   else {
  545.       
  546.     register integer m;
  547.     boolean vacuous;
  548.     boolean OKsofar;
  549.  
  550.     radix = 10 ; 
  551.     m = 214748364L ; 
  552.     if ( curtok == octaltoken ) {
  553.       radix = 8 ; 
  554.       m = 268435456L ; 
  555.       getxtoken () ; 
  556.     } else if ( curtok == hextoken ) {
  557.       radix = 16 ; 
  558.       m = 134217728L ; 
  559.       getxtoken () ; 
  560.     } 
  561.     OKsofar = true;
  562.     vacuous = true;
  563.     curval = 0;
  564.  
  565.     while ( true ) {
  566.       register smallnumber d;
  567.  
  568.       if ( ( curtok < zerotoken + radix ) && ( curtok >= zerotoken )
  569.         && ( curtok <= zerotoken + 9 ) )
  570.     d = curtok - zerotoken ; 
  571.       else if ( radix == 16 ) 
  572.     if ( ( curtok <= Atoken + 5 ) && ( curtok >= Atoken ) ) 
  573.       d = curtok - Atoken + 10 ; 
  574.      else if ( ( curtok <= otherAtoken + 5 ) && ( curtok >= otherAtoken ) ) 
  575.       d = curtok - otherAtoken + 10;
  576.     else goto lab30;
  577.       else
  578.     goto lab30;
  579.       vacuous = false;
  580.       if ( curval >= m && ( curval > m || d > 7 || ( radix != 10 ) ) ) {
  581.     if ( OKsofar ) {
  582.       print_err("Number too big");
  583.       zhelp1( STR_H_ICAN_ONLY_GOUPTO );
  584.       error();
  585.       curval = infinity;
  586.       OKsofar = false;
  587.     }
  588.       } else
  589.     curval = curval * radix + d;
  590.       getxtoken();
  591.     }
  592.  
  593. lab30:
  594.     if ( vacuous ) {
  595.       missing_number_error();
  596.     } else if ( curcmd != 10 ) 
  597.       backinput () ;
  598.   }
  599.   if ( negative )
  600.     curval = - (integer) curval;
  601.  
  602.   return curval;
  603. }
  604.  
  605. static char *Illegal_Unit_of_Measure = "Illegal unit of measure (";
  606.  
  607.   integer
  608. scandimen ( boolean mu, boolean inf, boolean shortcut )        /* 448. */
  609. { scandimen_regmem
  610.   boolean negative;
  611.   register integer f;
  612.   register integer r_curval;
  613.  
  614.   f = 0 ; 
  615.   aritherror = false ; 
  616.   curorder = normal ; 
  617.   negative = false ; 
  618.   if ( ! shortcut ) {
  619.     negative = false ; 
  620.     do {
  621.       (void) getxnbtoken(0);
  622.       if ( curtok == othertoken + 45 ) {
  623.     negative = ! negative ;
  624.     curtok = othertoken + 43 ;
  625.       }
  626.     } while ( curtok == othertoken + 43 );
  627.  
  628.     if ( curcmd >= min_internal && curcmd <= max_internal ) {
  629.       if ( mu ) {
  630.     r_curval = scansomethinginternal ( muval , false ) ; 
  631.     if ( curvallevel >= glueval ) {
  632.       register scaled v;
  633.  
  634.       v = width ( r_curval ) ; 
  635.       deleteglueref ( r_curval ) ; 
  636.       curval = r_curval = v ; 
  637.     }
  638.     if ( curvallevel == muval ) 
  639.       goto lab89 ; 
  640.     if ( curvallevel != intval ) 
  641.       muerror ();
  642.       } else {
  643.     r_curval = scansomethinginternal ( dimenval , false ) ; 
  644.     if ( curvallevel == dimenval ) 
  645.       goto lab89 ; 
  646.       }
  647.     } else {        /* not internal.. */
  648.       backinput ();
  649.       if ( curtok == continentalpointtoken ) 
  650.     curtok = pointtoken ; 
  651.       if ( curtok != pointtoken ) 
  652.     scanint ();
  653.       else {
  654.     radix = 10;
  655.     curval = 0;
  656.       }
  657.       if ( curtok == continentalpointtoken ) 
  658.     curtok = pointtoken ;
  659.  
  660.       if ( radix == 10 && curtok == pointtoken ) {
  661.     register long_halfword p;
  662.     register smallnumber k; 
  663.  
  664.     k = 0; p = 0;
  665.     gettoken();
  666.  
  667.     while ( true ) {
  668.       getxtoken () ; 
  669.       if ( ( curtok > zerotoken + 9 ) || ( curtok < zerotoken ) ) 
  670.         goto lab31 ; 
  671.       if ( k < 17 ) {
  672.         register long_halfword q;
  673.  
  674.         q = getavail () ; 
  675.         link ( q ) = p ; 
  676.         info ( q ) = curtok - zerotoken ; 
  677.         p = q ; 
  678.         incr ( k ) ; 
  679.       }
  680.     }
  681.  
  682. lab31:
  683.     { short kk;
  684. #if 0
  685.     for( kk = k ; kk >= 1 ; --kk ) {
  686.       register long_halfword q;
  687.  
  688.       dig [ kk - 1 ] = info ( p ) ; 
  689.       q = p ; p = link ( p ) ; freeavail ( q ) ; 
  690.     }
  691.     f = rounddecimals ( k ) ; 
  692. #else
  693.     f = 0;
  694.     kk = k;
  695.     while ( kk > 0 ) {
  696.       register long_halfword q;
  697.  
  698.       decr ( kk ) ; 
  699.       f = ( f + ((schar) info(p)) * two ) / 10; 
  700.       q = p; p = link(p); freeavail(q);
  701.     }
  702.     f = (f + 1) / 2;
  703. #endif
  704.     }
  705.     if ( curcmd != 10 ) 
  706.       backinput () ;
  707.       }    /* end... scan decimal fraction */
  708.     }    /* end... not internal quantity */
  709.   }    /* end... !shortcut */
  710.  
  711.   if ( curval < 0 ) {
  712.     negative = ! negative;
  713.     curval = - (integer) curval;
  714.   }
  715.  
  716.   if ( inf ) {
  717.     if ( scankeyword( STR_FIL ) ) {    /* "fil" */
  718.       curorder = fil;
  719.       while ( scankeyword( 108 ) ) {    /* "l" */
  720.     if ( curorder == filll ) {
  721.       print_err(Illegal_Unit_of_Measure);
  722.       c_print("replaced by filll)");
  723.       zhelp1( STR_H_I_DDDONT_GO );
  724.       error ();
  725.     } else
  726.       incr ( curorder );
  727.       }
  728.       goto lab88;
  729.     }
  730.   }
  731.  
  732.  
  733.   /* 455. Scan for units that are internal dimensions.. */
  734.   { integer savecurval;
  735.     halfword r_curcmd;
  736.     scaled v;
  737.  
  738.   savecurval = curval ; 
  739.   r_curcmd = getxnbtoken(0);
  740.   if ( r_curcmd < min_internal || r_curcmd > max_internal )
  741.     backinput ();
  742.   else {
  743.     if ( mu ) {
  744.       scansomethinginternal ( muval , false );
  745.       if ( curvallevel >= glueval ) {
  746.     v = width ( curval ) ; 
  747.     deleteglueref ( curval );
  748.     curval = v;
  749.       }
  750.       if ( curvallevel != muval ) 
  751.     muerror () ; 
  752.     } else
  753.       scansomethinginternal ( dimenval , false ) ; 
  754.     v = curval;
  755.     goto lab40 ; 
  756.   }
  757.  
  758.   if ( mu )
  759.     goto lab45;
  760.  
  761.   if ( scankeyword( STR_EM ) )
  762.     v = quad ( curfont );
  763.   else if ( scankeyword( STR_EX ) )
  764.     v = xheight ( curfont );
  765.   else
  766.     goto lab45;
  767.   {
  768.     if ( (eightbits)getxtoken() != 10 )
  769.       backinput ();
  770.   }
  771. lab40:
  772.   r_curval = multandadd (savecurval, v, xnoverd (v, f, 65536L), 1073741823L);
  773.   goto lab89;
  774.  }
  775.  
  776.  
  777. lab45:
  778.   if ( mu ) {
  779.     if ( scankeyword( STR_MU ) ) {    /* "mu" */
  780.       goto lab88;
  781.     } else {
  782.       print_err(Illegal_Unit_of_Measure);
  783.       c_print("mu inserted)");
  784.       zhelp2( STR_H_UNIT_IN_MATHGLUE, STR_H_TO_RECOVER_GRACEF );
  785.       error ();
  786.       goto lab88;
  787.     }
  788.   }
  789.  
  790.   if ( scankeyword( STR_TRUE ) ) {        /* "true" */
  791.     preparemag ();
  792.     if ( mag != 1000 ) {
  793.       curval = xnoverd ( curval , 1000 , mag );
  794.       f = ( 1000 * f + 65536L * remainder ) / mag;
  795.       curval = curval + ( f / 65536L );
  796.       f = f % 65536L;
  797.     }
  798.   }
  799.  
  800.   if ( scankeyword( STR_PT ) )        /* "pt" */
  801.     goto lab88;
  802.  
  803.  { register integer num, denom;
  804.  
  805.   if ( scankeyword( STR_IN ) ) {
  806.     num = 7227;    denom = 100;
  807.   } else if ( scankeyword( STR_PC ) ) {
  808.     num = 12;    denom = 1;
  809.   } else if ( scankeyword( STR_CM ) ) {
  810.     num = 7227;    denom = 254;
  811.   } else if ( scankeyword( STR_MM ) ) {
  812.     num = 7227;    denom = 2540;
  813.   } else if ( scankeyword( STR_BP ) ) {
  814.     num = 7227;    denom = 7200;
  815.   } else if ( scankeyword( STR_DD ) ) {
  816.     num = 1238;    denom = 1157;
  817.   } else if ( scankeyword( STR_CC ) ) {
  818.     num = 14856; denom = 1157;
  819.   } else if ( scankeyword( STR_SP ) )
  820.     goto lab30;
  821.   else {
  822.     print_err(Illegal_Unit_of_Measure);
  823.     c_print("pt inserted)");
  824.     zhelp2( STR_H_DIMENSIONS_EMEX, STR_H_TO_RECOVER_GRACEF );
  825.     error () ; 
  826.     goto lab32 ; 
  827.   } 
  828.   curval = xnoverd ( curval , num , denom ) ; 
  829.   f = ( num * f + 65536L * remainder ) / denom ; 
  830.   curval = curval + ( f / 65536L ) ; 
  831.   f = f % 65536L ;
  832. lab32: ;
  833.  }
  834.  
  835. lab88:
  836.   if ( curval >= 16384 ) 
  837.     aritherror = true;
  838.   else
  839.     curval = curval * unity + f;
  840.  
  841. lab30: ; 
  842.   {
  843.     if ( (eightbits)getxtoken() != 10 )
  844.       backinput();
  845.   } 
  846.   r_curval = curval;
  847.  
  848. lab89:
  849.   if ( aritherror || ( abs ( r_curval ) >= 1073741824L ) ) {
  850.     print_err("Dimension too large");
  851.     zhelp1( STR_H_ICANT_WORK_BIGGER );
  852.     error();
  853.     r_curval = maxdimen;
  854.     aritherror = false;
  855.   }
  856.   if ( negative )
  857.     r_curval = - (integer) r_curval;
  858.  
  859.   curval = r_curval;
  860.   return r_curval;
  861. }
  862.  
  863.  
  864.   long_halfword
  865. scanglue ( smallnumber level )        /* 461. */
  866. { scanglue_regmem
  867.   boolean negative;
  868.   register long_halfword q;
  869.   boolean mu;
  870.   register eightbits r_curcmd;
  871.   register integer r_curval;
  872.  
  873.   negative = false ; 
  874.   do {
  875.     r_curcmd = getxnbtoken(0);
  876.     if ( curtok == othertoken + 45 ) {
  877.       negative = ! negative ; 
  878.       curtok = othertoken + 43 ; 
  879.     }
  880.   } while ( curtok == othertoken + 43 ) ; 
  881.  
  882.   mu = ( level == muval );
  883.   if ( r_curcmd >= min_internal && r_curcmd <= max_internal ) {
  884.     r_curval = scansomethinginternal ( level , negative );
  885.     if ( curvallevel >= glueval ) {
  886.       if ( curvallevel != level ) {
  887.     muerror ();
  888.     r_curval = curval;
  889.       }
  890.       return r_curval; 
  891.     }
  892.     if ( curvallevel == intval ) 
  893.       r_curval = scandimen ( mu , false , true );
  894.     else if ( level == muval ) {
  895.       muerror ();
  896.       r_curval = curval;
  897.     }
  898.   } else {
  899.     backinput () ; 
  900.     r_curval = scandimen ( mu, false, false );
  901.     if ( negative )
  902.       r_curval = - (integer) r_curval;
  903.   }
  904.  
  905.   q = newspec ( zeroglue );
  906.   width ( q ) = r_curval;
  907.  
  908.   if ( scankeyword( STR_PLUS ) ) {        /* "plus" */
  909.     stretch ( q ) = scandimen ( mu , true , false );
  910.     stretchorder ( q ) = curorder;
  911.   }
  912.   if ( scankeyword( STR_MINUS ) ) {        /* "minus" */
  913.     shrink ( q ) = scandimen ( mu , true , false );
  914.     shrinkorder ( q ) = curorder ; 
  915.   }
  916.  
  917.   curval = q;
  918.   return q;
  919. }
  920.  
  921. long_halfword scanrulespec ( void )
  922. { scanrulespec_regmem 
  923.   register long_halfword q;
  924.  
  925.   q = newrule ();
  926.   if ( curcmd == 35 )
  927.     width ( q ) = defaultrule;
  928.   else {
  929.     height ( q ) = defaultrule;
  930.     depth ( q ) = 0;
  931.   }
  932.  
  933. lab21:
  934.   if ( scankeyword( STR_WIDTH ) ) {
  935.     width(q) = scandimen ( false , false , false );
  936.     goto lab21;
  937.   }
  938.   if ( scankeyword( STR_HEIGHT ) ) {
  939.     height(q) = scandimen ( false , false , false );
  940.     goto lab21;
  941.   }
  942.   if ( scankeyword( STR_DEPTH ) ) {
  943.     depth(q) = scandimen ( false , false , false );
  944.     goto lab21 ; 
  945.   }
  946.  
  947.   return(q);
  948. }
  949.  
  950. /* -- end -- */
  951.